美文网首页
Unity中,简易的光效播放系统

Unity中,简易的光效播放系统

作者: 全新的饭 | 来源:发表于2022-05-27 11:08 被阅读0次

    使用方法

     EffectSys.Instance.CreateEffect(光效模板(如预制体), 位置, 光效持续时间(可不填));
     EffectSys.Instance.CreateEffect(光效模板(如预制体), 父节点, 光效持续时间(可不填));
    
    若不填光效持续时间,则CreateEffect方法会返回生成的光效:由外部自行控制光效的销毁。
    

    相关代码

    EffectSys.cs

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class EffectSys : MonoBehaviour
    {
        private static EffectSys _instance;
        public static EffectSys Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject go = new GameObject(nameof(EffectSys));
                    _instance = go.AddComponent<EffectSys>();
    
                    var parentGo = GameObject.Find("Singleton");
                    if (parentGo == null)
                    {
                        parentGo = new GameObject("Singleton");
                        UnityEngine.Object.DontDestroyOnLoad(parentGo);
                    }
    
                    go.transform.SetParent(parentGo.transform);
                }
                return _instance;
            }
        }
    
        public void Destroy()
        {
            Destroy(Instance.gameObject);
            _instance = null;
        }
    
        private void DelayCall(float delayTime, Action action)
        {
            StartCoroutine(DelayCallCoroutine());
            IEnumerator DelayCallCoroutine()
            {
                yield return new WaitForSeconds(delayTime);
                action?.Invoke();
            }
        }
    
        #region 创建和销毁光效
        // 在指定位置创建一个特效,经过指定时间后消失
        public void CreateEffect(GameObject templateGo, Vector3 pos, float lifeTime)
        {
            CreateEffect(templateGo, pos, transform, lifeTime);
        }
        // 在指定Transform下创建一个特效,经过指定时间后消失
        public void CreateEffect(GameObject templateGo, Transform parent, float lifeTime)
        {
            CreateEffect(templateGo, parent.transform.position, parent, lifeTime);
        }
        // 在指定位置创建一个特效,外部控制其消失
        public GameObject CreateEffect(GameObject templateGo, Vector3 pos)
        {
            return CreateEffect(templateGo, pos, transform, -1);
        }
        // 在指定Transform下创建一个特效,外部控制其消失
        public GameObject CreateEffect(GameObject templateGo, Transform parent)
        { 
            return CreateEffect(templateGo, parent.transform.position, parent, -1);
        }
    
        private GameObject CreateEffect(GameObject templateGo, Vector3 pos, Transform parent, float lifeTime)
        { 
            var go = GOPool.Instance.GetInstance(templateGo);
            go.transform.position = pos;
            go.transform.SetParent(parent);
            go.SetActive(true);
            if (lifeTime > 0)
            {
                DelayCall(lifeTime, () => DestroyEffect(templateGo, go));
            }
    
            return go;
        }
    
        // 销毁光效
        public void DestroyEffect(GameObject templateGo, GameObject go)
        {
            GOPool.Instance.RecycleInstance(templateGo, go);
        }
        #endregion
    }
    

    GOPool.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 外界可以传入GO模板,获取GO实例
    /// </summary>
    public class GOPool : MonoBehaviour
    {
    
        private static GOPool _instance;
        private Dictionary<GameObject, GOPoolObj> _goPoolDict;
        public static GOPool Instance
        {
            get
            {
                if (_instance == null)
                {
                    GameObject go = new GameObject(nameof(GOPool));
                    _instance = go.AddComponent<GOPool>();
                    _instance._goPoolDict = new Dictionary<GameObject, GOPoolObj>();
    
                    var parentGo = GameObject.Find("Singleton");
                    if (parentGo == null)
                    {
                        parentGo = new GameObject("Singleton");
                        UnityEngine.Object.DontDestroyOnLoad(parentGo);
                    }
    
                    go.transform.SetParent(parentGo.transform);
                }
                return _instance;
            }
        }
    
        public void Destroy()
        {
            foreach (var value in _goPoolDict.Values)
            {
                value.Destroy();
            }
    
            _goPoolDict.Clear();
            _goPoolDict = null;
    
            Destroy(Instance.gameObject);
            _instance = null;
        }
    
        public GameObject GetInstance(GameObject goTemplate)
        {
            EnsureDictHasKey(goTemplate);
            return _goPoolDict[goTemplate].GetInstance();
        }
        public void RecycleInstance(GameObject goTemplate, GameObject go)
        {
            EnsureDictHasKey(goTemplate);
            _goPoolDict[goTemplate].RecycleInstance(go);
        }
    
        private void EnsureDictHasKey(GameObject key)
        {
            if (!_goPoolDict.ContainsKey(key))
            {
                var go = new GameObject(key.name);
                go.transform.SetParent(transform);
                var goPoolObj = new GOPoolObj(go, key);
                _goPoolDict.Add(key, goPoolObj);
            }
        }
    
        private class GOPoolObj
        {
            private readonly GameObject MyGo;
            private readonly GameObject GOTemplate;
            private List<GameObject> _gos;
    
            public GOPoolObj(GameObject myGo, GameObject goTemplate)
            {
                MyGo = myGo;
                GOTemplate = goTemplate;
                _gos = new List<GameObject>();
            }
    
            public void Destroy()
            {
                _gos.Clear();
                _gos = null;
                GameObject.Destroy(MyGo);
            }
    
            public GameObject GetInstance()
            {
                if (_gos.Count == 0)
                {
                    var instance = Instantiate(GOTemplate, MyGo.transform);
                    instance.name = GOTemplate.name + "_0";
                    _gos.Add(instance);
                }
    
                var go = _gos[0];
                _gos.RemoveAt(0);
                return go;
            }
            public void RecycleInstance(GameObject go)
            {
                if (MyGo == null)
                {
                    return;
                }
                
                go.name = GOTemplate.name + "_" + _gos.Count;
                go.transform.SetParent(MyGo.transform);
    
                go.transform.localPosition = Vector3.zero;
                go.transform.localRotation = Quaternion.identity;
                go.transform.localScale = Vector3.one;
    
                go.SetActive(false);
    
                _gos.Add(go);
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Unity中,简易的光效播放系统

          本文链接:https://www.haomeiwen.com/subject/mhumprtx.html