【问题标题】:WaitForSeconds firing immediatelyWaitForSeconds 立即触发
【发布时间】:2021-05-10 15:18:48
【问题描述】:

我正在尝试设置一个冲刺能力来更新玩家速度,等待一段时间(dashTime),然后将canDash 设置为 false 一段时间(dashCooldown) .

但是,waitForSeconds 似乎无法正常工作,因为 canDash 布尔值在切换回 true 之前仅保持 false 片刻。

PlayerAbilities.cs

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

public class PlayerAbilities : MonoBehaviour
{
    // Scripts & Data
    [SerializeField] PlayerController s_PC;
    internal PlayerData pd = new PlayerData();

    private void Awake() {
        pd.canDash = true;
    }

    // Dash
    internal IEnumerator Dash()
    {
        pd.CanDash = false;
        Debug.Log("dash, dash baby");
        // Perform dash and update canDash
        s_PC.rb2d.velocity = s_PC.s_PlayerMovement.moveInput * pd.dashSpeed;
        yield return new WaitForSeconds(pd.dashTime); // Wait set time for dash to happen
        s_PC.UpdateState(PlayerController.State.Normal); // Change state back to normal

        // Cooldown dash
        yield return new WaitForSeconds(pd.dashCooldown); // Cooldown dash

        pd.CanDash = true;
    }
}

PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    // Scripts & Data
    [SerializeField] internal PlayerAbilities s_PlayerAbilities;
    [SerializeField] internal PlayerInput s_PlayerInput;
    internal PlayerData pd = new PlayerData();

    // Update is called once per frame
    private void FixedUpdate()
    {
        // Check if user has control of player
        if (pd.canControlPlayer)
        {
            // Update player state
            switch (playerState)
            {
                case State.Normal:
                    s_PlayerMovement.Move();
                    break;
                case State.Dash:
                    StartCoroutine(s_PlayerAbilities.Dash());
                    break;
                case State.DodgeRoll:
                    StartCoroutine(s_PlayerAbilities.DodgeRoll());
                    break;
            }
        }
    }
}

PlayerData.cs

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

[Serializable]
public class PlayerData
{
    // Dash
    internal float dashSpeed = 50f;
    internal float dashTime = 0.2f;
    internal float dashCooldown = 5f;
    internal bool canDash = true;
    
    internal bool CanDash {
        get { return canDash; }
        set { canDash = value; }
    }
}

PlayerInput.cs

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

public class PlayerInput : MonoBehaviour
{
    // Scripts & Data
    [SerializeField] PlayerController s_PC;
    internal PlayerData pd = new PlayerData();

    // Input Actions
    internal PlayerInputActions playerInputActions;

    private void Awake() {
        // Define new player input
        playerInputActions = new PlayerInputActions();
    }

    private void Update()
    {
        // Check if player state is normal
        if (s_PC.playerState == PlayerController.State.Normal)
        {
            // Check for button presses
            if (playerInputActions.Movement.DodgeRoll.triggered)
                s_PC.UpdateState(PlayerController.State.DodgeRoll);
        }

    }
}

【问题讨论】:

  • pd.dashCooldown 设置为什么以及如何运行这个协程?另外我会将pd.CanDash = false; 移到协程的顶部.. 否则您仍然可以启动多个例程,直到pd.dashTime 过去...我怀疑这是您的问题的根源
  • pd.dashCooldown5f。使用 switch 语句从 playerController 中的 FixedUpdate 调用协程。当 playerState 案例为 dash 时,它会触发它。我会将其添加到最初的问题中。此外,将 pd.canDash = false 移动到协程的开头并不能解决问题
  • 第一个WaitForSeconds() 工作了吗?
  • Longshot,但值得检查的一点是:你已经序列化了字段 dashCooldown 并且如果你在检查器中更改了它的值(例如为了测试目的而更改为 0 ) 它将使用该值并忽略5f 的默认值。
  • 嗨@MarkHughes88 您偶然发现了Unity 中的一个基本问题!因为单例在 Unity 中是没有意义的(没有游戏对象“单例”的概念),所以您只需有一个“预加载场景”,您可以在其中保留任何“类似单例的通用系统,这些系统是 MonoBehaviors”。这是我关于这个问题的世界著名文章 :) stackoverflow.com/a/35891919/294884 干杯,一旦你这样做了,一切都是微不足道的

标签: c# unity3d


【解决方案1】:

代码太复杂了,你只是在某个地方犯了无数个简单的错误

按照正常调试。

首先要改变这个

yield return new WaitForSeconds(pd.dashCooldown); 

到这里

Debug.Log("test with number");
yield return new WaitForSeconds(20f);
Debug.Log("tested with number"); 

然后从那里出发。

顺便说一句,FixedUpdate() 出了点问题。出于某种原因,您每一帧都被称为 Dash(和其他人)。这似乎完全错误。你会在按键按下时调用那种东西一次

另外:

你可能已经遭受了这个 Gotchya:

https://stackoverflow.com/a/35166004/294884

由于所有奇异的变量。

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    相关资源
    最近更新 更多