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

Unity GameObject移动停止后陷入无动作循环问题求助(附代码)

问题分析与解决方案

问题根源

  • 倒计时逻辑错误:你使用timer--在Update中按帧计数,而非基于实际时间的倒计时,且初始值100000过大,导致恢复移动后需要极长时间才会再次触发停止,视觉上表现为“死循环无动作”。
  • 状态控制不够直观:依赖running布尔值和帧计数的方式,在状态切换时容易出现逻辑漏洞,且无法精准控制移动/等待的实际时长。

解决方案1:修正原逻辑为时间驱动倒计时

将帧计数的int类型计时器改为基于Time.deltaTime的浮点型计时器,精准控制移动时长:

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

public class Enemyai : MonoBehaviour
{
    public Animator anim;
    // 移动持续时长(单位:秒)
    public float moveDuration = 3f;
    // 停止等待时长(单位:秒)
    public float waitDuration = 2f;
    public bool isRunning = true;
    
    public float speed = 5f;

    private float currentTimer;

    void Start()
    {
        // 初始化计时器为移动时长
        currentTimer = moveDuration;
    }

    void Update()
    {
        if (isRunning)
        {
            anim.SetBool("isRunning", true);
            transform.position += transform.right * -speed * Time.deltaTime;
            
            // 基于实际时间倒计时
            currentTimer -= Time.deltaTime;
            if (currentTimer <= 0)
            {
                isRunning = false;
                anim.SetBool("isRunning", false);
                // 触发等待后恢复移动
                Invoke("ResumeMovement", waitDuration);
            }
        }
    }

    void ResumeMovement()
    {
        isRunning = true;
        // 重置计时器为移动时长,开始下一轮移动
        currentTimer = moveDuration;
    }
}

解决方案2:使用协程实现循环逻辑(更推荐)

协程可以更清晰地封装“移动→等待→重复”的序列逻辑,无需在Update中维护状态:

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

public class Enemyai : MonoBehaviour
{
    public Animator anim;
    // 移动持续时长(单位:秒)
    public float moveDuration = 3f;
    // 停止等待时长(单位:秒)
    public float waitDuration = 2f;
    public float speed = 5f;

    void Start()
    {
        // 启动循环协程
        StartCoroutine(MoveAndWaitLoop());
    }

    IEnumerator MoveAndWaitLoop()
    {
        while (true)
        {
            // 移动阶段
            anim.SetBool("isRunning", true);
            float moveTimer = moveDuration;
            while (moveTimer > 0)
            {
                transform.position += transform.right * -speed * Time.deltaTime;
                moveTimer -= Time.deltaTime;
                yield return null; // 等待下一帧
            }

            // 停止等待阶段
            anim.SetBool("isRunning", false);
            yield return new WaitForSeconds(waitDuration); // 等待指定时长
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:20:39