Unity 运行动画重复播放。

huangapple go评论85阅读模式
英文:

Unity running animations repeatedtly

问题

使用铰链关节附着的二维项目中,我创建了这个脚本,但我对枚举器不太熟悉。我尝试运行一个动画,使玩家在施加力的同时奔跑。但出现了一个问题,MoveLeft 枚举器一直在运行。我打印了它是否从函数运行或动画是否默认播放,但实际上是从函数中播放的。

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour
{
    
    public GameObject leftLeg;
    public GameObject rightLeg;
    Rigidbody2D leftLegRB;
    Rigidbody2D rightLegRB;

    Animator anim;

    [SerializeField] float speed = 2f;
    [SerializeField] float jumpHeight = 2f;
    [SerializeField] float legWait = .5f;

    // Start is called before the first frame update
    void Start()
    {
        leftLegRB = leftLeg.GetComponent<Rigidbody2D>();
        rightLegRB = rightLeg.GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        IEnumerator MoveRight(float seconds)
        {
            float endTime = Time.time + seconds;
            Debug.Log("向右移动");

            while (Time.time < endTime)
            {
                leftLegRB.velocity = new Vector2(speed, leftLegRB.velocity.y);
                rightLegRB.velocity = new Vector2(speed, rightLegRB.velocity.y);
                yield return null;
            }
        }

        IEnumerator MoveLeft(float seconds)
        {
            float endTime = Time.time + seconds;
            Debug.Log("向左移动");

            while (Time.time < endTime)
            {
                leftLegRB.velocity = new Vector2(-speed, leftLegRB.velocity.y);
                rightLegRB.velocity = new Vector2(-speed, rightLegRB.velocity.y);
                yield return null;
            }
        }
        
        if (Input.GetAxisRaw("Horizontal") != 0)
        {
            if (Input.GetAxis("Horizontal") > 0)
            {
                anim.Play("Run");
                StartCoroutine(MoveRight(legWait));
            }
            else if (Input.GetAxis("Horizontal") < 0)
            {
                anim.Play("Run");
                StartCoroutine(MoveLeft(legWait));
            }
        }
        else if (Input.GetAxisRaw("Horizontal") == 0)
        {
            anim.Play("Idle");
        }
 
        if (Input.GetKeyDown(KeyCode.Space))
        {
            leftLegRB.AddForce(Vector2.up * (jumpHeight*1000));
            rightLegRB.AddForce(Vector2.up * (jumpHeight * 1000));
        }
    }
}

空闲动画保持腿部在0位置,但不起作用。不,不是卡键。还有一个平衡脚本,选择腿和躯干的角度,但没有运动脚本,它运行正常。


<details>
<summary>英文:</summary>
I have a 2D project with a stickman attached with hinge joints. I created this script and I am not really  familiar with Enumerators. I am trying to run an animation to make the player run while adding force. And for some reason the MoveLeft Enumerator keeps on running. I printed if it ran the function or the animation was on by default but it did in fact play it from the function.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Movement : MonoBehaviour
{

public GameObject leftLeg;
public GameObject rightLeg;
Rigidbody2D leftLegRB;
Rigidbody2D rightLegRB;
Animator anim;
[SerializeField] float speed = 2f;
[SerializeField] float jumpHeight = 2f;
[SerializeField] float legWait = .5f;
// Start is called before the first frame update
void Start()
{
leftLegRB = leftLeg.GetComponent&lt;Rigidbody2D&gt;();
rightLegRB = rightLeg.GetComponent&lt;Rigidbody2D&gt;();
anim = GetComponent&lt;Animator&gt;();
}
// Update is called once per frame
void Update()
{
IEnumerator MoveRight(float seconds)
{
float endTime = Time.time + seconds;
Debug.Log(&quot;Moved Right&quot;);
while (Time.time &lt; endTime)
{
leftLegRB.velocity = new Vector2(speed, leftLegRB.velocity.y);
rightLegRB.velocity = new Vector2(speed, rightLegRB.velocity.y);
yield return null;
}
}
IEnumerator MoveLeft(float seconds)
{
float endTime = Time.time + seconds;
Debug.Log(&quot;Moved Left&quot;);
while (Time.time &lt; endTime)
{
leftLegRB.velocity = new Vector2(-speed, leftLegRB.velocity.y);
rightLegRB.velocity = new Vector2(-speed, rightLegRB.velocity.y);
yield return null;
}
}
if (Input.GetAxisRaw(&quot;Horizontal&quot;) != 0)
{
if (Input.GetAxis(&quot;Horizontal&quot;) &gt; 0)
{
anim.Play(&quot;Run&quot;);
StartCoroutine(MoveRight(legWait));
}
else if (Input.GetAxis(&quot;Horizontal&quot;) &lt; 0)
{
anim.Play(&quot;Run&quot;);
StartCoroutine(MoveLeft(legWait));
}
}
else if (Input.GetAxisRaw(&quot;Horizontal&quot;) == 0)
{
anim.Play(&quot;Idle&quot;);
}
if (Input.GetKeyDown(KeyCode.Space))
{
leftLegRB.AddForce(Vector2.up * (jumpHeight*1000));
rightLegRB.AddForce(Vector2.up * (jumpHeight * 1000));
}
}

}


The idle animation keeps the legs at 0 but just doesn&#39;t work. No, it&#39;s not a key that stuck down. Their is also a balance script which selects the angle of the legs and torso but without the movement script it works fine.
</details>
# 答案1
**得分**: 1
你在开始协程,但从未停止它们。在这个代码块中,你还应该调用StopAllCoroutines(或将每个协程保存到变量中并手动停止它们,这将更方便):
```csharp
else if (Input.GetAxisRaw("Horizontal") == 0)
{
anim.Play("Idle");
}

但这也是一种非常奇怪的通过腿部刚体来实现角色动画和移动的方式...也许你应该考虑为角色使用一个单独的刚体,以及一种正常的动画方式,比如使用AnimationController和AnimationClips(它们不难理解,比通过物理来处理动画要可靠得多)。

英文:

You're starting coroutines, but never stopping them. In this block you should also call StopAllCoroutines (or save each routine into variable and stop them manually, that will be more convenient):

else if (Input.GetAxisRaw(&quot;Horizontal&quot;) == 0)
{
anim.Play(&quot;Idle&quot;);
}

But it's also a very strange way to animate and move character via leg rigidbodies... Maybe you should consider using a single Rigidbody for the character and a normal way to do animations, like using AnimationController and AnimationClips (they aren't that hard to understand and much more reliable than dealing with animation through physics).

huangapple
  • 本文由 发表于 2023年6月26日 06:35:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552671.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定