目录

  • 系列文章目录
  • 前言
  • 1
    • 1.1
    • 1.2
    • 1.3
    • 2 总结

系列文章目录

迷失岛游戏框架开发个人每集总结(第一期)
迷失岛游戏框架开发个人每集总结(第二期)
迷失岛游戏框架开发个人每集总结(第三期)

前言

在上一期中,我们实现了通过鼠标点击带有标签“item”的物体,根据物品的名称在已设置好的,内容为物品的名称及其对应图片的列表里寻找该物品信息,该物体的图片、名称以及将对应的序号传给订阅获取这些信息事件的InventoryUI。根据这些信息对我们的ui进行更新。
这一期要实现的是保存物品在场景中的状态,以及互动的状态。这样在切换场景后就不会出现例如:刚刚在该场景拾取了钥匙,切换场景回来后钥匙依旧在该场景里显示的情况。

1

1.1

ObjectManager 用于管理物品状态

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//用于保存物品以及的状态
//场景第一次被加载进来之后,我要记录有哪些物体来构成我们的字典,并且场景里还有一些互动,在卸载这个场景之前,我要记录它们的状态public class ObjectManager : MonoBehaviour
{//创建一个字典,储存物品的名字以及判断该物品是否可用的布尔值private Dictionary<ItemName, bool> itemAvailableDict = new Dictionary<ItemName, bool>();private Dictionary<string, bool> interactiveStateDict = new Dictionary<string, bool>();//保存互动状态//注册事件的方法private void OnEnable(){EventHandler.BeforeSceneUnloadEvent += OnBeforeSceneUnloadEvent;EventHandler.AfterSceneUnloadEvent += OnAfterSceneUnloadEvent;EventHandler.updateUIEvent += OnUpdateUIEvent;}private void OnDisable(){EventHandler.BeforeSceneUnloadEvent -= OnBeforeSceneUnloadEvent;EventHandler.AfterSceneUnloadEvent -= OnAfterSceneUnloadEvent;EventHandler.updateUIEvent -= OnUpdateUIEvent;}private void OnBeforeSceneUnloadEvent(){foreach (var item in FindObjectsOfType<Item>()){if (!itemAvailableDict.ContainsKey(item.itemName))itemAvailableDict.Add(item.itemName, true);//true代表在当前场景中该物体是显示状态}foreach (var item in FindObjectsOfType<Interactive>()){if (interactiveStateDict.ContainsKey(item.name))interactiveStateDict[item.name] = item.isDone;elseinteractiveStateDict.Add(item.name, item.isDone);}}private void OnAfterSceneUnloadEvent(){//如果已经在字典中则更新显示状态,不在则添加foreach(var item in FindObjectsOfType<Item>()){if (!itemAvailableDict.ContainsKey(item.itemName))itemAvailableDict.Add(item.itemName, true);elseitem.gameObject.SetActive(itemAvailableDict[item.itemName]);}foreach (var item in FindObjectsOfType<Interactive>()){if (interactiveStateDict.ContainsKey(item.name))item.isDone=interactiveStateDict[item.name] ;elseinteractiveStateDict.Add(item.name, item.isDone);}}//只在拾取物品后更新private void OnUpdateUIEvent(ItemDetails itemDetails ,int arg2){if(itemDetails!=null){itemAvailableDict[itemDetails.itemName] = false;}}
}

OnBeforeSceneUnloadEvent()
这段代码实现了一个名为 OnBeforeSceneUnloadEvent 的函数,它是在 Unity 场景销毁前执行的事件回调函数。

具体来说,该函数会获取场景中所有类型为 Item 的游戏对象,依次遍历这些游戏对象,然后将每个对象的 itemName 属性作为键值,
在 itemAvailableDict 字典中添加一个布尔型的值(如果该键值不存在)。itemAvailableDict 是一个存储 Item 对象可用性的字典
在这个场景被卸载前,我们需要将场景中所有 Item 对象的可用性信息收集起来,并保存到该字典中。

具体而言,FindObjectsOfType() 是一个函数调用,它返回当前场景中所有类型为 Item 的对象。接着,foreach 循环遍历这些对象,
对于每个对象,程序判断它的 itemName 是否已经存在于 itemAvailableDict 中,如果不存在,则将其添加到 itemAvailableDict 中,对应的布尔值为 true。

这段代码可能运行在 MonoBehavoir 的派生类中,例如 SceneManager 或某个具体的场景控制器,以实现在场景加载和卸载时进行特定的逻辑处理。

小知识
在 Unity 中,private void OnEnable() 是一个生命周期函数,它会在脚本对象被启用时自动调用。
当我们需要对脚本执行初始化操作时,可以在该函数中进行相应的操作。

具体来说,当脚本对象被创建时,默认处于禁用状态,此时 OnEnable() 函数不会被调用。
而当我们手动启用脚本对象(例如将其挂载到场景中的游戏物体上,并勾选其对应的“启用”选项),则 OnEnable() 函数会被调用。

在 OnEnable() 函数中,我们可以进行初始化、注册事件监听器、获取组件等操作,以确保脚本在启用后能够正常运行。
同时,在 OnDisable() 函数中,我们可以进行反初始化、取消事件监听器等操作,以确保脚本在禁用或销毁时不会继续运行或产生错误。

总之,OnEnable() 函数是在脚本对象被启用时自动调用的函数,在其中执行必要的初始化操作可以保证脚本能够正常运行。

1.2

EventHandler

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class EventHandler : MonoBehaviour
{  public static event Action<ItemDetails, int> updateUIEvent;public static void CallUpdateUIEvent(ItemDetails itemDetails,int index){updateUIEvent?.Invoke(itemDetails, index);}/*创建两个事件来传递或者执行某些函数方法,这两个事件用于提醒订阅了这两个事件的ObjectManager 在场景切换前以及切换到该场景前更新字典的数据*/public static event Action BeforeSceneUnloadEvent;public static void CallBeforeSceneUnloadEvent(){BeforeSceneUnloadEvent?.Invoke();}public static event Action AfterSceneUnloadEvent;public static void CallAfterSceneUnloadEvent(){AfterSceneUnloadEvent?.Invoke();}}

1.3

TransitionManger

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;//用于场景的加载和卸载
public class TranstionManager : Singleton<TranstionManager>//TransitionManager用于实现场景的切换,每次点击场景切换箭头后将Teleport to H1 的两个变量传入到TransitonManager//将TransitionManager设置为单例模式
{[SceneName] public string startScene;private bool isFade;//判断是否切换场景public CanvasGroup fadeCanvasGroup;public float fadeDuration;//用于控制渐进渐出的速度private bool canTransition;//加载游戏一开始的场景public void Start(){StartCoroutine(TransitionToScene (string.Empty, startScene));}public void Transition(string from,string to)//用于场景切换{if(!isFade&&canTransition)//运用协程的方法卸载当前的场景,重新加载要去到的那个场景,并且将它设置为AdditiveStartCoroutine((IEnumerator)TransitionToScene(from,to));}private IEnumerator TransitionToScene(string from,string to){yield return Fade(1);if(from!=string.Empty){//在场景卸载前,呼叫订阅了该事件的代码执行方法EventHandler.CallBeforeSceneUnloadEvent();yield return SceneManager.UnloadScene(from);//卸载当前激活的场景from,并通过yield return语句返回该操作的结果}yield return SceneManager.LoadSceneAsync(to, LoadSceneMode.Additive);//使用SceneManager.LoadSceneAsync方法异步加载新场景to,//并将其添加到场景列表中//设置新场景为激活场景Scene newScene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);SceneManager.SetActiveScene(newScene);EventHandler.CallAfterSceneUnloadEvent();yield return Fade(0);}private IEnumerator Fade(float targetAlpha){//传进一个数,如果是0就变成透明的,如果是1就变成黑色isFade = true;//核心方法:在场景中创建一个canvasfadeCanvasGroup.blocksRaycasts = true;float speed = Math.Abs(fadeCanvasGroup.alpha - targetAlpha)/fadeDuration;while (!Mathf.Approximately(fadeCanvasGroup.alpha, targetAlpha)){fadeCanvasGroup.alpha = Mathf.MoveTowards(fadeCanvasGroup.alpha, targetAlpha,speed * Time.deltaTime);yield return null;}fadeCanvasGroup.blocksRaycasts = false;isFade = false;}
}

2 总结

这一节比较简单。

【迷失岛游戏框架开发个人每集总结(第四期)】相关推荐

  1. 【迷失岛游戏框架开发个人每集总结(第三期)】

    目录 系列文章目录 前言 1代码 1.1 1.2 1.3 1.4 2 总结 系列文章目录 迷失岛游戏框架开发个人每集总结(第一期) 迷失岛游戏框架开发个人每集总结(第二期) 前言 在上一期中,我们实现 ...

  2. 《迷失岛2》游戏开发框架开发日记:场景切换和淡入淡出效果

    M_Studio的教程:[<迷失岛2>游戏框架开发01:实现场景转换|Unity教程] 搭建场景 使用下载好的素材搭建场景H1-H4和H2A.永久的场景Persistent,将场景都拖拽到 ...

  3. 迷失岛3计算机密码,迷失岛3在计算机内输入隐藏字母怎么完成_迷失岛3计算机天才成就攻略_玩游戏网...

    <迷失岛3>一周目第三关攻略 迷失岛3宇宙的尘埃一周目第三关怎么过?迷失岛系列第三部终于上线了,小编这里带来了迷失岛3一周目第三关攻略,想要参考的玩家们就一起来看看吧!>>&g ...

  4. 基于Volcano 3D游戏引擎开发一个类似魔兽世界的场景

    VOLCANO MMORPG 3D游戏引擎简介 1.基本介绍:http://volcano2014.cn/ VOLCANO是一款MMORPG(大型多人在线角色扮演)3D网络游戏的开发引擎,用作支持用户 ...

  5. 如何构建自己的游戏框架并且制作游戏

    这个教程就让我们学习怎么用这个游戏框架开发一个简单的空战游戏吧!由于素材有限,都是用的网上的素材.这个游戏可以改造成为空战或者植物大战僵尸等的养成类型游戏或者更多,原理都差不多.    一个出类拔萃的 ...

  6. 【CSON原创】HTML5游戏框架cnGameJS开发实录(外部输入模块篇)

    返回目录 1.为什么我们需要外部输入模块? 在游戏中我们常常用到类似这样的操作:鼠标点击某位置,玩家对象移动到该位置,或者按鼠标方向键,玩家向不同方向移动,等等.这些操作无一不用与外部输入设备打交道. ...

  7. arduino nano 蓝牙_探索 Golang 云原生游戏服务器开发,5 分钟上手 Nano 游戏服务器框架...

    介绍 Nano 是什么? 轻量级,方便,高性能 golang 的游戏服务器框架. nano 是一个轻量级的服务器框架,它最适合的应用领域是网页游戏.社交游戏.移动游戏的服务端.当然还不仅仅是游戏,用  ...

  8. 【CSON原创】HTML5游戏框架cnGameJS开发实录(精灵对象篇)

    返回目录 1.什么是精灵对象(sprite)? 所谓的精灵对象,就是游戏中的一个具有行为的元素,以超级玛丽为例,玛丽,敌人都算是一个精灵对象.在cnGameJS框架中,精灵对象如下几个特点: 1.添加 ...

  9. 【CSON原创】HTML5游戏框架cnGameJS开发实录

    cnGameJS是本人开发的一个基于HTML5的游戏框架,包括资源加载,碰撞检测,动画等模块.本系列文章主要介绍各个模块的开发流程,以及附上两个使用该框架进行开发的游戏demo. 目录: 1.核心函数 ...

最新文章

  1. 独家 | 数据科学家指南:梯度下降与反向传播算法
  2. Windows10 + Visual Studio 2017 + CMake +OpenCV编译、开发环境配置及测试
  3. LeNet-5 经典卷积网络模型浅析
  4. Android Studio之Instant Run requires ‘Tools | Android | Enable ADB integration‘ to be enabled解决办法
  5. matlab mex路径,使用matlab进行mex编译时的路径问题mexopts
  6. SHELL $RANDOM产生的随机数范围是0到32767
  7. 杭电acm2019数列有序!
  8. MSB与LSB的含义
  9. 几种常见的程序命名规则
  10. 【洛谷P1256】公路修建(问题分析+最小生成树prim法)
  11. Docker Desktop 安装使用教程
  12. 一位全减器逻辑电路图_用74ls138实现一位全减器 - 数字电路图
  13. 微软官方出了一款吊打WPS的PPT插件
  14. H5唤起APP进行分享的尝试
  15. error in ./node_modules/@lit/reactive-element/decorators/state.jsModule parse failed: Unexpected
  16. ElasticSearch教程——创建索引、类型、文档
  17. 【C51单片机】PC机控制单片机
  18. 一文读懂什么是cookie和session。
  19. 上海爱立信实习笔试面试
  20. 山寨电视不会成为山寨手机第二

热门文章

  1. uni-app 中如何打开外部应用,如:浏览器、淘宝、京东、微博等
  2. DNS服务器地址小总结
  3. Java云同桌学习系列(十五)——MySQL数据库
  4. 从算法工程师到全栈开发者,我终于明白了数据科学的真谛
  5. SQL45 将titles_test表名修改为 titles_2017
  6. Oracle19c数据库安装教程【Windows版】
  7. mac 设置java环境变量_mac下java环境变量配置
  8. 部署搭建DNS服务器
  9. shell脚本——学习笔记(包含应用案例)
  10. Android应用开发--MP3音乐播放器滚动歌词实现