自我感觉把,前几篇写的一些简单东西,并不能够很好的涉及到开发中各种控件的配合,想着接下来用实例的方式自己边学边做,这样我对NGUI的使用才会更熟练并且也有更多的东西与大家讨论。
所以接下来的文章我想开始我的实例操练——游戏菜单以及菜单的切换;
一、游戏UI的初步设计
在实现UI前,先设计一下UI的快速原型吧。(用Visio做的圆形,因为只需作为参考就不用AxureRP来做了)
设置的界面
比较简单不要介意哈,只要功能实现都是贴图的事,不慌,问题不大!!
二、开始实现
好了,这是我根据快速原型先整出来的界面 ,接下来给每个空间添加对应的功能;
1.首先,给sprite都attach一个BoxCollider(注意哦,lable可加可不加,但是按照这个设计是不用加的,因为如果加了,鼠标有时点到的BoxCollider是Label,就可能会妨碍Sprite之后添加的ButtonScript脚本的功能),然后右键sprite控件然后Attach一个ButtonScript脚本,就大功告成。如下图:(是StartButton添加的脚本)
两个PlaySound的脚本就很容易了,两个的Trigger各不同,一个是On Mouse Over,就是鼠标经过按钮时的声音;OnClick就是鼠标点击时的声音;这里用了我这个版本NGUI内置的声音;
2.好了,把能交互的设置好了,就该实现交互的内容了,从"开始游戏出发";
开始游戏在这里的设计效果是这样的:点击“开始游戏”,然后有一个加载的界面,之后就是游戏场景(比较简单)
那如何响应点击产生的这个事件呢?在“ButtonScript”脚本中有一个“On Click”下,有一个Notify,后面可以拖拽进去一个游戏物体,拖进去后会展开,然后选择该游戏物体上的某个脚本的事件就行;
在这里我们把场景切换的脚本挂在MainCamera
public class startGame : MonoBehaviour {
[HideInInspector]
public AsyncOperation asyncLoad;
public TweenPosition MenuUITween;
public TweenPosition LoadUITween;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
IEnumerator loadScene()
{
asyncLoad= SceneManager.LoadSceneAsync(1,LoadSceneMode.Single);
yield return asyncLoad;
}
public void EnterGame()
{
StartCoroutine(loadScene());
MenuUITween.PlayForward();//播放主菜单界面移除动画
LoadUITween.PlayForward();//加载界面的出现动画
}
}
这是我在加载场景时的过渡
在菜单到游戏场景的切换,我们可以用协同程序来进行,Unity的UnityEngine.SceneManagement这个命名空间中,提供了一个加载场景并可以得到加载进度的API,就是
public static AsyncOperation LoadSceneAsync(string sceneName,SceneManagement.LoadSceneMode mode = LoadSceneMode.Single);
public static AsyncOperation
LoadSceneAsync(int
sceneBuildIndex, SceneManagement.LoadSceneMode
mode = LoadSceneMode.Single);
有两个重载,区别在于第一个参数,这个参数指定对应场景,第一个是场景的名字,第二个是场景的索引,那么问题来了,索引是从何而来?
我们需要把所需要的场景放进这里面:(在File->buildSettings或者快捷键ctrl+shift+B),场景后面对应的数字就是索引了;
接着讲场景加载的API,返回的 AsyncOperation变量中有好几个属性,具体可以查看Unity官方API文档
progress是一个从0到1的float数据,完全可以用进度条给显示出来,所以我们再添加一个进度条的UI,如图所示
Progress脚本的代码如下
public class progress : MonoBehaviour {
UISlider slider;
public startGame sg;//定义一个startgame实例,在Inspector中把挂在这个脚本的物体放进去;这样做比较减少性能消耗
// Use this for initialization
void Start () {
slider = this.GetComponent();
}
// Update is called once per frame
void Update () {
if (slider != null && sg != null && sg.asyncLoad != null)//安全性检查,防止空指针
{
slider.value = sg.asyncLoad.progress;//
print(slider.value);
}
}
}
大致的代码都完成,简单解释一下,关键代码就是那个协同程序的几段代码,把EnterGame()函数挂载到主开始游戏按钮的点击事件上如图:
其中有两个函数调用没说到,就是
MenuUITween.PlayForward();//播放主菜单界面移除动画
LoadUITween.PlayForward();//加载界面的出现动画
这是我挂在MenuUI和LoadingUI的两个动画脚本 ,动画要怎么切换就根据大家的需要,我做的效果是直接切换,而且注意这个脚本是没有勾上的,因为我们一开始并不希望他们就起作用,需要我们点击开始游戏才发挥作用,所以用PlayForward()方法就可以让他起作用了。
效果展示:
开始运行
接着点击开始游戏
场景加载中
场景
上面那个Button是我为了方便弄的返回菜单的功能,实现和切换场景的方法大同小异;
接下来完场设置界面的显示以及参数调整;
下图是我根据原型再次优化的界面效果