中北大学动漫创新实验室问题汇总答疑
1.命名问题
1)一般变量:一般为首单词小写,其余大写(小驼峰)
2)Bool类型:+ 前缀“is”
3)常量:并且每个字母大写,单词间使用“_”
4)方法,脚本,GO:每个单词都大写(大驼峰)
5)接口:+ 前缀“I”
6)委托:+ 后缀 “Event”
7)回调函数:+ 前缀“On”
8)呼叫函数:+ 前缀“Call”
2.单例与事件模式
1)单例模式:当脚本挂在一个物体上,那么使用单例模式调用脚本中的方法和变量就不需要寻找了,可以直接使用。
注:直接写一个父类,使用直接继承即可。
public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{private static T instance;public static T Instance{get => instance;}protected virtual void Awake(){if (instance != null)Destroy(gameObject);elseinstance = (T)this;}protected virtual void OnDestroy(){if(instance == this){instance = null;}}
}
2)事件模式:详见《Unity事件系统(委托与回调函数)》
注:事件与单例滥用会不便于代码维护。
3.Lumbda表达式与变量get/set
1)Lumbda表达式:对匿名函数的简化。
基本格式:(参数1,参数2,....) => { 代码块 }
2)get与set:可以设置变量的读写性质,一般需要设置外部访问器。
private float num;private float Num{get{ return num; }set{ num += 10; }
}
4.周期函数
1)Awake > OnEnable > Start
2)Update:根据设备性能逐帧执行。
FixedUpdate:0.02s执行一次,可更改步长,一般进行物理模拟相关计算。
LateUpdate:等待所有Update执行完之后执行。
5.ScriptObject
1)概念:可独立于类实例来保存大量数据的数据容器。
2)作用:通过避免重复值来减少项目的内存使用量。
例子:每次实例化预制体时,都会产生单独的数据副本。这种情况会存储重复数据;使用
ScriptableObject 来存储数据,然后通过所有预制体的引用访问数据。这意味着内
存中只有一个数据副本。
3)使用场景:项目有一个预制体的脚本中存储不变的数据。
4)注意:如果存储变化(更新)的数据,那么数据可以在编辑器中实时保存,但是打包出的
项目只能在运行中暂时存储数据,一旦项目关闭,数据会恢复为打包时的数据,无
法做到持久化保存。
6.协程
1)作用:允许分段执行代码逻辑。
2)本质:运行在Unity主线程中,通过迭代器实现,模拟异步行为,协程之间是顺序执行,而
不是多线程并发,在每帧update之后检查yied条件是否满足,通过yield return暂停
协程后,主线程继续处理其他操作(如渲染),待条件满足时,Unity将协程的后续
代码重新加入主线程队列。协程本身不涉及多线程,但能避免主线程阻塞。
7.序列化与反序列化
1)序列化实际上就是把一段数据转化为比较底层的语言(如汇编、机器语言)。
2)使用场景:Inspector面板的显示,游戏存档与JSON序列化(Unity将场景中的GameObject
及其组件属性序列化为.unity
场景文件或.prefab
预制体文件),
ScriptableObject数据容器,场景和预制体(Prefab)的保存等。
3)不支持序列化的类型:静态变量,属性,委托,事件与接口。
4)常用API:
[System.SerializeField] //表示变量可被序列化
[HideInInspector] //原本显示在检视面板上的序列化值隐藏起来
[NonSerialized] //将一个公有变量不序列化并且不显示在检视面板中
[Serializable] //用在类的前面,表示该类可被序列化
8.异步加载
1)作用:可以在不冻结游戏主线程的情况下加载资源。
2)好处:加载资源的同时,游戏继续运行,提高性能,加载大型场景时可以实现平滑转换。
3)使用方式:Resources.LoadSceneAsync(1) 或者 使用Addressables工具实现。
4)注:都需要使用协程来完成异步加载操作,协程作为调度工具使用。
9.欧拉角与四元数
1)欧拉角:直观,unity编辑器中使用的旋转方式就是以欧拉角的方式呈现。但是欧拉角存在
万向死锁问题和插值错误的不可避免的问题。
2)四元数:不直观但能解决欧拉角的问题。
3)注:Transform组件里的Rotation是四元数,但是他是以欧拉角(Vector3)的形式展现在
我们面前。
4)万向死锁问题:旋转时x,y,z需要有先后顺序不然变换的结果不一,当旋转时可能出现
轴重合。变换不存在过程,只有初始与结果,例如:先绕x轴旋转10°,再
绕y轴旋转90°,最后绕x轴旋转35°,但是因为不存在过程,因此实际计算
是先绕x轴旋转45°,最后绕y轴旋转90°。