Unity3D仿星露谷物语开发56之保存角色位置到文件

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状态未变化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/83136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TKernel模块--杂项

TKernel模块–杂项 1.DEFINE_HARRAY1 #define DEFINE_HARRAY1(HClassName, _Array1Type_) \ class HClassName : public _Array1Type_, public Standard_Transient { \public: …

c++ typeid运算符

typeid运算符能获取类型信息。获取到的是type_info对象。type_info类型如下&#xff1a; 可以看到&#xff0c;这个类删除了拷贝构造函数以及等号操作符。有一些成员函数&#xff1a;hash_code、before、name、raw_name, 还重载了和!运算符。 测试&#xff1a; void testTyp…

第304个Vulnhub靶场演练攻略:digital world.local:FALL

digital world.local&#xff1a;FALL Vulnhub 演练 FALL (digitalworld.local: FALL) 是 Donavan 为 Vulnhub 打造的一款中型机器。这款实验室非常适合经验丰富的 CTF 玩家&#xff0c;他们希望在这类环境中检验自己的技能。那么&#xff0c;让我们开始吧&#xff0c;看看如何…

【数据库】数据库恢复技术

数据库恢复技术 实现恢复的核心是使用冗余&#xff0c;也就是根据冗余数据重建不正确数据。 事务 事务是一个数据库操作序列&#xff0c;是一个不可分割的工作单位&#xff0c;是恢复和并发的基本单位。 在关系数据库中&#xff0c;一个事务是一条或多条SQL语句&#xff0c…

switch-case判断

switch-case判断 #include <stdio.h> int main() {int type;printf("请输入你的选择&#xff1a;\n");scanf("%d",&type);getchar();switch (type){case 1:printf("你好&#xff01;");break;case 2:printf("早上好&#xff01;…

从监控到告警:Prometheus+Grafana+Alertmanager+告警通知服务全链路落地实践

文章目录 一、引言1.1 监控告警的必要性1.2 监控告警的基本原理1.2.1 指标采集与存储1.2.2 告警规则与触发机制1.2.3 多渠道通知与闭环 二、技术选型与架构设计2.1 为什么选择 Prometheus 及其生态2.1.1 Prometheus 优势分析2.1.2 Grafana 可视化能力2.1.3 Alertmanager 灵活告…

STM32 UART通信实战指南:从原理到项目落地

STM32串口通信实战指南&#xff1a;从零开始手把手教你 前言&#xff1a;为什么串口这么重要&#xff1f; 在嵌入式开发中&#xff0c;串口就像设备的"嘴巴"和"耳朵"。无论是给单片机下达指令、读取传感器数据&#xff0c;还是让两个模块"对话"…

Jmeter requests

1.Jemter元件和组件 1.1 元件和组件的概念 元件&#xff1a;多个功能相似的的组件的容器&#xff0c;类似于一个工具箱。 组件&#xff1a;实现某个特定功能的实例&#xff0c;类似于工具箱中的螺丝刀&#xff0c;十字扳手... 1.2 作用域和执行顺序 1.2.1 作用域 例子&#…

计算机视觉---GT(ground truth)

在计算机视觉&#xff08;Computer Vision, CV&#xff09;领域&#xff0c;Ground Truth&#xff08;GT&#xff0c;中文常译为“真值”或“ ground truth”&#xff09; 是指关于数据的真实标签或客观事实&#xff0c;是模型训练、评估和验证的基准。它是连接算法与现实世界的…

1-Wire 一线式总线:从原理到实战,玩转 DS18B20 温度采集

引言 在嵌入式系统中&#xff0c;通信总线是连接 CPU 与外设的桥梁。从 I2C、SPI 到 UART&#xff0c;每种总线都有其独特的应用场景。而本文要介绍的1-Wire 一线式总线&#xff0c;以其极简的硬件设计和独特的通信协议&#xff0c;在温度采集、身份识别等领域大放异彩。本文将…

基于开源AI大模型AI智能名片S2B2C商城小程序源码的销售环节数字化实现路径研究

摘要&#xff1a;在数字化浪潮下&#xff0c;企业销售环节的转型升级已成为提升竞争力的核心命题。本文基于清华大学全球产业研究院《中国企业数字化转型研究报告&#xff08;2020&#xff09;》提出的“提升销售率与利润率、打通客户数据、强化营销协同、构建全景用户画像、助…

Linux浅谈

Linux浅谈 一、什么是 Linux&#xff1f;先抛开 “内核”&#xff0c;看整体 可以把 Linux 系统 想象成一台 “组装电脑”&#xff1a; 最核心的零件是 “主板”—— 这就是 Linux 内核&#xff08;Kernel&#xff09;&#xff0c;负责管理电脑里的所有硬件&#xff08;比如 …

PostgreSQL ERROR: out of shared memory处理

使用pg_dump命令导出一个库的时候&#xff0c;报 pg_dump: error: query failed: ERROR: out of shared memory HINT: You might need to increase "max_locks_per_transaction". 从错误字面上看是超出内存大小了&#xff0c;建议增加max_locks_per_transaction参…

IoT/基于NB28-A/BC28-CNV通信模组使用AT指令连接华为云IoTDA平台(HCIP-IoT实验2)

文章目录 概述检查通信环境通信模组固件信号强度CGATT指令参数 / 啥是PS域&#xff1f;PS附着状态&#xff1a;ATCGATTPLMN 选择&#xff1a;ATCOPSCEREG指令参数 / 啥是EPS与EPC?CEREG指令参数 / 啥是URC?网络注册状态&#xff1a;ATCEREG网络附着和网络注册 AT指令接入IoTD…

红外遥控(外部中断)

目录 1.红外遥控简介 通信方式&#xff1a; 红外LED波长&#xff1a; 通信协议标准&#xff1a; 2.硬件电路 发送部分1&#xff1a; 内部元件介绍&#xff1a; 工作原理&#xff1a; 为什么要以38KHZ亮灭&#xff1f; 电路图&#xff1a; 发送部分2&#xff1a; 电…

【C#】一个简单的http服务器项目开发过程详解

这跟安装NoteJs程序运行脚本文件搭建一个简单Http服务器一样&#xff0c;相比起来&#xff0c;它的优点是可以开发的应用是免安装&#xff0c;跨平台的&#xff0c;放在移动盘上便捷的&#xff0c;这里着重讲http服务器实现的过程&#xff0c;以便自主实现特定的功能和服务。 …

WPF【11_4】WPF实战-重构与美化(MVVM 架构)

11-9 【理论】MVVM 架构 在 WPF 项目中&#xff0c;我们主要采用的是一种类似 MVC 的架构&#xff0c;叫做 MVVM。 MVVM 继承了 MVC 的理念&#xff0c;是 Model-View-ViewModel 的缩写&#xff0c;中文意思是模型、视图、视图模型。这三个词分开看我们都能看懂&#xff0c;不…

使用PowerBI个人网关定时刷新数据

使用PowerBI个人网关定时刷新数据 PowerBI desktop连接mysql&#xff0c;可以设置定时刷新数据或在PowerBI服务中手动刷新数据,步骤如下&#xff1a; 第一步&#xff1a; 下载网关。以个人网关为例&#xff0c;如图 第二步&#xff1a; 双击网关&#xff0c;点击下一步&…

深度学习驱动的超高清图修复技术——综述

Deep Learning-Driven Ultra-High-Definition Image Restoration: A Survey Liyan Wang, Weixiang Zhou, Cong Wang, Kin-Man Lam, Zhixun Su, Jinshan Pan Abstract Ultra-high-definition (UHD) image restoration​​ aims to specifically solve the problem of ​​quali…

3 分钟学会使用 Puppeteer 将 HTML 转 PDF

需求背景 1、网页存档与文档管理 需要将网页内容长期保存或归档为PDF,确保内容不被篡改或丢失,适用于法律文档、合同、技术文档等场景。PDF格式便于存储和检索。 2、电子报告生成 动态生成的HTML内容(如数据分析报告、仪表盘)需导出为PDF供下载或打印。PDF保留排版和样…