作者:大帅纷纭
泰斗原文链接:http://www.taidous.com/forum.php?mod=viewthread&tid=33049
要点:我们把脚本绑在对象上为什么不把对象抓到脚本里殴打呢?
问题:那不继承Mono的话,协同以及实例化,以及每帧运算该怎么去做呢?
最近看到一个做技能冷却的话题,所以也想去尝试一下。
1.这是界面2D和3D摄像机
2.这是对象排布
3.代码
(1)主要负责UI的界面
[AppleScript] 纯文本查看 复制代码
<font style="color:rgb(51, 51, 51)">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); } } } }</font>
设计思想:外界需要处理这个界面的时候,只需要声明对象new 这个类的有参构造函数即可,然后默认进行一系列初始化动作。
这个是替代自带的OnClick()事件,采用事件事件监听机制。
其他略。
(2)
如果我需要每帧去计算的要求我该怎么办?
那就写一个可以控制全局的每帧运算。
/*[/color][/p] * 游戏主循环 */ 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; }
设计思想:这个类用字典去存储需要进行每帧运算的函数,然后默认去每帧遍历,并带有从字典中移除函数的功能。
(3)启动程序,启动游戏主循环。
Main类挂在一个GameObject上,负责游戏启动,只负责游戏的主循环,不管其他的操作。
<font style="color:rgb(51, 51, 51)">using UnityEngine; public class Main : MonoBehaviour { void Start() { } void Update() { GameController.getInstance().mainLoop(); } }</font>
test.cs在他需要的时候去new SkillsMenu_UI(Skills对象)。
new SkillsMenu_UI(gameObject.transform.FindChild("Skills").gameObject);
整个程序就可完美启动起来。
总结,这样的设计多用于解耦和模块的划分。
不用频繁绑定脚本,给public对象绑定对象,一些都在代码中完成。
转载请注明出处。