提问人:Sewiwey 提问时间:9/3/2023 最后编辑:derHugoSewiwey 更新时间:9/4/2023 访问量:42
Unity 2D 输入操作未释放
Unity 2D Input Action not releasing
问:
我正在尝试使用 Unity 的新输入系统为平台游戏添加可变跳跃高度。由于我正在尝试集成有限状态机框架,因此我正在使用 Send Messages 行为读取输入。若要添加可变跳转高度,请在按下跳转操作时以空闲状态调用以下函数:
public void Jump(InputAction jumpAct)
{
float jumpCount = 10f;
if (jumpAct.WasPressedThisFrame())
{
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
}
while (jumpCount > 0f)
{
if (jumpAct.WasReleasedThisFrame() && rb.velocity.y > 0f)
{
Debug.Log("Yay");
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
} else
{
Debug.Log(jumpAct.ReadValueAsObject());
}
jumpCount -= Time.deltaTime;
}
}
似乎即使我释放按钮,InputValue 仍注册为 On(第二个 if 语句总是失败,调试器为 jumpAct 值打印值 1)。尽管查看了文档和不同的论坛,但不知道为什么会发生这种情况。一些帮助将不胜感激。
额外说明:我知道一个事实,这可以通过使用调用 Unity Events 行为中的回调上下文来修复。但是,理想情况下,有一个使用“发送消息”行为的解决方案,否则我需要重写我编码的 FSM 框架的很大一部分。
试过 WasReleasedThisFrame(), !IsPressed() 和 !WasPressedThisFrame()。尝试过在字符组件上的 InputAction 中添加和删除触发器。尝试直接使用 ReadValueAsObject() 读取 InputValue,而不是检查上述方法。结果保持不变。有一个跳跃,但无论何时松开按钮,高度都是均匀的。
额外的更新。我找到了一种方法来读取操作的回调上下文阶段。在整个过程中,此阶段被读取为“已执行”,即使释放按钮也是如此。
答:
你的整个循环将在一帧内执行,你的释放条件永远无法满足,除非你真的如此快速地粉碎和释放按钮,以至于它在同一帧内被按下和释放。while
假设你无论如何都在每一帧调用这个方法,例如 from - 否则你只会使用事件驱动的方法 - 你一次只需要处理一个帧,例如Update
private float jumpCount = 10f;
public void Jump(InputAction jumpAct)
{
if (jumpAct.WasPressedThisFrame())
{
jumpCount = 10f;
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
}
// NOTE: "if" instead of "while" -> only one single execution at a time
if(jumpCount > 0f)
{
jumpCount -= Time.deltaTime;
if (jumpAct.WasReleasedThisFrame() && rb.velocity.y > 0f)
{
Debug.Log("Yay");
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
else
{
Debug.Log(jumpAct.ReadValueAsObject());
}
}
}
无论如何,我可能仍然会使用事件驱动的方法,并做一些类似的事情,例如
// in your state enter method
YourActionMap.jump.performed += StartJump;
YourActionMap.jump.canceled += StopJump;
// accordingly in your state exit method
YourActionMap.jump.performed -= StartJump;
YourActionMap.jump.canceled -= StopJump;
然后
private float jumpStartTime;
private void StartJump(InputAction.CallbackContext context)
{
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
jumpStartTime = Time.time;
}
private void StopJump(InputAction.CallbackContext context)
{
if(Time.time - jumpStartTime <= 10f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
}
评论
while