2016-09-08 2 views
1

나는 거의 흔들리지 않는 애니메이션을 원한다. 잠시 동안 빠르게 흔들 리다가 다시 느려지고 원래의 위치로 되돌아 간다. 떨리는 것을 계속하는 것에 대한 답이 많습니다. 그러나 나는 그 흔들림을 어떻게 줄일 것입니까? Lerp이 정말 빠르지 않습니까? 아니면 느려지는 기능이있는 PingPong을 사용합니까?끝을 가볍게하면서 물건을 앞뒤로 흔 듭니다.

+0

어떤 유형의 게임 객체입니까? UI 구성 요소, 메쉬 렌더러 또는 스프라이트 렌더러? – Programmer

+0

스프라이트 렌더러가 구체적이지만 전체 GameObject를 움직일 수 있습니까? – GMR516

+0

가능합니다. 나는 잠시 답을 줄 것이다 – Programmer

답변

3

당신은 단순히 단순히 코 루틴 함수에서 다음 원래 위치를 얻어서으로 게임 오브젝트를 흔들 수, 특정 시간 동안 루프에서 YourObjTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * shakeAmount;을한다. GameObject를 흔들면 값을 기본 위치로 다시 설정하십시오.

흔들림을 줄이려면 while 루프에서 shakeAmount += Time.deltaTime;을 수행하십시오. 이렇게하면 while 루프의 흔들림 속도가 감소합니다.

아래 함수는 위의 문장의 전체 예제입니다. 흔들리는 GameObject, GameObject를 얼마나 오랫동안 흔들어야하는지, 그리고 흔들리는 시간을 줄이기위한 세 가지 매개 변수가 필요합니다. 당신이 함수에 myGameOBject, 5f, 3f에 전달하면

예를 들어, 그것은 5초의 총 시간 동안 myGameOBject를 흔들 것입니다. myGameOBject을 흔들고 카운터가 3에 도달하면 타이머가 5에 도달 할 때까지 흔들림의 속도가 감소하기 시작합니다 (shakeAmount).

악수 할 GameObject가 SpriteRender 인 경우 마지막 매개 변수에 패스하면 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, 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, 0, counter/decreasePoint); 
       decreaseAngle = Mathf.Lerp(angleRot, 0, 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), new Vector3(0f, 0f, 1f)); 
       } 
       else 
       { 
        objTransform.position = defaultPos + UnityEngine.Random.insideUnitSphere * decreaseSpeed; 
        objTransform.rotation = defaultRot * Quaternion.AngleAxis(UnityEngine.Random.Range(-decreaseAngle, decreaseAngle), new Vector3(1f, 1f, 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, float decreasePoint, bool objectIs2D = false) 
{ 
    if (shaking) 
    { 
     return; 
    } 
    shaking = true; 
    StartCoroutine(shakeGameObjectCOR(objectToShake, shakeDuration, decreasePoint, objectIs2D)); 
} 

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

와우, 이건 정말 대단해! 최대한 빨리 확인해보고 작동하는지 알려 드리겠습니다. 다시 한번 감사드립니다. – GMR516

+0

흔들기가 너무 많은 경우'speed' 및'angleRot' 변수를 줄일 수 있습니다. 떨림이 개체를 조금 회전시키기 때문에 더 사실적인 회전을 포함합니다. 이것은 큐브 (3D)로 테스트됩니다. 스프라이트 같은 2D 오브젝트를 사용하려면 약간 수정하고 z 축이 변경되지 않도록해야합니다. 그렇게하는 것은 매우 간단합니다. 2D 오브젝트에서 회전 코드를 필요로하지 않으므로 회전 코드에 주석을 달아야합니다. – Programmer

+0

그래, 확실히 2D 프로젝트로 작업 할 수 있도록 약간 수정할 것입니다. 너무 커스터마이징 한 것은 정말 멋지 네요. – GMR516

0

댐핑 효과가있는 cos/sin 함수를 살펴보십시오.

A*Pow(e, -bt/2)*cos(f*t)