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

Unity自定义事件无法触发的问题排查与解决

Unity顾客离开事件未触发问题排查与解决

问题背景

开发游戏时实现以下流程:生成顾客→顾客前往餐桌→等待后返回生成点→删除顾客并触发事件通知生成更多顾客。当前其他功能正常,但事件触发后无响应,监听器日志未输出。

代码实现情况

  • CustomerMovement脚本中定义并触发OnCustomerLeaves事件
  • CustomerSpawnManager脚本尝试订阅该事件,但未收到触发通知

相关代码

CustomerMovement 脚本

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CustomerMovement : MonoBehaviour
{
    public event EventHandler OnCustomerLeaves;

    private Vector3 startingPos;

    [SerializeField] private List<GameObject> seatingOptionsList;
    private GameObject seatingSpot;
    private bool atSpot = false;

    private float speedValue = 3.0f;
    private float speed;
    private float waitTimer = 5.0f;

    private void Start()
    {
        startingPos = transform.position;
        PickRandomSeat();
    }

    private void Update()
    {
        HandleMovement();     
    }

    private void PickRandomSeat()
    {
        int randomSeatingSpot = UnityEngine.Random.Range(0, seatingOptionsList.Count);
        seatingSpot = seatingOptionsList[randomSeatingSpot];
    }

    private void HandleMovement()
    {
        if (atSpot == false)
        {
            speed = speedValue * Time.deltaTime;
            Vector3 modSeatingPosition = new Vector3(seatingSpot.transform.position.x, seatingSpot.transform.position.y + 1, seatingSpot.transform.position.z);

            transform.position = Vector3.MoveTowards(transform.position, modSeatingPosition, speed);
            
            if (transform.position == modSeatingPosition)
            {
                atSpot = true;
            }
        }
        if (atSpot == true)
        {
            waitTimer -= Time.deltaTime;

            if (waitTimer <= 0)
            {
                transform.position = Vector3.MoveTowards(transform.position, startingPos, speed);

                if (transform.position == startingPos)
                {
                    DestroyCustomer();
                }
            }
        }
    }

    private void DestroyCustomer()
    {
        OnCustomerLeaves?.Invoke(this, EventArgs.Empty);
        Debug.Log("Called");
        gameObject.SetActive(false);
    }
}

CustomerSpawnManager 脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CustomerSpawnManager : MonoBehaviour
{
    [SerializeField] private GameObject customerPrefab;
    private CustomerMovement customerMovement;

    private float spawnRate = 2.0f;
    private float spawnRateMax = 2.0f;

    private int maxCustomers = 3;
    private int currentCustomers = 0;

    private void Start()
    {
        customerMovement = customerPrefab.GetComponent<CustomerMovement>();
        customerMovement.OnCustomerLeaves += CustomerMovement_OnCustomerLeaves;
    }

    private void CustomerMovement_OnCustomerLeaves(object sender, System.EventArgs e)
    {
        Debug.Log("Maybe");
    }

    private void Update()
    {
        if (currentCustomers < maxCustomers)
        {
            SpawnCustomers();
        }
    }

    private void SpawnCustomers()
    {
        spawnRate -= Time.deltaTime;

        if (spawnRate <= 0)
        {
            var customer = Instantiate(customerPrefab, transform.position, customerPrefab.transform.rotation);
            customer.transform.parent = gameObject.transform;

            currentCustomers++;
            Debug.Log("Customers: " + currentCustomers);

            spawnRate = spawnRateMax;
        }
    }
}

问题解决

原代码中在Start()方法里直接订阅预制体上的CustomerMovement事件,但实际运行时生成的是预制体的实例,实例上的事件并未被订阅。将获取组件和订阅事件的逻辑移至预制体实例化之后,即可正常接收事件触发通知。

内容的提问来源于stack exchange,提问作者Dylan Baum

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 18:50:16