1、目標
游戲中通過Save Game保存角色位置,當重啟游戲后,通過Load Game可以恢復角色的位置。
2、Player對象操作
(1)組件添加
給Hierarchy下的Player組件添加Generate GUID組件。
(2)修改SceneSave.cs腳本
添加2行代碼:
using System.Collections.Generic;[System.Serializable]public class SceneSave
{public Dictionary<string, bool> boolDictionary; // string key is an identifier name we choose for this listpublic Dictionary<string, string> stringDictionary; public Dictionary<string, Vector3Serializable> vector3Dictionary; // 可以保存角色位置// string key is an identifier name we choose for this listpublic List<SceneItem> listSceneItem;public Dictionary<string, GridPropertyDetails> gridPropertyDetailsDictionary; // key是坐標信息,value是地面屬性信息
}
(3)修改Settings.cs腳本
添加PersistentScene的常量,因為Player是在該Scene下。
添加1行代碼如下:
(4)修改Player.cs腳本
添加以下代碼:
using System;
using UnityEngine.SceneManagement;
修改Player類繼承自ISaveable:
接下來就是實現ISaveable定義的屬性。
private string _iSaveableUniqueID;public string ISaveableUniqueID { get { return _iSaveableUniqueID; } set { _iSaveableUniqueID = value; } }private GameObjectSave _gameObjectSave;public GameObjectSave GameObjectSave { get { return _gameObjectSave; } set { _gameObjectSave = value; } }
在Awake方法中添加屬性的初始化:
在OnDisable和OnEnable中各添加一個步驟:
添加這7個方法的實現:
public void ISaveableRegister()
{SaveLoadManager.Instance.iSaveableObjectList.Add(this);
}public void ISaveableDeregister()
{SaveLoadManager.Instance.iSaveableObjectList.Remove(this);
}public GameObjectSave ISaveableSave()
{// Delete saveScene for game object if it already existsGameObjectSave.sceneData.Remove(Settings.PersistentScene);// Create saveSave for game objectSceneSave sceneSave = new SceneSave();// Create Vector3 DictionarysceneSave.vector3Dictionary = new Dictionary<string, Vector3Serializable>();// Create String DictionarysceneSave.stringDictionary = new Dictionary<string, string>(); // Add Player position to Vector3 dictionaryVector3Serializable vector3Serializable = new Vector3Serializable(transform.position.x, transform.position.y, transform.position.z);sceneSave.vector3Dictionary.Add("playerPosition", vector3Serializable);// Add Current Scene Name to string dictionarysceneSave.stringDictionary.Add("currentScene", SceneManager.GetActiveScene().name);// Add Player Direction to string dictionarysceneSave.stringDictionary.Add("playerDirection", playerDirection.ToString());// Add sceneSave data for player game objectGameObjectSave.sceneData.Add(Settings.PersistentScene, sceneSave);return GameObjectSave;
}public void ISaveableLoad(GameSave gameSave)
{if(gameSave.gameObjectData.TryGetValue(ISaveableUniqueID, out GameObjectSave gameObjectSave)){// Get save data dictionary for sceneif(gameObjectSave.sceneData.TryGetValue(Settings.PersistentScene, out SceneSave sceneSave)){// Get player positionif(sceneSave.vector3Dictionary != null && sceneSave.vector3Dictionary.TryGetValue("playerPosition", out Vector3Serializable playerPosition)){transform.position = new Vector3(playerPosition.x, playerPosition.y, playerPosition.z);}// Get string dictionaryif(sceneSave.stringDictionary != null){// Get player sceneif(sceneSave.stringDictionary.TryGetValue("currentScene", out string currentScene)){SceneControllerManager.Instance.FadeAndLoadScene(currentScene, transform.position);}// Get player directionif(sceneSave.stringDictionary.TryGetValue("playerDirection", out string playerDir)){bool playerDirFound = Enum.TryParse<Direction>(playerDir, true, out Direction direction);if (playerDirFound){playerDirection = direction;SetPlayerDirection(playerDirection);}}}}}
}public void ISaveableStoreScene(string sceneName)
{// Nothing required here since the player is on a persistent scene;
}public void ISaveableRestoreScene(string sceneName)
{// Nothing required here since the player is on a persistent scene;
}private void SetPlayerDirection(Direction playerDirection)
{switch(playerDirection){case Direction.up:// set idle up triggerEventHandler.CallMovementEvent(0f, 0f, false, false, false, false, ToolEffect.none, false, false, false, false, false, false, false, false,false, false, false, false, false, false, false, false, true, false, false, false);break;case Direction.down:// set idle down triggerEventHandler.CallMovementEvent(0f, 0f, false, false, false, false, ToolEffect.none, false, false, false, false, false, false, false, false,false, false, false, false, false, false, false, false, false, true, false, false);break;case Direction.left:EventHandler.CallMovementEvent(0f, 0f, false, false, false, false, ToolEffect.none, false, false, false, false, false, false, false, false,false, false, false, false, false, false, false, false, false, false, true, false);break;case Direction.right:EventHandler.CallMovementEvent(0f, 0f, false, false, false, false, ToolEffect.none, false, false, false, false, false, false, false, false,false, false, false, false, false, false, false, false, false, false, false, true);break;default:// set idle down triggerEventHandler.CallMovementEvent(0f, 0f, false, false, false, false, ToolEffect.none, false, false, false, false, false, false, false, false,false, false, false, false, false, false, false, false, false, true, false, false);break;}
}
3、運行游戲
角色種植了Crop,然后進入另一個Scene后,選擇Save Game。
重啟游戲后,選擇 Load Game,此時:
1)角色在另一個Scene中,并且direction保持一直
2)之前種植的Crop狀態未變化