• 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);
            }
        }
    }

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

      

      

  • 相关阅读:
    N4-某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
    N3-按链表值从尾到头的顺序返回一个ArrayList。
    N2-替换字符串空格
    innodb死锁1213
    innodb是行锁还是表锁
    docker是什么,docker干什么用
    innodb通过frm ibd还原数据,线上项目验证过
    机器性能预警系统(cpu,process,内存,硬盘监控)并钉钉机器人报警
    mysql++ query.more_results()为true时,query.store_next()就崩掉了
    yum install nload失败,提示No package nload available.Error: Nothing to do
  • 原文地址:https://www.cnblogs.com/lihangppz/p/9749914.html
Copyright © 2020-2023  润新知