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

Unity 2D问题:Player GameObject失活后无法重新激活

问题分析与解决方案

核心问题

  1. 失活对象无法被查找:Player被SetActive(false)后,GameObject.FindGameObjectWithTag("Player")无法定位到该对象,导致后续调用Player.SetActive(true)时,Player变量为null,无法执行激活操作。
  2. 硬编码时间不可靠:用固定的17/18秒延迟匹配Timeline时长,一旦Timeline修改时长就会出错,且无法保证和Timeline实际结束时间完全同步。
  3. Timeline引用逻辑错误:Start方法里的timeline = timeline.GetComponent<PlayableDirector>()会覆盖Inspector中拖入的引用,强制替换为当前脚本所在物体的PlayableDirector,导致引用错误。

修复步骤

  • 提前缓存Player引用:在Player活跃状态时获取并保存引用,避免在Update中反复查找,更不要在Player失活后尝试查找。
  • 监听Timeline完成事件:使用PlayableDirector的completed回调替代硬编码延迟,确保Player在Timeline结束时精准激活。
  • 修正Timeline引用:移除错误的GetComponent调用,直接使用Inspector赋值的引用,或自动获取当前物体的组件。

修正后的代码

using System.Collections;
using UnityEngine;
using UnityEngine.Playables;

public class TimelineTrigger : MonoBehaviour
{
    public PlayableDirector timeline;
    public GameObject Player;
    public GameObject CutsceneCollider;
    public GameObject CutsceneMC;

    void Start()
    {
        // 若未在Inspector赋值timeline,自动获取当前物体的PlayableDirector
        if (timeline == null)
        {
            timeline = GetComponent<PlayableDirector>();
        }
        CutsceneMC.SetActive(false);
        
        // 提前缓存Player引用(确保Player初始状态为活跃)
        if (Player == null)
        {
            Player = GameObject.FindGameObjectWithTag("Player");
        }
    }

    private void EnableAfterTimeline()
    {
        // 直接使用缓存的引用,无需再次查找
        if (Player != null)
        {
            Player.SetActive(true);
        }
    }

    public void OnTriggerEnter2D (Collider2D col)
    {
        if (col.CompareTag("Player"))
        {
            // 禁用碰撞体,防止重复触发
            CutsceneCollider.SetActive(false);
            
            timeline.Play();
            Player.SetActive(false);
            CutsceneMC.SetActive(true);
            
            // 监听Timeline完成事件,替代固定延迟
            timeline.Completed += OnTimelineCompleted;
            
            StartCoroutine(FinishCut());
        }
    }

    private void OnTimelineCompleted(PlayableDirector director)
    {
        EnableAfterTimeline();
        // 移除监听,避免重复触发
        director.Completed -= OnTimelineCompleted;
    }

    IEnumerator FinishCut()
    {
        // 等待Timeline实际时长,而非硬编码17秒
        yield return new WaitForSeconds((float)timeline.duration);
        CutsceneMC.SetActive(false);
    }
}

额外注意事项

  • 确保Player对象的Tag确实为"Player",且初始状态为活跃。
  • 在Inspector中正确拖入timeline、Player等引用,减少对Find方法的依赖,提升性能和可靠性。
  • 检查Timeline轨道是否有修改Player激活状态的动画片段,避免和代码逻辑冲突。

内容的提问来源于stack exchange,提问作者Moonlit Buns

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:06:22