目录
知识点
- Unity目前序列化是不支持字典的,可以采用两个列表实现键值对,然后在序列化和反序列化时监听更新字典。
- Unity同样不支持数组嵌套序列化,如List<List<T>>> L。但是可以通过添加新类的方式间接支持。
[System.Serializable] public class Data { public List<int> a; } // 另一个类 public List<Data> b; // 支持
- C#中提供了get和set属性字段,默认情况下是无法将其序列化的,但是使用[field: SerializeField] 标签就可以进行序列化了。
- 序列化是有限制的,必须绑定在游戏对象上。开发中有时候需要序列化一些编辑器数据,但仅仅是数据,完全没必要依赖游戏对象使用游戏脚本,此时就需要使用ScriptableObject。创建ScriptableObject其实就是创建了序列化的资源,因为它只存储了数据。
- 脚本生命周期需要在运行模式下才能执行,而Unity其实提供了在编辑模式下执行脚本的方法,只需要在脚本类名前添加[ExecuteInEditorMode]标签即可。这样,生命周期的方法,如Awake()、Start()、Update()等,都会在非运行模式下执行。
- 携程并不是多线程,只是让延迟部分等到下一帧,满足条件时执行。
- 自定义携程函数。
// 自定义携程实现在10秒钟内,每个1秒调用给定函数方法 using System.Collections; using System.Collections.Generic; using System; using UnityEngine; using UnityEngine.Events; public class NewBehaviourScript : MonoBehaviour { // 运行游戏后开始调用 IEnumerator Start() { // 采用匿名函数传参 yield return new CustomWait(10f, 1f, () => { Debug.LogFormat($"每过1秒回调一次:{ Time.time}"); }); Debug.Log("10秒结束"); } public class CustomWait : CustomYieldInstruction { private UnityAction m_IntervalCallback; private float m_StartTime; private float m_LastTime; private float m_Interval; private float m_Time; // 构造函数,赋初值 public CustomWait(float time, float interval, UnityAction callback) { m_StartTime = Time.time; m_Interval = interval; m_LastTime = Time.time; m_Time = time; m_IntervalCallback = callback; } // 重写父类属性 public override bool keepWaiting { get { if(Time.time - m_StartTime >= m_Time) // 达到总时间,携程结束 { return false; // 表示携程结束 } else if(Time.time - m_LastTime >= m_Interval) // 达到时间间隔,调用回调函数 { m_LastTime = Time.time; m_IntervalCallback?.Invoke(); } return true; } } } }
技巧
- 采用InspectorName标签在枚举属性之前声明一个别名,在Unity的Inspector面板中可以显示别名,提升阅读体验。
public enum my_Enum { [InspectorName("第一")] one, [InspectorName("第二")] two }