您的位置:首页 > 其它

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

2015-01-27 19:15 381 查看
要点:我们把脚本绑在对象上为什么不把对象抓到脚本里殴打呢?

问题:那不继承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;

       
101b8
    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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 3d
相关文章推荐