Unity游戏开发UI框架(1)
最近有点累了,所以写⼀些⽂章放松⼀下。
简单说⼀下我的⼀些不成熟的关于学习游戏开发的想法吧。这个框架是来⾃某培训机构的⼀位姓朱的⽼师教给我的,如果是我同期的U3D开发的同学⼤概就知道我说的是谁了,再此⾮常感谢⽼朱!
说⼀下⾃⼰的学习曲折道路吧,希望不要和我⼀样⾛弯路。在新⼿阶段,也就是说没有真正的在商业项⽬中磨炼不到⼀两年的,不要去造轮⼦!能看懂,能⽤,并且会⽤是最重要的!程序员,没有⼀定的代码积累是很难达到随⼼所欲的⾏云流⽔的⼀般的写出⾼质量的代码的。等有了⼀定的积累,然后再去修改⼀部分开源插件的功能,甚⾄说重新提炼出属于⾃⼰的写代码思路和架构。
⼊⾏游戏开发的程序员经常犯的⼀个错误就是在深度不⾜的时候,就去拓展⼴度。这其实严格意义上来说,是⾮常⾮常不好的⼀种学习⽅法。程序员的学习,⼀定是深度优先。达到了⼀定的深度,再去学习相关的东西,那么提升的⾮常快,⾼效!否则的,三步⼀坑五步⼀坎⼉。
注意:当熟悉了C#语⾔,⼀定要长期坚持练习数据结构和算法⼀定要长期坚持练习数据结构和算法⼀定要长期坚持练习数据结构和算法!!!!(三遍了!)
前期的学习:C#基本语法最重要的,是⾯向对象这⼀⽅⾯的学习,这是游戏开发的核⼼部分。接⼝、类
、委托,前期写多少代码都是不够的!必须⼀直写,⼀直练!然后可以看看C#的语法糖,有惊喜~接着就开始研究Unity的⼀些常⽤的组件:碰撞器、寻路组件、Animation、UGUI等等,其中各种教学视频数不胜数。这⾥不多说了,然后开始研究Unity常⽤的API。这⾥可能会需要⼀定的基础的关于⾼数、物理相关知识,但是仅仅是基础⽽已。
这些组件基本了解⼀遍了,开始⾃⼰写Demo。不要管框架不要管任何东西,先写⼀个Demo,只要能实现你想要的游戏功能就可以接下来,对于急于⼯作的⼩伙伴来说,就要深⼊研究UGUI或者NGUI是重点的!百分之九⼗九的新⼿程序刚⼊⼯作都是在处理UI⽅⾯的事情。什么叫做深⼊了解,就是同⼀个UI的功能,考虑实现他的功能的时候,需要考虑它的效率问题。(⽼⽣常谈的NGUI的WrapContent,不知道的⾃⼰百度⼀下他的实现原理。)甚⾄,ScrollView滑动的的时候,⼀般来说他的item是直线的,怎么让他弧形滑动,按照预定的曲线⽅向滑动等等。怎么提⾼他的效率,都需要⾃⼰去重写⼀部分逻辑和功能才能实现。(当然有这种插件)
这⼀部分⾯试:会问各种奇葩的东西,没办法只能扫题了。注意:算法和数据结构⼀定会有算法笔试题的!尤其是⼤⼚的⾯试,算法和数据结构是核⼼,其他的Untiy之类的反⽽不会问。
前端开发什么组件不学:shader相关的都不学习!材质球知道,会⽤即可!粒⼦系统不学!说⽩了美术向的组件,都可以不学!很简单,时间精⼒有限!这些玩意对于 **新⼿** 前端程序来说,没什么⽤处!但是,Animation和Animator相关的代码API得会⽤Unity编辑器相关的代码,不看!
另外:提⼀下NGUI和UGUI到底学习哪⼀个,我的回答是都⾏!现在⼤部分游戏公司都在换⽪,很多⽼项⽬都是⽤的NGUI。但是不意味着新项⽬就不使⽤NGUI 了,本⾝NGUI和UGUI的作者是同⼀个⼈,原理相差不⼤,并且NGUI插件是开源的!等需要深⼊研究的时候,NGUI源码是不得不研究的⼀个东西。相⽐UGUI ,我个⼈觉得NGUI的⾃由度更⾼⼀些,尤其写⼀些UI框架的时候,NGUI⾮常合适。例如:实现⾃动的Panel进⾏UI预制体的层级显⽰(对深度排序),可以直接获取depth进⾏在UI基类中实现排序。
接下来,需要了解资源打包相关的知识。⾯试这个东西是加分项,实际上在框架中都会写好固定的打包逻辑。但是你还是得会!AB包,以及现在新出来的寻址加载系统。这个东西是和Lua热更相关的,不知道很不好⼯作。
AB相关涉及到:C#和Unity的⽂件读取,⾯试很可能会问深度拷贝(⽂件流,字节流,using的⼏种⽤法,如何释放等等)Json相关的东西。最好⾃⼰能写⼀个简单的⽂件打包器。
接下来就得说Lua了。这个玩意,现在基本算是⼯作必备的东西了,不会不代表不到⼯作,但是不好!前提是C#必须得熟悉,不然写完了C#在去学习lua ,两头懵逼。Lua语法⾮常随⼼所欲,属于那种没有规则的规则。Lua核⼼部分都是在table,也就是表。
然后Lua热更:XLua,uLua,toLua之类的相关的插件。这玩意,基本在⼯作中⽤不到,但是实际上
⾯试有的会问。因为好的框架会把这些都封装好了,不⽤我们多做什么东西。
Lua核⼼部分:⾯试常问的,Lua⼏种数据类型,模型匹配,迭代器和泛型for的⼏个之间的区别。模块与包。尾调函数,闭包。元⽅法,元表。最重要的如何使⽤表table来实现⾯向对象(反射和协程我是真的没⽤到,也没遇到有⾯试问这个的。)
买书学习的建议:看Lua程序设计,黄⾊封⽪的那本个⼈感觉那本书讲的简单易懂⼀些!否则的话,直接baidu~~
说⼀下关于粒⼦特效、模型K动画相关的。这两个部分,⼀个属于特效师,⼀个属于建模,部分特效也可能负责K模型动作。如果有想要⾛特效⽅⾯的技术美术的,粒⼦系统是绕不过去的!Unity编辑器相关的代码也是绕不过去的!写⼯具要⽤的。特效很重要的⼀部分在Shader。这⾥多提⼀句:Unity⼊门精要——冯乐乐,新⼊⾏的技术美术必看的东西。然后说⼀下连连看(ASE等以及现在bug不少的ShaderGraph),连连看在我们的现在项⽬中已经使⽤了,想转TA的学不学⾃⾏决定。其他的:⼩破站的闫令qi⼤佬的课程,以及庄懂的技术美术课程。⾄于⾮要买课花钱,我不说什么,您有钱您随意……Shader短期收效慢,说⽩了很难在短期内拉出去能⼲活,需要⼀个长期积累和实践的东西。
不废话了,直接说框架。
基本游戏流程:
1、打开游戏需要检测是否需要热更(涉及热更相关的东西就不说了太多了,百度就可以了)加载loading界⾯。下载资源完成
2、进⼊登录界⾯,执⾏登录⽅⾯以及注册⽅⾯的校验逻辑。
3、退出登录场景(状态),进⼊主城(主界⾯),然后正⼋经进⼊游戏开始玩了。
上⾯的虽然都是废话,但是整个游戏UI的控制,其实就是⼀直进⾏这样⼀个简单的循环。
退出上⼀个场景(可能需要做⼀些事情:清理内存,销毁⼀些不必要的预制体)——进⼊新的场景(可能需要做⼀些事情:加载Loading界⾯,加载状态内的资源,例如场景中的⼀些房⼦模型,⼈物模型等等)——加载完成(关闭loading界⾯)
下⾯三个是常⽤的⼀些⼯具或者框架中简单但是挺重要的模块,因为简单就不过多介绍了。
1、⼩⼯具之类的东西:单例基类。不多介绍,这个不会的话可能真的需要⾃⼰去补⼀下C#基础知识了啊~~
public class AutoSingleton<T>:MonoBehaviour where T:MonoBehaviour
{
private static T instance;
public static T Instance
{
get
{
if(instance ==null)
{
GameObject go =new GameObject(typeof(T).ToString());
instance = go.AddComponent<T>();
}
return instance;
}
}
}
2、⼩⼯具:拓展⽅法,递归查⼦物体;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public static class ExpandFunc
{
public static Transform FindChildWithName(this Transform self,string targetName) {
if(self.name == targetName)
return self;
if(self.childCount <1)
return null;
Transform target;
for(int i =0; i < self.childCount; i++)
{
target = self.GetChild(i).FindChildWithName(targetName);
if(target)
return target;
}
return null;
}
}
3、框架中经常⽤到的⼀个部分,消息传递:
public delegate void LoadDel(float num);//可以⾃定义泛型委托;
public static class MessageManager
{
//⽤于存储想要执⾏的委托字典;
private static Dictionary<string, LoadDel> m_loadDic =new Dictionary<string, LoadDel>();
//将消息或者委托注册到字典中
public static void AddListener(string funcName, LoadDel loadDel)
{
if(m_loadDic.ContainsKey(funcName))
{
m_loadDic.Remove(funcName);
}
前端开发培训得多少钱m_loadDic.Add(funcName, loadDel);
}
//执⾏的时候,就可以通过string把委托从字典取出来,执⾏,num是⼀个参数,可以根据⾃⼰的需要⾃定义泛型委托或者固定参数的委托;
public static void DoFunc(string funcName,float num)
{
LoadDel temDel =null;
if(m_loadDic.TryGetValue(funcName,out temDel))
{
temDel(num);
MDebug.Log("执⾏了⽅法:"+ funcName);
}
}
public static void RemoveFunc(string funcName)
{
m_loadDic.Remove(funcName);
}
public static void ClearAllFunc()
{
m_loadDic.Clear();
}
}
⼀、状态(通常可以理解为⼀个状态,就是⼀个场景,或者在⼀个模块中想要⼲的⼀系列事情。)
由此可知,加载场景就需要两个东西:第⼀加载场景管理类,第⼆状态管理类。这两个是有区别的,第⼀个是从硬盘中把场景资源加载进来,第⼆个是决定管理这些状态什么时候加载,什么时候卸载。这两个管理类暂时先不说,之后详细介绍,也是核⼼的部分!
1)状态基类:
public abstract class BaseScene
{
//开始加载
public void Start()
{
UIManager.LoadPanel();//通过UI管理类加载LoadingPanel;
OnStart();
}
//退出场景
public void Stop()
{
OnStop();
}
//场景加载完成,这个参数的⽤处,之后会介绍的;
public void LoadComplete(params object[] args)
{
OnLoadComplete(args);
}
protected abstract void OnStart();
protected abstract void OnStop();
protected abstract void OnLoadComplete(params object[] args);
}
2)先简单举⼀个例⼦,作为具体实现状态基类的⽅法,当进⼊登录场景的时候,实现具体的虚⽅法,会在基类BaseScene中调⽤。
public class LoginStateScene : BaseScene
{
protected override void OnLoadComplete(params object[] args)
{
//关于UIManger以后介绍;
UIManager.LoadPanel(PanelNameEnum.LoginPanel, PanelNameEnum.None);
}
protected override void OnStart()
{
}
protected override void OnStop()
{
UIManager.DestoryPanel(PanelNameEnum.LoginPanel);
}
}
这两个没什么难度,就是简单的继承⽽已。在之后要写的状态管理类中,就会发现进⼊⼀个场景之前,想要执⾏Stop⽅法,然后执⾏场景的Start⽅法。这个流程就是在状态管理类中控制的;
⾄于UIManager这管理类先不要去管它。之后会详细介绍UI代码如何处理;接下来可能需要先介绍⼀下AB包管理器了(本来想着直接⽤本地加载算了,不⽤ab包了。后来想着反正都写了框架,多介绍⼀点是⼀点吧);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。