首页 > 解决方案 > Unity2D 使用协程跟踪玩家何时转动?

问题描述

我正在使用骨骼为玩家设置动画。当玩家转身时,我有 3 个基本骨架可以转换:

要面向左侧或右侧,渲染器只需使用以下方式渲染镜像:

if (movement > 0) transform.localScale = new Vector2(1f, 1f);
if (movement < 0) transform.localScale = new Vector2(-1f, 1f);

然而,捕捉玩家从右向左移动(反之亦然)的中间状态被证明是棘手的。

我设置了 3 个渲染器来操作如下:

void Start()
  {
    rightRenderer.enabled = true;
    turningRenderer.enabled = false;
    centerRenderer.enabled = false;
  }

我一直在假设可以使用协程来测量Input.GetAxis("Horizontal");从左到右(反之亦然)的运动。因此,我围绕以下内容进行了各种实验:

  private List<float> trackedMovement = new List<float>();
  private bool isTurning;
  private float speed = 0f;
  private int turningCounter = 0;

  public IEnumerator countdownTurn()
  {
    while (0 < turningCounter--)
    {
      if (turningCounter == 0)
      {
        StopCoroutine("countdownTurn");
        break;
      }
      yield return new WaitForSeconds(0.2f);
    }
  }

  public IEnumerator turn()
  { // speed can be between 0 and 2.5f;
    if (speed > 0 && speed <= 0.5f)
    {
      while (speed != 0)
      {
        trackedMovement.Add(movement);
        trackedMovement.ForEach(f =>
        {
          if (
            ((f > 0 && movement < 0) ||
            (f < 0 && movement > 0)))
          {
            isTurning = true;
            trackedMovement = new List<float>();
            turningCounter = 5;
            StartCoroutine("countdownTurn");
          }
        });
        yield return new WaitForSeconds(0.02f);
      }
    }
  }

  void Update()
  {
    StartCoroutine("turn");
    speed = defaultAnimator.GetFloat("Speed");
    turn();
  }

我脑海中的理论是turningCounter可以通过数字来展示玩家的状态

假设我从左向右移动:

turningCounter = 4玩家从左转向相机。

rightRenderer.enabled = false;
turningRenderer.enabled = true;
centerRenderer.enabled = false;

turningCounter = 3 || 2玩家正对着镜头。

rightRenderer.enabled = false;
turningRenderer.enabled = false;
centerRenderer.enabled = true;

turningCounter = 1玩家正在从相机转向右侧配置文件。

rightRenderer.enabled = false;
turningRenderer.enabled = true;
centerRenderer.enabled = false;

turningCounter = 0玩家完全面向右侧。

rightRenderer.enabled = true;
turningRenderer.enabled = false;
centerRenderer.enabled = false;

我所有的实验都产生了不一致的结果。

如果我将渲染器例程放在 sub-coroutinecountdownTurn中,它们并不总是在玩家向左/向右转时触发。

如果我尝试在任何更新语句中测量转动计数器(我尝试了标准、固定和默认但没有多大成功)我得到关于 turningCounter 值的过时反馈(即它有时给我一些倒计时但不是所有倒计时)。

所以我的问题是:

协程是解决这个问题的最好方法吗?如果是这样,对于我如何从他们那里获得干净且一致的转向计数器值有什么建议吗?如果协程不是一个好的解决方案,人们是否采取了其他方法来创建所需的结果?

标签: c#unity3dcoroutine

解决方案


[编辑] 正如@Everts 建议的那样,使用当前的本地比例作为计算方向变化的基础。

如果localscale.x < 0然后movement > 0我们可以推测玩家想要转身(对于这个人为的例子)。localscale.x > 0对于和也是如此movement < 0

因此我们能够起草以下更新(我在这里附上一个简化版本,忽略了蹲伏机制等内容):

void Update()
  {
      movement = Input.GetAxis("Horizontal");
      if (((transform.localScale.x > 0 && movement < 0) ||
      (transform.localScale.x < 0 && movement > 0))
      && !isTurning)
      {
        isTurning = true;
        turningCounter = 5;
        StartCoroutine("countdownTurn"); // simply ticks down turningCounter every 0.n seconds
      }

      if (turningCounter == 3) setRenderDirection(); // ie. routine for transforming localscale (mirroring the image)

      // show player in profile at end of counter
      profileRenderer.enabled = turningCounter < 1;
      // show player turning towards camera on 4 and away from camera on 1
      turningRenderer.enabled = turningCounter == 4 || turningCounter == 1;
      // show player looking dead center for 2 counts
      centerRenderer.enabled = turningCounter == 2 || turningCounter == 3;

      if (turningCounter < 1)
      {
        isTurning = false;
        defaultAnimator.SetBool("isTurning", false);
      }
  }

推荐阅读