zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }

    我发现我不太会写博客,就直接上代码了,有问题可以直接问我。

      

      

  • 相关阅读:
    自己动手编写一个网络图片爬虫
    使用maven构建项目的注意事项
    maven 构建一个web项目
    构建简单的Maven工程,使用测试驱动的方式开发项目
    像Maven一样构建java项目的目录,更好的管理java工程的源码
    Tomcat源码导入eclipse的步骤
    [HNOI2012] 矿场搭建
    UVA10641 Barisal Stadium 照亮体育馆
    CSP-J/S(NOIP PJ/TG) 游记
    [BalticOI 2011 Day1] Switch the Lamp On
  • 原文地址:https://www.cnblogs.com/lihangppz/p/9749914.html
Copyright © 2011-2022 走看看