Unity3D-VR《静夜诗》3-开始按钮与开始文本信息
凝视确认了开始按钮后,开始信息文本对象是和开始按钮对象将会一起消失的,应该把这样的可视对象都放到有个容器对象(父对象)中,在程序中只要设置容器对象消失了,其子对象也就一起消失了。
1.开始按钮及开始信息文本UI对象的设计
为实现开始文本显示及开始按钮凝视触发功能,在场景中设计UI对象如下:
1.1容器对象PanelBeginUI
通过Create | UI | Panel 添加容器对象,并命名PanelBeginUI,设置属性如上图。位置大小根据需要设定,这里给的仅是参考,设置旋转使得对象的Z方向朝前,否则文字会反方向显示的,背景图片在资源目录下有的。
1.2开始信息文本TextBegin
通过Create | UI | Text 添加文本对象,并命名TextBegin,设置属性如下。
1.3开始按钮BtnBegin
通过Create | UI | Button 添加按钮对象,并命名BtnBegin,设置属性如下。
因为按钮对象要凝视交互的,所以要为按钮对象添加盒子碰撞器,其大小能包住按钮对象即可,按钮对象的Image属相设置的图片在提供的资源目录中有的。
按钮对象下还有一个子对象Text,把它的默认显示文本改为“开始”。
接下来我们事先开始按钮的交互凝视功能。
2.开始按钮实现凝视触发
如果你已经理解前面宝剑交互对象的凝视转圈事件触发的代码,就可以类似的编写开始按钮事件触发的脚本了。参考ReticleTrigger_for_DispayTextTip脚本,新建脚本ReticleTrigger_for_ButtonStartPlay.cs,参考代码如下:
public class ReticleTrigger_for_ButtonStartPlay : MonoBehaviour {
private VRReticleTriggerItem vrReticleTriggerItem;//处理准星精度条触发的类变量
private void Awake ()
{ //要保证对象也有VRReticleTriggerItem脚本
vrReticleTriggerItem = GetComponent<VRReticleTriggerItem> () ?? gameObject.AddComponent<VRReticleTriggerItem>() ;
}
//对象使能(激活)时调用
private void OnEnable()
{ //订阅事件
vrReticleTriggerItem.OnTrigger += HandleTrigger;
}
//对象不使能(不激活)时调用
private void OnDisable()
{ //去掉订阅的事件,与OnEnable的语句对应
vrReticleTriggerItem.OnTrigger -= HandleTrigger;
}
//准星凝视进度条满了后,要触发的事件代码
void HandleTrigger ()
{ //设置当前对象父对象不活动(不可见,不可交互)
this.transform.parent.gameObject.SetActive(false);
Debug.Log("你触发了开始按钮");//后续程序逻辑可在这里继续编码
}
}
把脚本ReticleTrigger_for_ButtonStartPlay挂在开始按钮BtnBegin对象上,试着运行。
测试:
准星凝视在按钮上,出现转圈进度条,凝视触发后,开始信息文本及按钮对象不见了,控制台提示“你触发了开始按钮”。
问题
仔细观测项目的实现要求,发现准心凝视开始按钮时,按钮的背景会变成另一种颜色,根据提供的资源,在资源目录下还有一个图片文件btn_Long-button.png是作为开始按钮刚凝视时显示用的图片,一旦凝视中止开始按钮的背景恢复为原来的图片即btn_black-button.png。这又如何实现呢?
实现思路
记得VRReticleTriggerItem脚本吗?目前它只提供OnTrigger事件供使用者订阅,为了实现凝视时的背景图片切换,我们希望VRReticleTriggerItem提供OnOVer、OnOut事件的订阅,以便在ReticleTrigger_for_ButtonStartPlay脚本中能捕捉到凝视移入移出的事件。修改后的VRReticleTriggerItem脚本参考如下:
public class VRReticleTriggerItem : MonoBehaviour {
//添加可订阅的事件变量
public event Action OnOver;//凝视移入
public event Action OnOut;//凝视移出
//准星凝视移入对象上时调用
private void HandleOver()
{
if (OnOver!=null)
OnOver();
}
//准星凝视移出对象时调用
private void HandleOut()
{
isTrigger = false;
timer = 0;
imageProgressBar.fillAmount = 0f;//进度条填充置0
if (OnOut!=null)
OnOut();
}
}
这样VRReticleTriggerItem脚本具有订阅OnOver、OnOut事件的功能了,继续编辑ReticleTrigger_for_ButtonStartPlay脚本。完成后的参考代码如下(留意代码中的注释):
public class ReticleTrigger_for_ButtonStartPlay : MonoBehaviour {
private Sprite normalImage;//原来的精灵图片
public Sprite overImage;//准星经过时精灵图片
private VRReticleTriggerItem vrReticleTriggerItem;//处理准星精度条触发的类变量
private void Awake ()
{ //要保证对象也有VRReticleTriggerItem脚本
vrReticleTriggerItem = GetComponent<VRReticleTriggerItem> () ?? gameObject.AddComponent<VRReticleTriggerItem>() ;
normalImage = GetComponent<Image> ().sprite;//保存原来的精灵图片
}
//对象使能(激活)时调用
private void OnEnable()
{
//订阅事件
vrReticleTriggerItem.OnTrigger += HandleTrigger;
vrReticleTriggerItem.OnOver += HandleOver;
vrReticleTriggerItem.OnOut += HandleOut;
}
//对象不使能(不激活)时调用
private void OnDisable()
{ //去掉订阅的事件
vrReticleTriggerItem.OnTrigger -= HandleTrigger;
vrReticleTriggerItem.OnOver -= HandleOver;
vrReticleTriggerItem.OnOut -= HandleOut;
}
//准星移出对象时调用
void HandleOut ()
{
this.gameObject.GetComponent<Image> ().sprite = normalImage;
}
//准星在对象上时调用
void HandleOver ()
{
this.gameObject.GetComponent<Image> ().sprite = overImage;
}
//准星凝视进度条满了后,要触发的事件代码
void HandleTrigger ()
{ //设置当前对象父对象不活动(不可见,不可交互)
this.transform.parent.gameObject.SetActive(false);
Debug.Log("你触发了开始按钮");
}
}
保存代码后在开始按钮BtnBegin的属性面板中设置变量overImage对应的图片值。
测试:
- 凝视在开始按钮时,出现凝视转圈,背景图片也切换了
- 凝视移出按钮后转圈进度条消失,背景图片也恢复为原来的图片
- 凝视转圈完成触发后,开始信息文本和按钮消失了。
提示
请同学们掌握访问父对象的方法,比如像这样调用父对象的函数SetActive(),说明如下:
this.transform // 获取当前对象的Transform组件,返回的是Transform类型。
this.transform.parent //获取当前对象的Transform组件的父组件,返回的也是Transform类型。
this.transform.parent.gameObject //获取父组件所在的游戏对象,返回的是GameObject类型。
this.transform.parent.gameObject.SetActive(false) //设置父对象不活动。
思考:
- 如果凝视在开始按钮,按钮变大些,凝视移出恢复原来大小,如何实现呢?
- 凝视在开始按钮时,不用默认的转圈进度条,用按钮背景作为水平进度条,又如何实现呢?