Files
Vision/.agents/skills/unity-development-rules/SKILL.md
T
2026-10-14 14:46:24 +08:00

91 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: unity-development-rules
description: Unity 开发规则(Unity Vision 项目)。在本项目里写或改 C# 脚本、预制体、场景时适用,包含节点引用接线等硬性约定。
---
# Unity 开发规则
本项目的硬性约定。动手写脚本、改预制体或场景之前先对照这里。
## 节点引用必须在 Inspector / 预制体里指定,不能硬编码到代码
脚本要访问场景或预制体里的节点(Transform、Text、Image、其他组件……)时,一律用 `[SerializeField]` 字段,由 Inspector 或预制体把引用接好。
**不允许**——在代码里按名字 / 标签 / 路径找节点:
```csharp
// ❌ 节点名字写死在代码里
target = transform.Find("FPS").GetComponent<TMP_Text>();
target = GameObject.Find("FPS").GetComponent<TMP_Text>();
foreach (var t in GetComponentsInChildren<TMP_Text>(true))
if (t.name == "FPS") return t;
```
**允许**:
```csharp
[SerializeField] private TMP_Text target; // ✅ 引用由 Inspector / 预制体提供
```
**为什么**:节点改名或挪位置以后,硬编码的查找会静默失效——不报错、就是不工作;而且引用关系藏在代码里,看 Inspector 看不出到底接没接上。
**引用为空时**:不要写运行时兜底查找,直接报错,让接线问题第一时间暴露。
```csharp
private void Awake()
{
if (target == null)
Debug.LogError("[Xxx] 没有指定 target,请在 Inspector 里拖入。", this);
}
```
**边界**:这条只约束游戏运行时代码。编辑器工具、一次性批处理脚本需要按结构查找节点时可以照常查找。
## 动画一律用 Animator 播,不用 legacy 的 Animation 组件
要在物体上播放动画时,走 `Animator`(状态 / 触发器 / 参数):
```csharp
[SerializeField] private Animator animator; // ✅ 引用由 Inspector / 预制体提供
```
**不允许**——用老的 `Animation` 组件播动画:
```csharp
// ❌ legacy 的 Animation 组件
_animation = GetComponent<Animation>();
_animation.clip = someClip;
_animation.Play();
// ❌ 运行时自己补一个 Animation 组件
gameObject.AddComponent<Animation>();
```
**为什么**:项目统一一套动画播放方式,动画和程序看同一处。混用会让同一个物体上既有 `Animator` 又有 `Animation`,两边驱动同一批属性,播放互相打架、排查困难。
**例外**:用户明确说明这次要用 `Animation` 才用,且只限那一次改动。
## 只做用户点名要做的事
用户说改哪里就只改哪里。下面这些都算「没说过的事」,不要顺手做:
- 给预制体 / 物体加组件(尤其是为了让自己写的代码能跑起来而补一个组件)
- 加用户没提过的功能或容错(自动回收、时长兜底、默认值兜底……)
- 动用户已经定好的行为或时序(例如特效 / 动画的播放时机)
- 保存场景、保存预制体、改其它资源
不改就做不下去时,先说明「为什么必须动它」并问一句,确认后再动。
## 预制体资产存不下场景对象引用
预制体上的脚本要指向场景里的物体(玩家、UI、相机……)时,预制体资产里这个字段只能是空的,
必须在**每个场景实例上各接一次**;指向资源(预制体、Clip、材质)的字段才可以直接在预制体上设。
接的时候留意目标是不是「真正会移动 / 变化」的那个节点:玩家根节点不动、真正移动的是子节点时,要接子节点。
## 「编译干净」要先确认脚本真的被 Unity 导入
改完脚本后,确认对应的 `*.cs.meta` 已生成、类型能在编辑器程序集里查到,再看编译结果。
否则 Unity 还没导入这个文件,控制台没报错不代表它编译通过。