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

相关推荐
NoteStream1 天前
【C语言基础】分支和循环(上)
c语言·开发语言·c++·经验分享·笔记·算法·c#
lzhdim1 天前
C# 通过 Windows API 实现进程内存读写操作
开发语言·windows·c#
-银雾鸢尾-1 天前
C#中的预处理指令
开发语言·c#
dalong101 天前
Savitzky-Golay 的C# 实现
开发语言·kotlin·c#
小小工匠1 天前
把生成模型接进 Agent:Higgsfield MCP 的架构拆解与工程实践
ui·higgsfield mcp·impeccable
猿长大人1 天前
C# | Autofac 新手指南:从零理解依赖注入与组件装配
c#·.net·di·依赖注入
show4331 天前
多格式导出怎么做?2026免费小程序TXT/SRT实践
开发语言·小程序·c#
czhaii1 天前
word插入表格排版创建或编辑应用技巧
ui·c#·xhtml
智塑未来1 天前
打开快、切换顺、游戏稳:鸿蒙的日常流畅表现
游戏·华为·harmonyos
zhchyun20081 天前
# 【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(03)
unity