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

Unity中从Delivery类向CustomerScript类导入变量i失败求助

问题分析与解决方案

核心问题

你在CustomerScript中通过Delivery abc = new Delivery();创建了一个全新的Delivery实例,这个实例和场景中挂载在玩家对象上的Delivery完全无关,因此永远无法获取到碰撞后更新的i值。


解决方案

方案一:Inspector手动引用(最简单直观)

修改CustomerScript,将Delivery字段设为可在Unity编辑器中赋值的类型,然后手动关联场景中的Delivery组件:

using UnityEngine;

public class CustomerScript : MonoBehaviour
{
    // 用[SerializeField]让字段在Inspector面板可见,也可直接设为public
    [SerializeField] private Delivery delivery;

    void Update()
    {
        // 先判断引用是否有效,避免空引用错误
        if (delivery != null && delivery.i == 1)
        {
            transform.position = new Vector3(8.22f, 16.52f, -16f);
            // 可选:执行后重置i,防止重复触发位置修改
            // delivery.i = 0;
        }
    }
}

操作步骤:选中挂载CustomerScript的精灵物体,在Inspector面板找到CustomerScript组件,将场景中挂载了Delivery的玩家对象拖到delivery字段上。

方案二:代码动态查找(无需手动赋值)

如果不想手动关联引用,可在Start方法中自动查找场景中的Delivery组件:

using UnityEngine;

public class CustomerScript : MonoBehaviour
{
    private Delivery delivery;

    void Start()
    {
        // 查找场景中第一个Delivery组件
        delivery = FindObjectOfType<Delivery>();
        
        // 若场景中有多个Delivery,建议给玩家对象加专属标签(比如"Player"),用以下方式查找更高效:
        // delivery = GameObject.FindWithTag("Player").GetComponent<Delivery>();
    }

    void Update()
    {
        if (delivery != null && delivery.i == 1)
        {
            transform.position = new Vector3(8.22f, 16.52f, -16f);
        }
    }
}

注意:FindObjectOfType在复杂场景中效率较低,优先推荐标签查找方式。

方案三:事件系统(解耦性最强,推荐)

通过事件通知的方式,让Delivery在触发碰撞时主动通知CustomerScript,无需互相引用,代码解耦性更好:

  1. 修改Delivery.cs,添加触发事件:
using UnityEngine;

public class Delivery : MonoBehaviour
{
    public int i = 0;
    public int Score = 0; // 修正拼写错误:Sccore → Score

    // 定义事件,当触发Stone碰撞时调用
    public static event System.Action OnStoneDelivered;

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Stone"))
        {
            Debug.Log("Triggered!!!");
            i = 1;
            Destroy(other.gameObject);
            // 触发事件,通知所有订阅者
            OnStoneDelivered?.Invoke();
        }

        if (other.CompareTag("EditorOnly"))
        {
            Score += 1;
            Debug.Log("Score: 1");
            Destroy(other.gameObject);
        }
    }
}
  1. 修改CustomerScript.cs,订阅事件:
using UnityEngine;

public class CustomerScript : MonoBehaviour
{
    void OnEnable()
    {
        // 订阅事件
        Delivery.OnStoneDelivered += OnStoneDeliveredHandler;
    }

    void OnDisable()
    {
        // 取消订阅,避免内存泄漏
        Delivery.OnStoneDelivered -= OnStoneDeliveredHandler;
    }

    private void OnStoneDeliveredHandler()
    {
        // 收到通知后修改位置
        transform.position = new Vector3(8.22f, 16.52f, -16f);
    }
}

额外注意事项

  • 碰撞触发条件:确保Stone对象的Collider2D勾选了Is Trigger,或者玩家对象的Collider2D勾选了Is Trigger,且至少一个对象带有Rigidbody2D(你的玩家对象已满足),否则OnTriggerEnter2D不会触发。
  • 变量命名规范:建议将i改为更具语义的名称(比如isStoneDelivered),提升代码可读性。

内容的提问来源于stack exchange,提问作者Vishist Parashar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:20:13