通过委托与事件监听状态改变来更新UI
来源:互联网 发布:闪电地震流数据 编辑:程序博客网 时间:2024/05/21 02:19
该博文涵盖的知识点
1. C# 委托
2. 如何利用委托监听事件以此更新显示
所要完成目标
我们刚开始做好的部分UI界面如下图所示:
观察左边的红色方框,我们先做了实例的姓名,头像,slider,和Label等,在运行游戏时候需要更新相应的属性。
在下面的脚本中,我们分别更新:左边方框中的nameLabel(黄晓明),energyLabel(50/100),toughenLabel(32/50)以及levelLabel(89);和右边的两个Label(12345678和12345678)。如何更新呢?我们借助委托注册事件来监听属性的改变,下面不再做解释,脚本中注释说明了一切!!!!
脚本、Unity相关设置
这里只使用三个脚本来学习如何使用委托来注册事件,以此监听属性的变化。如上图所示,PlayerBar脚本绑定在player-bar上,PlayerInfo脚本绑定在GameObject(空的游戏物体,作为控制)上,TopBar脚本绑定在top-bar上,分别在这些脚本中获取Unity Hierarchy中的相关属性,然后进行更新。下面分别是三个脚本:PlayerInfo,PlayerBar以及TopBar
using UnityEngine;using System.Collections;public enum InfoType{Name,HeadPortrait,Level,Power,Exp,Diamond,Coin,Energy,Toughen,All}public class PlayerInfo : MonoBehaviour {// 创建该类 为单例模式、public static PlayerInfo _instance;#region propertyprivate string _name;private string _headPortrait;private int _level = 1;private int _power = 1;private int _exp = 0;private int _diamond;private int _coin;private int _energy;private int _toughen;#endregion// 体力和历练的计时器;一分钟体力加1private float energyTimer = 0;private float toughenTimer = 0;// ----------------- 委托 -----------------------------------public delegate void OnPlayerInfoChangedEvent(InfoType type);// 利用委托定义事件,通过事件监听属性的更改public event OnPlayerInfoChangedEvent OnPlayerInfoChanged;#region get set methodpublic string Name{get{ return _name; }set{ _name = value; }}public string HeadPortrait{get { return _headPortrait; }set { _headPortrait = value; }}public int Level{get { return _level; }set { _level = value; }}public int Power{get { return _power; }set { _power = value; }}public int Exp{get { return _exp; }set { _exp = value; }}public int Diamond{get { return _diamond; }set { _diamond = value; }}public int Coin{get { return _coin; }set { _coin = value; }}public int Energy{get { return _energy; }set { _energy = value; }}public int Toughen{get { return _toughen; }set { _toughen = value; }}#endregionvoid Start(){Init ();// 初始化}void Awake(){_instance = this;}void Update(){// ------------- 实现体力和历练的自由增长 ---------------------------- // 每一分钟体力和历练增长1,其中体力总数为100,历练总是为50// 实现体力的自动增长if (this.Energy < 100) {energyTimer += Time.deltaTime;if (energyTimer > 60) {Energy += 1;energyTimer -= 60;OnPlayerInfoChanged (InfoType.Energy);}} else {energyTimer = 0;}// 实现历练的自由增长if (this.Toughen < 50) {toughenTimer += Time.deltaTime;if (toughenTimer > 60) {Toughen += 1;toughenTimer -= 60;OnPlayerInfoChanged (InfoType.Toughen);}} else {toughenTimer = 0;}// ------------- ----------------------- ---------------------------- }// 初始化属性void Init(){this.Coin = 9870;this.Diamond = 1234;this.Energy = 78;this.Exp = 123;this.HeadPortrait = "头像底板女性";this.Level = 12;this.Name = "千颂伊";this.Power = 1745;this.Toughen = 34;OnPlayerInfoChanged (InfoType.All);}}
using UnityEngine;using System.Collections;/**2016-5-13 By BigoSprite * 设置PlayerBar脚本的执行顺序次于PlayerInfo脚本 * 步骤如下: * Edit>Project Settings>Script Execution Order * 注意:值小的,先执行*/public class PlayerBar : MonoBehaviour {// 该脚本用于更新左上角这一区域的属性private UISprite headSprite;private UILabel nameLabel;private UILabel energyLabel;private UISlider energySlider;private UILabel levelLabel;private UILabel toughenLabel;private UISlider toughenSlider;private UIButton energyPlusButton;private UIButton toughenPlusButton;void Awake(){headSprite = transform.Find ("head-sprite").GetComponent<UISprite> ();nameLabel = transform.Find ("name-label").GetComponent<UILabel> ();energyLabel = transform.Find("energy-progressBar/Label").GetComponent<UILabel> ();energySlider = transform.Find ("energy-progressBar").GetComponent<UISlider> ();levelLabel = transform.Find ("level-label").GetComponent<UILabel> ();toughenLabel = transform.Find ("toughen-progressBar/Label").GetComponent<UILabel> ();toughenSlider = transform.Find ("toughen-progressBar").GetComponent<UISlider> ();energyPlusButton = transform.Find ("energyPlusButton").GetComponent<UIButton> ();toughenPlusButton = transform.Find ("toughenPlusButton").GetComponent<UIButton> ();energyPlusButton = transform.Find ("energyPlusButton").GetComponent<UIButton> ();toughenPlusButton = transform.Find("toughenPlusButton").GetComponent<UIButton> ();// 使用单例模式前,要保证先初始化。因为我们设置PlayerInfo脚本先执行,后执行PlayerBar脚本// 而已经在PlayerInfo脚本中的Awake方法中初始化了,因此可保证_instance肯定存在。// ------- 注册PlayerInfo中的委托事件(+=), PlayerInfo是单例模式,公有的类,所以 ----------PlayerInfo._instance.OnPlayerInfoChanged += this.OnPlayerInfoChanged;}// 注销事件 -=void OnDestory(){PlayerInfo._instance.OnPlayerInfoChanged -= this.OnPlayerInfoChanged;}// 当我们的主角信息发生改变的时候,会触发这个方法void OnPlayerInfoChanged(InfoType type){// 首先判断角色的哪部分信息改变了// 注意这个脚本(PlayerBar)绑定在PlayerBar身上,即左上角的区域if(type == InfoType.All ||type == InfoType.Name || type == InfoType.Level || type == InfoType.Energy || type == InfoType.Toughen){UpdateShow();// 更新信息的显示}}// 更新显示// 如何更新信息的显示?怎么确定具体哪一个信息改变了???// 这里管他具体哪个改变了,全部给他更新,哈哈!!!void UpdateShow(){PlayerInfo info = PlayerInfo._instance;// 初始化一个对象headSprite.spriteName = info.HeadPortrait;// 头像levelLabel.text = info.Level.ToString();nameLabel.text = info.Name;// 注意: 这里需要除以100f和50f,得到浮点型;如果除以100和50,slider不会显示!energySlider.value = info.Energy / 100f;// energy SliderenergyLabel.text = info.Energy.ToString () + "/100";toughenSlider.value = info.Toughen / 50f;// toughen SlidertoughenLabel.text = info.Toughen.ToString()+"/50";}}
using UnityEngine;using System.Collections;public class TopBar : MonoBehaviour {private UILabel coinLabel;private UILabel diamondLabel;private UIButton coinPlusButton;private UIButton diamondPlusButton;void Awake(){coinLabel = transform.Find ("coin-bg/Label").GetComponent<UILabel> ();diamondLabel = transform.Find ("diamond-bg/Label").GetComponent<UILabel> ();coinPlusButton = transform.Find ("coin-bg/coinPlusButton").GetComponent<UIButton> ();diamondPlusButton = transform.Find ("diamond-bg/diamondPlusButton").GetComponent<UIButton> ();// 1. 注册事件,同样是在设置脚本执行次序的前提下// 加入未设置执行次序,PlayerInfo不先于TopBar执行,会报错:说// Object reference not set to an instance of an object.// 即PlayerInfo脚本中的_instance = this;次于TopBar脚本执行,TopBar脚本使用实例,但实例还未初始化呢?所以需要指定次序。PlayerInfo._instance.OnPlayerInfoChanged += this.OnPlayerInfoChanged;}// 注销事件void OnDestory(){PlayerInfo._instance.OnPlayerInfoChanged -= this.OnPlayerInfoChanged;}// ---------------------------------------------------------------------// 1. 注册和注销事件// 2. 更新显示// 注意:更改脚本执行顺序,PlayerInfo先于TopBar执行void OnPlayerInfoChanged(InfoType type){if(type == InfoType.All || type == InfoType.Coin || type == InfoType.Diamond){UpdateShow ();}}void UpdateShow(){PlayerInfo info = PlayerInfo._instance;coinLabel.text = info.Coin.ToString ();diamondLabel.text = info.Diamond.ToString ();}}其中,设置脚本执行次序如下图所示:
运行Unity,效果如下图所示:
注:本博文参考SIKI老师的《泰斗破坏神》,用于学习
0 0
- 通过委托与事件监听状态改变来更新UI
- EventHandle事件委托(通过状态发生改变时判断)
- ngRoute路由改变监听事件(1)+ui.router状态路由
- javascript事件监听与事件委托
- Android监听软键盘显示与隐藏状态来动态改变布局
- 通过window.attachEvent来监听事件
- js---JavaScript中的事件委托/事件代理,如何通过事件委托进行异步DOM事件监听
- Android GPS状态改变与监听
- 线程更新UI (线程与委托)
- JS 中的事件绑定、事件监听与事件委托
- Android 通过广播来异步更新UI
- 通过ImageView的点击监听事件来滑动ScrollView的滚动条,进而改变屏幕显示内容
- android之通过phoneStateListener监听电话状态改变
- android之通过phoneStateListener监听电话状态改变
- android之通过phoneStateListener监听电话状态改变
- android之通过phoneStateListener监听电话状态改变
- Android 通过广播监听USB连接状态的改变
- 【JQuery】用JQuery来监听浏览器改变窗口大小事件
- 编程上的那点事情儿
- phonegap cordova 环境搭建及安装
- Codeforces Round #347 (Div. 2) B. Rebus
- STM32_RTC闹钟
- linux常用命令笔记
- 通过委托与事件监听状态改变来更新UI
- Java泛型 泛型的上下限
- Block全面分析
- java jdbc编程,运行总显示不允许链接
- new TextView
- Java设计模式之策略设计模式
- git的学习笔记(与小伙伴协作)
- 使用uc/os中遇到的一个有关OSMboxPend()的一个问题
- java-web易错汇总