Unity3D仿星露谷物语开发66之NPC存档

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里面。

相关推荐
c#上位机3 小时前
C#上位机项目实战——Task.Run执行带参数的方法
c#·上位机
传奇开心果编程3 小时前
【ArkUI 练中学】第15课:UI 界面设计与实战
学习·ui·华为·harmonyos
HwJack204 小时前
【HarmonyOS开发小实践】ArkUI 动画系统属性动画、显式动画与路径动画
ui·性能优化·harmonyos
林川~014 小时前
Unity新输入系统使用笔记
unity·input system
传奇开心果编程5 小时前
【Flutter入门练中学】第2课:布局系统
学习·flutter·ui
传奇开心果编程6 小时前
【Jetpack Compose基础语法学与练】第8课 rememberSaveable,页面旋转/系统重建保留状态
android·学习·ui·kotlin·android jetpack
xy34538 小时前
Axure 9.0 中继器核心结构
前端·ui·html·axure·原型·产品设计
Lost of 程序猿9 小时前
用 YARP 为 .NET 微服务搭一座“立交桥“:路由转发与生产配置实践
c#·asp.net
传奇开心果编程11 小时前
【Jetpack Compose基础语法学与练】第7课 if条件渲染 + 列表基础(LazyColumn)
学习·ui·kotlin·android jetpack
小贺儿开发11 小时前
Unity 结合百度AI开放平台 手写文字识别
人工智能·科技·学习·unity·云服务·文字识别·手写文字