欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity实现简单技能冷却管理器

程序员文章站 2022-04-03 09:17:33
...

前言

这段时间做技能系统,需要实现技能冷却。如果每个技能都写一段计时器代码的话重复性太高而且还不方便管理,于是根据使用到的功能写了个简单的冷却管理器统一处理。

实现

代码很简单,理解思路即可。
这里我方法中传的key为了方便管理和传参使用的枚举,可以使用字符串替换。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class CDMgr : MonoSingleton<CDMgr>  //这里继承的单例,可自己实现
{
    Dictionary<string, float> dic = new Dictionary<string, float>(); //保存id和cd时长信息
    Dictionary<string, float> cds = new Dictionary<string, float>(); //保存当前的cd
    List<string> ids = new List<string>(); //保存id

    void Update()
    {
    	//冷却计时
        if(ids.Count > 0)
        {
            ids.ForEach(_ =>
            {
                if (cds[_] > 0)
                {
                    cds[_] -= Time.deltaTime;
                }
            });
        }
    }
	
	//第一个参数传字符串也可,这里为了方便传参用的枚举
	//第二个参数为cd时长
    public void AddCD(GlobalParameter.CDType type,float time)
    {
        var id = type.ToString();
        if (dic.ContainsKey(id))
        {
            Debug.LogError("该ID已存在!");
            return;
        }
        dic.Add(id, time);
        cds.Add(id, 0); //一开始没进入冷却
        ids.Add(id);
    }
	
	//进入冷却
    void StartCal(string id)
    {
        if (!dic.ContainsKey(id))
        {
            Debug.LogError("不存在该ID!");
            return;
        }

        cds[id] = dic[id];
    }
	
	//是否冷却结束,如果冷却结束会返回true并重新开始计算cd
    public bool IsReady(GlobalParameter.CDType type)
    {
        var id = type.ToString();
        if (cds.ContainsKey(id))
        {
            if(cds[id] <= 0)
            {
                StartCal(id);
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            Debug.LogError("不存在该ID!");
            return false;
        }
    }

	//获取当前CD
    public float GetCurrentCD(GlobalParameter.CDType type)
    {
        var id = type.ToString();
        if (cds.ContainsKey(id))
        {
            return cds[id];
        }
        else
        {
            Debug.LogError("不存在该ID!");
            return 9999999;
        }
    }

	//获取CD时长
    public float GetWholeCD(GlobalParameter.CDType type)
    {
        var id = type.ToString();
        if (dic.ContainsKey(id))
        {
            return dic[id];
        }
        else
        {
            Debug.LogError("不存在该ID!");
            return 9999999;
        }
    }
	
	//移除id
    public void RemoveCD(GlobalParameter.CDType type)
    {
        var id = type.ToString();
        if (dic.ContainsKey(id))
        {
            dic.Remove(id);
            cds.Remove(id);
            ids.Remove(id);
        }
        else
        {
            Debug.LogError("不存在该ID!");
        }
    }
}

使用

CDMgr脚本挂到场景中。
初始化时需要调用AddCD()注册进去。
判断冷却结束使用IsReady()即可。
如果不需要计时则使用RemoveCD()移除该计时,起到性能优化效果。
如果技能冷却中需要实现相关效果则可以通过GetCurrentCD()获取当前CD时长。
示例代码:

public class LaserAttackTri : MonoBehaviour
{
    public float CD = 0.5f;

    private void OnEnable()
    {
        CDMgr.Instance.AddCD(GlobalParameter.CDType.Laser, CD);
    }
    
    private void OnDisable()
    {
        CDMgr.Instance.RemoveCD(GlobalParameter.CDType.Laser);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (CDMgr.Instance.IsReady(GlobalParameter.CDType.Laser))
        {
            //技能
        }
    }
}