如何不绑定脚本且不继承MonoBehaviour做U3D的开发

    要点:我们把脚本绑在对象上为什么不把对象抓到脚本里殴打呢?

    问题:那不继承Mono的话,协同以及实例化,以及每帧运算该怎么去做呢?

    最近看到一个做技能冷却的话题,所以也想去尝试一下。

    1.这是界面2D和3D摄像机

    2.这是对象排布

    3.代码

    (1)主要负责UI的界面

    [mw_shl_code=csharp,true]using Assets.Classes.com.system;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using UnityEngine;

    namespace Assets.Classes.com.view.ui
    {
    enum SKILLTYPE
    {
    Q_SKILL = 10,//→_→代表该技能的冷却时间
    W_SKILL = 20,
    E_SKILL = 30,
    R_SKILL = 100
    }

    class SkillsMenu_UI
    {
    private SKILLTYPE skillType;//技能类型
    private bool isSkill = false;//是否正在释放技能
    private bool isCooling = false;//是否正在冷却
    private float coolingTime;//冷却时间
    private GameObject currentObj;

    public SkillsMenu_UI(GameObject skillsObj)
    {
    //    GameObject go = (GameObject)GameObject.Instantiate(skillsObj);
    //   new PanelHandler().RootHandler(skillsObj);
    HandlerListener("Q_Skill", skillsObj);
    HandlerListener("W_Skill", skillsObj);
    HandlerListener("E_Skill", skillsObj);
    HandlerListener("R_Skill", skillsObj);
    }

    private void HandlerListener(string skillName, GameObject go)
    {
    Transform Skill = go.transform.FindChild(skillName);
    UIEventListener.Get(Skill.gameObject).onClick = OnClick;
    }

    private void OnClick(GameObject go)
    {
    Debug.Log("点击了技能按钮 : " + go.name);
    switch (go.name)
    {
    case "Q_Skill": skillType = SKILLTYPE.Q_SKILL; HandlerSkill(skillType, go); break;
    case "W_Skill": skillType = SKILLTYPE.W_SKILL; HandlerSkill(skillType, go); break;
    case "E_Skill": skillType = SKILLTYPE.E_SKILL; HandlerSkill(skillType, go); break;
    case "R_Skill": skillType = SKILLTYPE.R_SKILL; HandlerSkill(skillType, go); break;
    }
    }

    private void HandlerSkill(SKILLTYPE type, GameObject go)
    {
    if (!isCooling || !isSkill)//是否冷却或者是否有技能没有释放
    {
    currentObj = go;
    skillType = type;
    isSkill = true;
    isCooling = true;
    HandlerCoolingTimer(type);
    Debug.Log("可以释放该技能了");
    }
    else
    {
    Debug.Log("不可释放技能");
    }
    }

    private void HandlerCoolingTimer(SKILLTYPE type)
    {
    coolingTime = (float)type;
    currentObj.transform.FindChild("Fore").gameObject.GetComponent<UISprite>().fillAmount = 1;
    GameController.getInstance().addInterval(TimerCutting);
    Debug.Log("开始倒计时");
    }

    private void TimerCutting(float t)
    {
    currentObj.transform.FindChild("Fore").gameObject.GetComponent<UISprite>().fillAmount -= (1.0f / coolingTime) * Time.deltaTime;
    float tempTime = currentObj.transform.FindChild("Fore").gameObject.GetComponent<UISprite>().fillAmount;
    Debug.Log("------------coolingTime : " + tempTime);
    if (tempTime <= 0.01f)
    {
    isSkill = false;
    isCooling = false;
    GameController.getInstance().removedInterval(TimerCutting);
    }
    }
    }
    }[/mw_shl_code]

    设计思想:外界需要处理这个界面的时候,只需要声明对象new 这个类的有参构造函数即可,然后默认进行一系列初始化动作。

     

    这个是替代自带的OnClick()事件,采用事件事件监听机制。

    其他略。

    (2)

    如果我需要每帧去计算的要求我该怎么办?

    那就写一个可以控制全局的每帧运算。

          

    [mw_shl_code=csharp,true]  /*
             * 游戏主循环 
             */
           private static GameController m_instance;

            List<Action<float>> intervalCallFuns;

            public void mainLoop()
            {
                interval(Time.deltaTime);
            }

            public void interval(float t)
            {
                List<Action<float>> tempIntervalCallFuns = intervalCallFuns;
                foreach (Action<float> intervalCallFun in tempIntervalCallFuns)
                {
                    intervalCallFun(t);
                }
                tempIntervalCallFuns = null;
            }
            /*
             *  添加每帧回调
             *        @param:需要回调的函数
             */
            public void addInterval(Action<float> callFun)
            {
                if (!intervalCallFuns.Equals(callFun))
                {
                    intervalCallFuns.Add(callFun);
                } else
                {
                    Debug.LogWarning("add interval already exists!");
                }
            }
            /*
             *  移除每帧回调函数
             *        @param:需要移除的回调函数
             */
            public void removedInterval(Action<float> callFun)
            {
                List<Action<float>> tempIntervalCallFuns = new List<Action<float>>();
                foreach (Action<float> tempFun in intervalCallFuns)
                {
                    if (tempFun != callFun) tempIntervalCallFuns.Add(tempFun);
                }
                intervalCallFuns = tempIntervalCallFuns;
                tempIntervalCallFuns = null;
            }[/mw_shl_code]

    设计思想:这个类用字典去存储需要进行每帧运算的函数,然后默认去每帧遍历,并带有从字典中移除函数的功能。

    (3)启动程序,启动游戏主循环。

    Main类挂在一个GameObject上,负责游戏启动,只负责游戏的主循环,不管其他的操作。

    [mw_shl_code=csharp,true]using UnityEngine;

    public class Main : MonoBehaviour
    {
    void Start()
    {

    }

    void Update()
    {
    GameController.getInstance().mainLoop();
    }
    }[/mw_shl_code]

    test.cs在他需要的时候去new SkillsMenu_UI(Skills对象)。

    new SkillsMenu_UI(gameObject.transform.FindChild("Skills").gameObject);

    整个程序就可完美启动起来。

     

    总结,这样的设计多用于解耦和模块的划分。

    不用频繁绑定脚本,给public对象绑定对象,一些都在代码中完成。
    转载请注明出处。

    作者: 大帅纷纭

    微博:http://weibo.com/2357191704/profile?topnav=1&wvr=6

    博客:http://blog.csdn.net/dashuaifenyun1991

    邮箱:bandit_empire@163.com

    有帮助就分享一下吧!

    转载请注明:少狼 – 敬畏知识的顽皮狗 » 如何不绑定脚本且不继承MonoBehaviour做U3D的开发

    喜欢 0

*

还没有人抢沙发呢~