【问题标题】:Unity 2D IEnumerator not working / processing the WaitForSecondsUnity 2D IEnumerator 不工作/处理 WaitForSeconds
【发布时间】:2022-10-05 15:26:19
【问题描述】:

[更新] 这是我正在使用的代码。这是我的更新方法中的 if(Enemy != Chasing) 中的一个。

此代码指定让敌人选择 90、180、-90、360 的设定旋转,然后朝该方向移动一段时间。然后再做一遍。但是当我运行它时,它所做的就是

    private IEnumerator RomeCO() {
        int MovePick = Random.Range(1, 4);
        
        yield return new WaitForSecondsRealtime(1)

        switch (MovePick)
        {
            case 1:
            // TODO 
            // turn / face 0 for up
            Rb.SetRotation(0);
            yield return new WaitForSecondsRealtime(1);
            // give movement in that dirrection
            transform.Translate(new Vector2(0f, 1f) * EnemySpeed * Time.deltaTime); // up

            break;

            case 2:
            // TODO 
            // turn / face 180 for down 
            Rb.SetRotation(180);
            yield return new WaitForSecondsRealtime(1);
            // give movement in that dirrection
            transform.Translate(new Vector2(0f, -1f) * EnemySpeed * Time.deltaTime); // down
            break;

            case 3:
            // TODO 
            // turn / face 90 for left
            Rb.SetRotation(90);
            yield return new WaitForSecondsRealtime(1);
            // give movement in that dirrection
            transform.Translate(new Vector2(-1f, 0f) * EnemySpeed * Time.deltaTime); // left 
            
            break;

            case 4:
            // TODO 
            // turn / face -90 for right
            Rb.SetRotation(-90);
            yield return new WaitForSecondsRealtime(1);
            // give movement in that dirrection
            transform.Translate(new Vector2(1f, 0f) * EnemySpeed * Time.deltaTime); // right
            break;
        }


        GetComponent<Rigidbody2D>().velocity = Vector2.zero;
        GetComponent<Rigidbody2D>().angularVelocity = 0.0f;

    


    }

  • 使用 RectTransform 移动 2D 对象(图像、按钮等)。 var rectTr = GetComponent&lt;RectTransform&gt;(); 并使用 anchoredPosition 移动。
  • 所以你的说法也适用于二维精灵?
  • 好的,所以我尝试了它并且它有效,但我尝试使用翻译的原因是它是从一个点到另一个点的平稳过渡。我怎样才能添加同样的效果?
  • RectTransform 还有一个 Translate 函数。
  • 我该如何使用它?我一直在努力。。

标签: c# unity3d


【解决方案1】:

如 cmets 中所述,您观察到小平移的原因是您乘以最后一帧的时间(在 60fps 下,这相当于 ~0.016.

仅乘以 Time.deltaTime 不会使参数具有动画效果。有多种方法可以使值从一个转换到另一个,您可以启动一个协程,您可以在标志出现时在 Update 中对其进行动画处理,或者当目标值与当前值不同时,或者使用 LeanTween / DoTween 等插件。

【讨论】:

    【解决方案2】:

    首先,您在 Start 中做事,这被称为一次.

    您宁愿将其放入每帧重复调用的Update


    然后你的第一次尝试

    flaot RandomXmin = Random.Range(1, 2) 
    transform.position = new Vector3(RandomXmin, 0) * Time.deltaTime;
    

    会将您的对象硬设置到具有RandomXmin * Time.deltaTime, 0, 0 的位置。其中RandomXmin12Time.deltaTime 之间的某个浮点值,基本上是自上一帧以来经过的时间。在Start 内无论如何都有无效值,但通常会非常小。 (例如 60 fps => 1/60 = 0.001666..)

    而第二个

    transform.Translate(Vector3.up * 2 * Time.deltaTime);
    

    已经更适合以每秒2 个单位的恒定速度向上移动您的对象.. 但是您仍然只调用它一次。


    所以这取决于你,但你可能会做类似的事情,例如

    private void Update()
    {
        transform.Translate(Vector3.up * 2 * Time.deltaTime);
        // basically equals
        //transform.localPosition += Vector3.up * 2 * Time.deltaTime;
    }
    

    更新:

    解决您的实际用例

    我希望我的游戏对象选择像 90,180,360 这样的旋转。然后等待一段时间。然后在那个方向上移动一段随机距离。

    我宁愿使用一个例程,例如

    [Header("References")]
    [SerializeField] private Rigidbody rigidbody;
    
    [Header("Settings")]
    [SerializeField] private float minDistance;
    [SerializeField] private float maxDistance;
    [SerializeField] private float delayBeforeMove;
    [SerializeField] private float moveSpeed;
    
    private void Start()
    {
        StartCoroutine(RoamRoutine());
    }
    
    private IEnumerator RoamRoutine()
    {
        while (true)
        {
            // chose random direction
            // NOTE: he upper bound of the int version of Random.Range is exclusive!
            // This will return values from 0 to 3
            var randomAngle = Random.Range(0, 4) * 90;
    
            // so this will be a rotation to either 0, 90, 180 or 270
            var targetRotation = Quaternion.Euler(0, randomAngle, 0);
    
            // important: since you deal with physics wait for the next physics routine
            yield return new WaitForFixedUpdate();
    
            // set the rotation
            rigidbody.MoveRotation(targetRotation);
    
            // your desired delay between setting rotation and start to move
            yield return new WaitForSecondsRealtime(delayBeforeMove);
            yield return new WaitForFixedUpdate();
    
            // pick random distance
            var randomDistance = Random.Range(minDistance, maxDistance);
            var targetPosition = rigidbody.position + rigidbody.rotation * Vector3.forward * randomDistance;
    
            while (rigidbody.position != targetPosition)
            {
                rigidbody.MovePosition(Vector3.MoveTowards(rigidbody.position, targetPosition, moveSpeed * Time.deltaTime));
    
                yield return new WaitForFixedUpdate();
            }
    
            rigidbody.MovePosition(targetPosition);
        }
    }
    

    【讨论】:

    • 所以我把它放在 start 的原因是为了测试。我不能把它放在更新 bc 它是一个协程。在它等待一次之后,它就再也不会等待了。它只会运行一次 WaitForSeconds(//) 或任何你放在那里的东西。 iv 也厌倦了一些事情。但没有什么真正奏效。我对协程不太熟悉,但我想相信我明白了它的要点。
    • 我想要协程的原因是我想要的某种行为运动。它是人工智能思考然后转向的地方。然后等待。然后移动。然后停下来。等待。冲洗冲洗并重复。并且通过协程,我可以使用 yield return new WaitForSeconds(//) 来获得我想要的行为。我只是想不通为什么如果我把它放在更新中它只能正确运行一次然后甚至不处理 WaitForSeconds(//),这只是随机和快速的移动。
    • 然后循环? while(true){ ... yield return XY; } ...如果您想获得有关具体实施的帮助,请在您的问题中发布完整的代码;)
    • 但是我怎样才能等待几秒钟才能工作。正如我之前所说,我不能在更新方法中放置协程,因为等待秒数只会运行一次。所以即使开始我怎么能解决这个问题?
    • 如前所述,分享您的完整代码.. 目前很难知道您的实际目标...
    猜你喜欢
    • 1970-01-01
    • 2015-06-14
    • 2019-10-27
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多