还记得童年的超级玛丽吗?怀揣着打败恶龙,就出公主的向往打开小霸王,开始一局闯关真的是乐趣无穷。偶尔也玩到了恶搞的同款游戏,以真正的大冒险为主比较出名,游戏逻辑不按常理出牌,顿时就想写出一个自己玩一下,素材相信大家在网上都找得到。我这里主要给喜欢的小伙伴或者是对u3d感兴趣的新人,要求有一定的U3D基础。
主要做出四个UI界面分别为UIStart,UIOption,UILevel1,UILose四个主要界面,后面的关卡有兴趣的朋友应该按讲解的思路做出来不是问题。
写代码前不要急,要先好好想一想都需要什么逻辑,哪些功能,理顺了才能做到下指如有神!
先来看看已经做好的UI界面:
大家可以看一下,这就是主要四个UI的游戏过程,这里将不讲解UI界面的搭建,但是主要我们讲讲游戏的编程逻辑与游戏功能的实现。
正式开始之前我们来看一下我已经做好的脚本文件是怎么划分的。
大家在这里应该能明白并且了解都需要哪些模块或者脚本了吧。下面我们开始进入脚本讲解每个脚本都需要负责的功能。
Root:做为跟脚本,负责启动游戏的开始界面与音乐播放器的音乐控制。
void Start () {
Application.runInBackground = true;
UIManager.Instance.Load("Start");
AudioManager.Instance.PlayBGM("bgm1");
}
AudioManager:功能主要负责控制游戏音乐或音效的播放,音乐添加采用动态加载Resource方法
public static AudioManager Instance;
private AudioSource aud;
private bool mute;//默认值静音
void Awake()
{
Instance = this;
}
private void Start()
{
aud = GetComponent<AudioSource>();
aud.loop = true;
}
public bool Mute
{
set
{
aud.mute = value;
}
}
public void PlayBGM(string bgm)
{
//播放BGM
aud.clip = Resources.Load<AudioClip>("Audio/"+ bgm );// "Audio/"+音乐名字
aud.Play();
}
UIManager:这里稍微复杂一些,主要实现功能是用字典预加载UI界面,把UI当做预制体直接加载,然后用栈保存已经实例化过的UI界面,最后我们还需要一个字典来存放已经实例过的UIBaseScript脚本,避免重复加载场景
//游戏控制采用单例模式
public static UIManager Instance;
//预加载UI预设体,保存到字典集合中
Dictionary<string, GameObject> uiAssentDic;
//保存已经实例化过的UI界面
Stack<UIBaseScript> uiStack;
//用来保存实例过的UIBaseScript脚本,避免多次实例化
Dictionary<string, UIBaseScript> uiBaseDic;
void Awake()
{
Instance = this;
uiAssentDic = new Dictionary<string, GameObject>();
uiStack = new Stack<UIBaseScript>();
uiBaseDic = new Dictionary<string, UIBaseScript>();
InitUI();
}
//直接把Resource中的预制体导入字典中
void InitUI()
{
uiAssentDic.Add("Start",Resources.Load<GameObject>("UIPanel/Start"));
uiAssentDic.Add("Option", Resources.Load<GameObject>("UIPanel/Option"));
uiAssentDic.Add("Level1", Resources.Load<GameObject>("UIPanel/Level1"));
uiAssentDic.Add("UILose", Resources.Load<GameObject>("UIPanel/UILose"));
}
//入栈
private void PushUI(string name)
{
//1.先取出旧的栈顶
if(uiStack.Count>0)
{
UIBaseScript oldTop = uiStack.Peek();
oldTop.Pause();
}
//实例化或者加载已经缓存过的UI界面(空间换时间)
UIBaseScript uibs = GetBase(name);
//UI入栈要执行Enter方法(初始化一些界面数据……)
uibs.Enter();
//uiPanel加到栈中保存
uiStack.Push(uibs);
}
//出栈
private void PopUI()
{
//判断栈内有没有UI
if(uiStack.Count <= 1 )
{
return;
}
//如果有UI 取出旧的栈顶退出
UIBaseScript oldTop = uiStack.Pop();
oldTop.Exit();
//取出新的栈顶
UIBaseScript newTop = uiStack.Peek();
newTop.Resume();
}
UIBaseScript GetBase(string name)
{
//遍历字典,查找之前有没有保存过当前UI的UIBase脚本
foreach(string key in uiBaseDic.Keys)
{
if(key.Equals(name))
{
return uiBaseDic[name];
}
}
//实例化
GameObject go = uiAssentDic[name];
if (go == null)
{
Debug.Log(name + "UI还没做完");
return null;
}
GameObject uiPanel = Instantiate(go);
//获取到实例化的UI上的UIBase脚本
UIBaseScript uibs = uiPanel.GetComponent<UIBaseScript>();//.Enter();
uiBaseDic.Add(name,uibs);
return uibs;
}
//加载指定的UI界面
public void Load(string name)
{
PushUI(name);
}
//退出当前UI界面
public void Pop()
{
PopUI();
}
下一篇讲讲解UI界面设置与英雄在场景中的触发机制