You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Collision.gameObject.tag报CS0120错误的原因及解决方法

Unity CS0120错误解决:碰撞触发门动画问题

错误原因

你代码第21行里的Collision.gameObject犯了大小写错误:大写的Collision是Unity的类名,而gameObject是Collision类的非静态属性,必须通过类的实例来访问。OnCollisionEnter方法的参数是小写的collision,这才是当前碰撞事件的实例对象,直接访问类名的非静态成员就会触发CS0120错误。

修复方法

  1. 修正大小写问题:把Collision.gameObject改成collision.gameObject,同时用更稳妥的标签判断方式:
    if (collision.gameObject.CompareTag("Door"))
    
  2. 修复动画重复触发问题:原代码里的doorAnim.StopPlayback()会直接终止动画,达不到“避免重复触发”的目的,建议添加布尔变量标记门的状态:
    private bool isDoorOpen = false;
    
    在碰撞判断里先检查状态,只有门未打开时才执行动画逻辑。
  3. 校验组件依赖:确保碰撞双方的物体都有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:42:45