Unity中的反射:游戏开发的魔法镜子
什么是反射?一个生动的比喻想象你是一个探险家,走进了一个神秘的迷宫——这个迷宫就是Unity的游戏世界。迷宫里有很多房间(游戏对象),每个房间里都有不同的家具(组件),比如桌子(Transform)、灯(Renderer)、门(Collider)等。通常,你会拿着地图(脚本)直接找到某个房间的某个家具,比如用gameObject.GetComponent()去拿出一个“柜子”(刚体组件)。
但有时候,你手上没有详细的地图,或者迷宫会随时改变布局(运行时条件未知)。这时候,你掏出一面魔法镜子(反射),它能让你看到每个房间里有什么家具(组件类型)、这些家具的细节(属性和字段),甚至还能让你喊一声“开门”(调用方法),或者凭空造出新家具(实例化对象)。这面镜子不需要你提前知道迷宫的全部信息,只需在探索时照一照,就能动态搞定一切。
反射的具体用法与例子在Unity中,反射是通过C#的System.Reflection命名空间实现的。以下是三个实际的例子,展示反射的强大之处。
动态获取组件并调用方法假设你想写一个工具,让玩家在运行时输入组件名和方法名,就能调用对应的功能,而不需要在代码里写死。
...
里氏替换原则:让你的代码像靠谱的接班人
引言在这篇笔记中,我将用简单易懂的语言,通过生活中的比喻和 C# 代码示例,理解里氏替换原则(Liskov Substitution Principle, LSP)。LSP 是面向对象编程中的一个核心原则
里氏替换原则是什么?简单来说,里氏替换原则就是:子类必须能完全替代父类,不出乱子。换句话说,子类得像个靠谱的接班人,能干父类的活儿,不能干砸了。如果用子类替换了父类,程序还得正常跑,不能崩。
生活中的比喻想象你有一辆自行车,平时骑着它去超市买菜,好用得很。有一天,你把自行车换成了一辆玩具车。玩具车也能“跑”(你推它就动),也能停,但它载不了你去超市。如果你指望用玩具车完成买菜的任务,那肯定完蛋。
问题在哪儿?玩具车虽然也能算“交通工具”,但它干不了自行车的基本活儿——载人去目的地。这就违反了里氏替换原则:玩具车不能真正替代自行车。
C# 代码示例:违反 LSP 的例子假设我们在写一个游戏,定义一个父类 Weapon(武器),有个方法 Attack() 表示攻击。子类 Sword(剑)继承它,实现正常的攻击功能:
123456789101112131415public class ...
Unity中多线程使用的注意点
Unity教程在这篇文章中,我们将讨论 Unity 中新线程无法访问 Unity 变量的问题。
Unity中新线程无法访问Unity变量在Unity中,默认情况下你不能从非主线程访问Unity的游戏对象或组件等变量。Unity的所有游戏对象和组件(如Transform、GameObject、MonoBehaviour等)都只能在主线程(也就是Unity的主线程)中访问。尝试从其他线程访问这些对象通常会导致异常或不可预测的行为。
主要原因:
Unity引擎本身是基于单线程的架构设计,所有与渲染、物理、输入等相关的操作都是在主线程中执行的。为了确保这些操作的安全性,Unity限制了游戏对象的访问范围,防止多线程操作导致数据竞态或崩溃等问题。
解决方案:如果你需要在多线程中处理一些数据,可以考虑以下几种方案:
使用线程安全的数据类型:在子线程中处理与Unity对象无关的数据,完成后将结果传递回主线程。
主线程与子线程的通信:使用线程安全的数据结构(如ConcurrentQueue)在主线程和子线程之间传递数据。
使用Task和async/await:利用异步任务在主线程完成Unity对象 ...
Unity项目丧失围城注意点
单例模式管理 UIUImag1 作为全局唯一的管理类,避免混乱:123private static UImag1 instance = new UImag1();public static UImag1 Instance => instance;
动态加载 UI 面板通过 ShowPanel 方法加载 Prefab,并缓存到字典中,减少重复实例化:123GameObject UIgameobj = GameObject.Instantiate(Resources.Load<GameObject>("UI/" + filename));UIgameobj.transform.SetParent(canvastran, false);
UI 生命周期管理BasePanel 类定义了 Init、ShowMe 和 HideMe 方法,子类(如 LoginPanel)通过重写实现自定义行为。资源释放Hideme 方法支持淡出动画并销毁实例,释放内存:12dicpanel[Ui_name].HideMe(() => { GameObject.D ...
Unity 资源管理与性能优化
Unity教程在这篇文章中,我们将聊聊如何在 Unity 中管理资源并优化性能,基于我的项目代码提取要点。
资源管理的实现我的代码在资源加载和性能优化上有几处亮点:
资源动态加载用 Resources.Load 加载 UI 和图标:1SpriteAtlas stateicon = Resources.Load<SpriteAtlas>("StateIcon");
SpriteAtlas 优化用 SpriteAtlas 管理状态图标,提升渲染效率:1ButtonState.sprite = stateicon.GetSprite("ui_DL_liuchang_01");
UI 元素复用先销毁旧按钮再创建新按钮,节省内存:1for (int i = 0; i < Right_Button.Count; i++) { Destroy(Right_Button[i]); }
Unity 中的数据持久化与 JSON 使用
Unity教程在这篇文章中,我们将聊聊如何用 JSON 在 Unity 中实现数据持久化,基于我的项目代码总结经验。
数据持久化的实现我的项目通过 LoginMager 单例类管理登录和注册数据,用 JSON 保存到本地。以下是核心实现:
JSON 数据的加载与保存用工具类处理 JSON 文件的读写:12loginData = jsonInstance.Instance.LoadJson<LoginData>("LoginData", JsonType.NewTonJson);jsonInstance.Instance.SaveJson(loginData, "LoginData");
登录与注册的实现
我的登录和注册功能靠 LoginPanel 和 RegisterPanel 完成,逻辑清晰且用户友好:
登录逻辑检查输入并验证合法性:12345678 if (User_Name.text.Length <= 6 || User_PassWord.text.Length <= 6) { /* 显示提示 * ...




