Unity2D 使用协程来跟踪玩家何时转动?

Posted

技术标签:

【中文标题】Unity2D 使用协程来跟踪玩家何时转动?【英文标题】:Unity2D using coroutines for tracking when the player is turning? 【发布时间】:2021-09-15 03:07:50 【问题描述】:

我正在使用骨骼为玩家设置动画。当玩家转身时,我有 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;

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

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

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

所以我的问题是:

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

【问题讨论】:

在第一个 sn-p 中,您还可以检查当前的 scale.x,如果与您要分配的不同,则触发旋转协程。 【参考方案1】:

[EDIT] 按照@Everts 的建议,使用当前的本地比例作为计算方向变化的基础。

如果localscale.x &lt; 0movement &gt; 0 那么我们可以推测玩家想要转身(对于这个人为的例子)。 localscale.x &gt; 0movement &lt; 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);
      
  

【讨论】:

以上是关于Unity2D 使用协程来跟踪玩家何时转动?的主要内容,如果未能解决你的问题,请参考以下文章

Day794.如何用协程来优化多线程业务 -Java 性能调优实战

通过在 Python 中等待协程来设置类属性

Unity2D - 验证 isGround 是不是正确

Unity2D-当玩家被击中时如何在摧毁它们后恢复心

Unity入门计划Unity2D动画-脚本与混合树实现玩家角色动画过渡

一种Unity2D多分辨率屏幕适配方案