unity3D 封装全局更新函数
Posted lihangppz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity3D 封装全局更新函数相关的知识,希望对你有一定的参考价值。
开发中必不可少的会遇到需要每一帧刷新的境况,一般是用MonoBehaviour中的Update函数。然而开发中不可能每个对象都继承MonoBehaviour,因此需要我们封装一个自己的可以在全局调用的更新函数。
封装全局更新需要考虑到下面几点:
1、全局性,可以在任何一个对象中调用,且在切换场景的时候也可以正常使用。
2、生命周期,需要可以方便的添加移除。
说道全局性,首先想到的是静态和单例,切换场景可以正常使用就需要用到Object.DontDestroyOnLoad(go);。
我们先封装一个全局的GameObject,用于挂载更新和其他全局组件。这个对象只需要两个功能,一个是添加组件,另一个是获取对象。代码非常简单,就不做过多说明。
using UnityEngine; public static class GlobalObject { private static GameObject globalObject = null; public static T AddComponent<T>() where T : MonoBehaviour { T component = GlobalObj.GetComponent<T>(); if (component == null) { component = GlobalObj.AddComponent<T>(); } return component; } public static GameObject GlobalObj { get { if (globalObject == null) { globalObject = GameObject.Find("_GlobalObject"); if (globalObject == null) globalObject = new GameObject("_GlobalObject"); Object.DontDestroyOnLoad(globalObject); } return globalObject; } } }
更新函数依旧在MonoBehaviour调用,因为我们不可能都继承MonoBehaviour,所以我们用一个接口,让需要更新的对象继承接口,然后在一个封装好的AllUpdate中调用。
public interface IZUpdate { void ZUpdate(); }
在封装AllUpdate时,需要两个列表,分别记录当前更新列表和已移除列表。三个核心方法,移除、添加、更新,还有一个单例。代码如下
using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class AllUpdate : MonoBehaviour { private static AllUpdate _allUpdate; private List<IZUpdate> updateList = new List<IZUpdate>(); private List<IZUpdate> removeList=new List<IZUpdate>(); private static AllUpdate allUpdate { get { if (_allUpdate == null) { try { _allUpdate = GlobalObject.AddComponent<AllUpdate>(); } catch (Exception e) { Debug.LogError(e.ToString()); } } return _allUpdate; } } public static void AddUpdate(IZUpdate update) { allUpdate.updateList.Add(update); } public static void RemoveUpdate(IZUpdate update) { allUpdate.removeList.Add(update); } private void RemoveUpdate() { while (removeList.Count>0) { updateList.Remove(removeList[0]); removeList.RemoveAt(0); } } void Update() { RemoveUpdate(); for (int i = 0; i < updateList.Count; i++) { if (removeList.IndexOf(updateList[i])==-1) { if (updateList[i] == null) continue; updateList[i].ZUpdate(); } } } }
讲上面三处代码添加到unity工程里,就可以直接用了,下面是我写的一个简单测试。我把这个脚本挂载主摄像机上的。
using UnityEngine; using System.Collections; public class TestUpdate : MonoBehaviour, IZUpdate { public float time; void OnGUI() { if (GUI.Button(new Rect(50, 250, 200, 20), "添加更新")) { AllUpdate.AddUpdate(this); } if (GUI.Button(new Rect(280, 250, 200, 20), "移除更新")) { AllUpdate.RemoveUpdate(this); } } public void ZUpdate() { time += Time.deltaTime; if (time > 1) { time = 0; Debug.Log("每隔一秒打印一次" + Time.time); } } }
我发现我不太会写博客,就直接上代码了,有问题可以直接问我。
以上是关于unity3D 封装全局更新函数的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装
VSCode自定义代码片段14——Vue的axios网络请求封装