Unity中Collision.gameObject.tag报CS0120错误的原因及解决方法
Unity CS0120错误解决:碰撞触发门动画问题
错误原因
你代码第21行里的Collision.gameObject犯了大小写错误:大写的Collision是Unity的类名,而gameObject是Collision类的非静态属性,必须通过类的实例来访问。OnCollisionEnter方法的参数是小写的collision,这才是当前碰撞事件的实例对象,直接访问类名的非静态成员就会触发CS0120错误。
修复方法
- 修正大小写问题:把
Collision.gameObject改成collision.gameObject,同时用更稳妥的标签判断方式:if (collision.gameObject.CompareTag("Door")) - 修复动画重复触发问题:原代码里的
doorAnim.StopPlayback()会直接终止动画,达不到“避免重复触发”的目的,建议添加布尔变量标记门的状态:
在碰撞判断里先检查状态,只有门未打开时才执行动画逻辑。private bool isDoorOpen = false; - 校验组件依赖:确保碰撞双方的物体都有
Collider组件,且其中一个带有Rigidbody组件(否则OnCollisionEnter不会被触发)。
优化建议
- 用
CompareTag()代替直接比较tag:CompareTag()性能更优,且Unity会在编译时校验标签是否存在,避免拼写错误。 - 简化对象引用:如果脚本挂在门对象上,不需要单独声明
public GameObject Door,直接用gameObject.GetComponent<Animator>()获取动画组件即可,减少Inspector配置工作。 - 优化动画控制:不需要手动启用/禁用
Animator组件,直接通过播放状态或布尔参数控制动画更稳妥;如果是一次性开门动画,播放后可以禁用碰撞体或者标记状态,防止重复触发。
修正后的完整代码
using UnityEngine; public class DoorOpen : MonoBehaviour { public Animator doorAnim; // 如果脚本挂在门上,可删除下面这行,直接用gameObject public GameObject Door; private BoxCollider boxCollider; private bool isDoorOpen = false; void Start() { boxCollider = GetComponent<BoxCollider>(); // 如果脚本挂在门上,替换为 doorAnim = GetComponent<Animator>(); doorAnim = Door.GetComponent<Animator>(); } private void OnCollisionEnter(Collision collision) { // 使用CompareTag优化标签判断 if (collision.gameObject.CompareTag("Door") && !isDoorOpen) { isDoorOpen = true; doorAnim.Play("Open"); // 可选:播放完动画后禁用碰撞体,防止重复触发 // boxCollider.enabled = false; } } }
内容的提问来源于stack exchange,提问作者DuckieIsADev
相关产品推荐
相关产品推荐

