1、目标
保存NPC的位置信息。
2、修改NPCMovement.cs脚本
添加一个新方法来取消NPC移动,如果有NPC正在移动则取消之。
添加函数:
cs
public void CancelNPCMovement()
{
npcPath.ClearPath();
npcNextGridPosition = Vector3Int.zero;
npcNextWorldPosition = Vector3.zero;
npcIsMoving = false;
if(moveToGridPositionRoutine != null)
{
StopCoroutine(moveToGridPositionRoutine);
}
// Reset move animation
ResetMoveAnimation();
// Clear event animation
ClearNPCEventAnimation();
npcTargetAniamtionClip = null;
// Reset idle animation
ResetIdleAnimation();
// Set idle animation
SetIdleAnimation();
}
3、重写NPC.cs脚本
cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(NPCMovement))]
[RequireComponent(typeof(GenerateGUID))]
public class NPC : MonoBehaviour, 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; } }
private NPCMovement npcMovement;
private void OnEnable()
{
ISaveableRegister();
}
private void OnDisable()
{
ISaveableDeregister();
}
private void Awake()
{
ISaveableUniqueID = GetComponent<GenerateGUID>().GUID;
GameObjectSave = new GameObjectSave();
}
private void Start()
{
// get npc movement component
npcMovement = GetComponent<NPCMovement>();
}
public void ISaveableDeregister()
{
SaveLoadManager.Instance.iSaveableObjectList.Remove(this);
}
public void ISaveableRegister()
{
SaveLoadManager.Instance.iSaveableObjectList.Add(this);
}
public void ISaveableRestoreScene(string sceneName)
{
// Nothing required here since on persistent scene
}
public void ISaveableStoreScene(string sceneName)
{
// Nothing required here since on persistent scene
}
public GameObjectSave ISaveableSave()
{
// Remove current scene save
GameObjectSave.sceneData.Remove(Settings.PersistentScene);
// Create scene save
SceneSave sceneSave = new SceneSave();
// Create vector 3 serialisable dictonary
sceneSave.vector3Dictionary = new Dictionary<string, Vector3Serializable>();
// Create string dictionary
sceneSave.stringDictionary = new Dictionary<string, string>();
// Store target grid position, target world position, and target scene
sceneSave.vector3Dictionary.Add("npcTargetGridPosition", new Vector3Serializable(npcMovement.npcTargetGridPosition.x, npcMovement.npcTargetGridPosition.y,
npcMovement.npcTargetGridPosition.z));
sceneSave.vector3Dictionary.Add("npcTargetWorldPosition", new Vector3Serializable(npcMovement.npcTargetWorldPosition.x, npcMovement.npcTargetWorldPosition.y,
npcMovement.npcTargetWorldPosition.z));
sceneSave.stringDictionary.Add("npcTargetScene", npcMovement.npcTargetScene.ToString());
// Add scene save to game object
GameObjectSave.sceneData.Add(Settings.PersistentScene, sceneSave);
return GameObjectSave;
}
public void ISaveableLoad(GameSave gameSave)
{
// Get game object scene
if(gameSave.gameObjectData.TryGetValue(ISaveableUniqueID, out GameObjectSave gameObjectSave))
{
GameObjectSave = gameObjectSave;
// Get scene save
if(GameObjectSave.sceneData.TryGetValue(Settings.PersistentScene, out SceneSave sceneSave))
{
// if dictionaries are not null
if(sceneSave.vector3Dictionary != null && sceneSave.stringDictionary != null)
{
// target grid position
if(sceneSave.vector3Dictionary.TryGetValue("npcTargetGridPosition", out Vector3Serializable savedNPCTargetGridPosition))
{
npcMovement.npcTargetGridPosition = new Vector3Int((int)savedNPCTargetGridPosition.x, (int)savedNPCTargetGridPosition.y, (int)savedNPCTargetGridPosition.z);
npcMovement.npcCurrentGridPosition = npcMovement.npcTargetGridPosition;
}
// target world position
if(sceneSave.vector3Dictionary.TryGetValue("npcTargetWorldPosition", out Vector3Serializable savedNPCTargetWorldPosition))
{
npcMovement.npcTargetWorldPosition = new Vector3(savedNPCTargetWorldPosition.x, savedNPCTargetWorldPosition.y, savedNPCTargetWorldPosition.z);
transform.position = npcMovement.npcTargetWorldPosition;
}
// target scene
if(sceneSave.stringDictionary.TryGetValue("npcTargetScene", out string savedTargetScene))
{
if(Enum.TryParse<SceneName>(savedTargetScene, out SceneName sceneName))
{
npcMovement.npcTargetScene = sceneName;
npcMovement.npcCurrentScene = npcMovement.npcTargetScene;
}
}
// Clear any current NPC movement
npcMovement.CancelNPCMovement();
}
}
}
}
}
运行游戏
NPC走到Scene3_Cabin后点击Save Game。
然后重新Load Game,NPC出现在Scene3_Cabin里面。
