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