首页 > 解决方案 > 如何制作简单的空闲摆动动作/动画?

问题描述

准备看看一些非常丑陋的代码。

所以基本上我想做的是为一个统一的 3d 对象创建一个简单的上下摆动运动,它在下降时变得更快,然后在上升时减慢速度。我下面的代码实现了这种效果,但我知道必须有一种更好、更优雅的方法,我只是找不到。

public class IdleAnimation : MonoBehaviour
{
    public float rotSpeed = 3.0f;
    public float minimum = 0.1f;
    public float maximum = 0.5f;
    public float yPos;

    public float bounceProgress = 0;
    public float initBounceSpeed = 0.001f;
    private float bounceSpeed;
    public float bounceAcc = 0.002f;
    public float dir = 1;

    // Start is called before the first frame update
    void Start()
    {
        bounceSpeed = initBounceSpeed;
    }

    // Update is called once per frame
    void Update()
    {
        //interpolates between the minimum and maximum based on the bounceProgress
        yPos = Mathf.Lerp(minimum, maximum, bounceProgress);
        transform.position = new Vector3(transform.position.x, yPos, transform.position.z);

        //bounceProgress increases/decreases by the bounceSpeed
        bounceProgress += bounceSpeed * dir;
        //bounceSpeed increases/decreases by the bounceAcc
        bounceSpeed += bounceAcc * dir;

        //once the bounceProgress reaches 1, the direction reverses
        //note that it will be going at maximum speed here
        if(bounceProgress > 1)
            dir = -1;
        //once the bounceProgress reaches 0, the direction reverses
        //note that it will be going at minimum speed here
        else if (bounceProgress < 0)
        {
            dir = 1;
            //resets bounceSpeed to avoid going into a negativeSpeed
            bounceSpeed = initBounceSpeed;
        }
    }
}

我觉得必须有更好的方法来使用 Mathf.PingPong 或 Mathf.SmoothStep 或类似的东西,我就是想不通。任何和所有的建议表示赞赏

标签: c#unity3d

解决方案


感谢 Abion47 的帮助,我发现 Mathf.Sin 正是我所需要的。

public class IdleAnimation : MonoBehaviour
{
    public float rotSpeed = 3;
    private float minimum = 0.1f;
    private float maximum = 0.5f;

    private float yPos;
    private float bounceSpeed = 3;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        float sinValue = Mathf.Sin(Time.time * bounceSpeed);

        yPos = Mathf.Lerp(maximum, minimum, Mathf.Abs(sinValue));
        transform.position = new Vector3(transform.position.x, yPos, transform.position.z);

        //Rotate
        transform.Rotate(Vector3.up, Time.deltaTime * rotSpeed);

    }

推荐阅读