这篇按“操作对象时想做什么”来查:找对象、拿组件、生成 Prefab、销毁、启用禁用、改父节点、换坐标。
快速索引
| 我想做什么 |
常用 API |
| 拿自己身上的组件 |
GetComponent<T>() |
| 安全判断组件是否存在 |
TryGetComponent<T>() |
| 拿子节点组件 |
GetComponentInChildren<T>() |
| 拿父节点组件 |
GetComponentInParent<T>() |
| 查场景对象 |
FindObjectOfType<T>()、GameObject.Find |
| 按 Tag 查对象 |
GameObject.FindWithTag |
| 生成 Prefab |
Instantiate |
| 销毁对象 |
Destroy |
| 禁用整个对象 |
gameObject.SetActive(false) |
| 禁用脚本组件 |
enabled = false |
| 禁用渲染 |
renderer.enabled = false |
| 设置父节点 |
transform.SetParent |
| 世界坐标转本地坐标 |
InverseTransformPoint |
| 本地坐标转世界坐标 |
TransformPoint |
0. GameObject 常用属性
1 2 3 4 5 6 7 8 9 10
| gameObject.name gameObject.tag gameObject.layer gameObject.activeSelf gameObject.activeInHierarchy transform.position transform.localPosition transform.rotation transform.localRotation transform.localScale
|
1. 获取组件
1 2 3 4 5 6
| private Rigidbody rb;
private void Awake() { rb = GetComponent<Rigidbody>(); }
|
安全写法:
1 2 3 4 5 6 7 8 9 10 11
| private void Awake() { if (!TryGetComponent(out Rigidbody rb)) { Debug.LogError("缺少 Rigidbody", this); enabled = false; return; }
this.rb = rb; }
|
查子节点或父节点:
1 2
| Renderer childRenderer = GetComponentInChildren<Renderer>(); Canvas parentCanvas = GetComponentInParent<Canvas>();
|
包含未激活对象:
1
| Renderer[] renderers = GetComponentsInChildren<Renderer>(true);
|
2. Inspector 引用优先
1 2
| [SerializeField] private Transform firePoint; [SerializeField] private GameObject bulletPrefab;
|
适合:
1 2 3 4
| 固定 UI 节点 固定 Prefab 固定出生点 固定音效源
|
好处:
3. 查找对象
低频可用:
1 2 3
| Player player = FindObjectOfType<Player>(); GameObject uiRoot = GameObject.Find("UIRoot"); GameObject playerObj = GameObject.FindWithTag("Player");
|
少用:
1 2 3 4
| private void Update() { GameObject player = GameObject.FindWithTag("Player"); }
|
替代写法:
1
| [SerializeField] private Player player;
|
或者用注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public sealed class PlayerRegistry : MonoBehaviour { public static Player Current { get; private set; }
private void Awake() { Current = GetComponent<Player>(); }
private void OnDestroy() { if (Current == GetComponent<Player>()) { Current = null; } } }
|
4. Instantiate 生成对象
1
| GameObject bullet = Instantiate(bulletPrefab);
|
指定位置和旋转:
1 2 3 4 5
| GameObject bullet = Instantiate( bulletPrefab, firePoint.position, firePoint.rotation );
|
指定父节点:
1 2
| GameObject item = Instantiate(itemPrefab, contentRoot); item.transform.localScale = Vector3.one;
|
泛型写法:
1 2
| Bullet bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation); bullet.Init(damage, direction);
|
5. Destroy 销毁对象
1 2 3
| Destroy(gameObject); Destroy(enemy.gameObject); Destroy(effect, 2f);
|
注意:
1 2 3 4
| Destroy 不是立刻从内存消失 当前帧后续代码仍可能继续执行 销毁后旧引用会变成 Unity 假 null 高频创建销毁用对象池
|
销毁后直接返回:
1 2
| Destroy(gameObject); return;
|
6. SetActive / enabled / renderer.enabled
禁用整个对象树:
1
| gameObject.SetActive(false);
|
只禁用脚本:
只隐藏渲染:
1
| meshRenderer.enabled = false;
|
只关闭碰撞:
1
| collider.enabled = false;
|
区分:
1 2
| activeSelf # 自己是否被设置激活 activeInHierarchy # 父节点影响后的最终激活状态
|
1 2 3 4
| transform.position = new Vector3(0, 1, 0); transform.localPosition = Vector3.zero; transform.rotation = Quaternion.identity; transform.localScale = Vector3.one;
|
移动:
1 2 3 4 5 6
| transform.Translate(Vector3.forward * speed * Time.deltaTime); transform.position = Vector3.MoveTowards( transform.position, target.position, speed * Time.deltaTime );
|
朝向目标:
1 2
| Vector3 dir = target.position - transform.position; transform.rotation = Quaternion.LookRotation(dir);
|
坐标转换:
1 2
| Vector3 local = transform.InverseTransformPoint(worldPos); Vector3 world = transform.TransformPoint(localPos);
|
8. 父子节点
1 2 3 4 5
| transform.SetParent(parent); transform.SetParent(parent, false); transform.SetAsFirstSibling(); transform.SetAsLastSibling(); int index = transform.GetSiblingIndex();
|
遍历子节点:
1 2 3 4 5
| for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); child.gameObject.SetActive(false); }
|
删除所有子节点:
1 2 3 4
| for (int i = transform.childCount - 1; i >= 0; i--) { Destroy(transform.GetChild(i).gameObject); }
|
9. Layer / Tag
1 2 3 4
| if (other.CompareTag("Player")) { Debug.Log("碰到玩家"); }
|
1 2
| int enemyLayer = LayerMask.NameToLayer("Enemy"); gameObject.layer = enemyLayer;
|
1
| LayerMask mask = LayerMask.GetMask("Enemy", "Ground");
|
10. 常见坑速查
1 2 3 4 5 6 7
| 每帧 GetComponent / Find # 提前缓存或拖引用 GameObject.Find 依赖名字 # 改名后失效 Destroy 后继续访问对象 # 直接 return SetParent 后 UI 坐标飞了 # UI 用 SetParent(parent, false) Prefab 引用场景对象 # 实例化后容易丢引用 父节点 inactive,子节点 activeSelf true # 看 activeInHierarchy 用世界坐标改 UI # UI 优先查 RectTransform
|
系列导航