c# – 最后用缓和来回摇动一个物体?

我几乎想要一个刺耳的动画,这样它会快速地来回摇晃一秒钟,然后放慢速度,慢慢回到正常位置.只有持续摇晃有很多答案,但我怎么能减少震动呢?我会Lerp真的很快,还是使用PingPong的功能会减慢?

解决方法

你只需通过获取原始位置然后在协程函数中简单地摇动GameObject,做YourObjTransform.position = defaultPos UnityEngine.Random.insideUnitSphere * shakeAmount;在一段时间内循环一段时间.摇动GameObject后,将值重置回其认位置.

至于减少震动,你做shakeAmount = Time.deltaTime;在while循环中.这将降低while循环中的摇动速度.

以下函数是上述语句的完整示例.它需要三个参数,GameObject摇动,摇动GameObject多长时间以及开始减少震动的时间.

例如,如果你将myGameOBject,5f,3f传递给该函数,它将摇动myGameOBject,总时间为5秒.在摇动myGameOBject并且计数器达到3时,它将开始降低摇动的速度(shakeAmount),直到计时器达到5.

如果要抖动的GameObject是SpriteRender,则将true传递给最后一个参数,以便z轴不会移动,并且在摇动时它只会在Z轴上旋转.

public GameObject GameObjectToShake;
bool shaking = false;

IEnumerator shakeGameObjectCOR(GameObject objectToShake,float totalShakeDuration,float decreasePoint,bool objectIs2D = false)
{
    if (decreasePoint >= totalShakeDuration)
    {
        Debug.LogError("decreasePoint must be less than totalShakeDuration...Exiting");
        yield break; //Exit!
    }

    //Get Original Pos and rot
    Transform objTransform = objectToShake.transform;
    Vector3 defaultPos = objTransform.position;
    Quaternion defaultRot = objTransform.rotation;

    float counter = 0f;

    //Shake Speed
    const float speed = 0.1f;

    //Angle Rotation(Optional)
    const float angleRot = 4;

    //Do the actual shaking
    while (counter < totalShakeDuration)
    {
        counter += Time.deltaTime;
        float decreaseSpeed = speed;
        float decreaseAngle = angleRot;

        //Shake GameObject
        if (objectIs2D)
        {
            //Don't Translate the Z Axis if 2D Object
            Vector3 tempPos = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
            tempPos.z = defaultPos.z;
            objTransform.position = tempPos;

            //Only Rotate the Z axis if 2D
            objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-angleRot,angleRot),new Vector3(0f,0f,1f));
        }
        else
        {
            objTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
            objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-angleRot,new Vector3(1f,1f,1f));
        }
        yield return null;


        //Check if we have reached the decreasePoint then start decreasing  decreaseSpeed value
        if (counter >= decreasePoint)
        {
            Debug.Log("Decreasing shake");

            //Reset counter to 0 
            counter = 0f;
            while (counter <= decreasePoint)
            {
                counter += Time.deltaTime;
                decreaseSpeed = Mathf.Lerp(speed,counter / decreasePoint);
                decreaseAngle = Mathf.Lerp(angleRot,counter / decreasePoint);

                Debug.Log("Decrease Value: " + decreaseSpeed);

                //Shake GameObject
                if (objectIs2D)
                {
                    //Don't Translate the Z Axis if 2D Object
                    Vector3 tempPos = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
                    tempPos.z = defaultPos.z;
                    objTransform.position = tempPos;

                    //Only Rotate the Z axis if 2D
                    objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-decreaseAngle,decreaseAngle),1f));
                }
                else
                {
                    objTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed;
                    objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-decreaseAngle,1f));
                }
                yield return null;
            }

            //Break from the outer loop
            break;
        }
    }
    objTransform.position = defaultPos; //Reset to original postion
    objTransform.rotation = defaultRot;//Reset to original rotation

    shaking = false; //So that we can call this function next time
    Debug.Log("Done!");
}


void shakeGameObject(GameObject objectToShake,float shakeDuration,bool objectIs2D = false)
{
    if (shaking)
    {
        return;
    }
    shaking = true;
    StartCoroutine(shakeGameObjectCOR(objectToShake,shakeDuration,decreasePoint,objectIs2D));
}

void Start()
{
    shakeGameObject(GameObjectToShake,5,3f,false);
}

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...