본문 바로가기
유니티/기초

유니티 오브젝트 회전 [기초 2]

by 노튜 2020. 5. 4.
728x90

유니티 오브젝트 회전에 관한 글입니다.

 

유니티 오브젝트의 회전은 월드 기준과 로컬 기준이 있습니다.

 

 

transform.rotation은 월드 기준으로 회전을 하고, 

transform.rotate()은 로컬(오브젝트) 기준으로 회전합니다. 

유니티 오브젝트의 회전은 Quaternion(사원수)을 사용합니다.

 

1.  회전 방향을 입력 받아 회전 

 

회전하고자 하는 Vector3 값을 입력받아,  회전축을 기준으로 각도를 계산합니다.

 

float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

 

Mathf.Atna2( y, x )의 값은 각을 나타내는 단위 중 하나인 radian 값으로 반환됩니다.

이를 우리가 흔히 알고 있는 Degree(도)로 바꾸어주기 위해 Mathf.Rad2Deg를 곱하여 준다.

Mathf.Rad2Deg의 곱은 +-180 사이의 값을 반환한다. 

 

나온 값은 오일러(Euler) 공식을 이용해 실제 회전하고자 하는 회전값을 얻는다. 

 

회전하고자하는 방향으로 오브젝트의 회전을 즉시 합니다.

transform.rotation = Quaternion.Euler(x,y,z,w);

 

오브젝트의 회전을 time동안 부드러운 회전을 합니다. 

transform.rotation =
		Quaternion.Slerp(Quaternion from, Quaternion to, float time);

2D 회전은 Z축 회전

3D 회전은 Y축 회전 

 

public class movement : MonoBehaviour 
{
   // TwoD : 2D회전 , ThreeD : 3D회전
   public enum RotateType{TwoD, ThreeD};
   public RotateType rotateType;
   
   // slerp 회전속도
   public float rotateSpeed = 5.0f;
	
  void Update()
  {
    switch(rotateType)
    {
      case RotateType.TwoD: Rotate2D(); break;
      case RotateType.ThreeD: Rotate3D(); break;
    }

  }
  
  void Rotate3D()
  {
    // 방향키
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");
    
    Vector3 dir = new Vector3(h, 0.0f, v);
    
    if(dir != Vector3.zero)
    {
      float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
      //  transform.rotation = Quaternion.Euler(0.0f, angle, 0.0f);
      transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0.0f, angle, 0.0f), rotateSpeed * Time.deltaTime);
    }   
  }
  
  void Rotate2D()
  {
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");
    
    Vector3 dir = new Vector3(h, v, 0.0f);
    
    if(dir != Vector3.zero)
    {
      float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
      //  transform.rotation = Quaternion.Euler(0.0f, 0.0f, angle);
      transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0.0f, 0.0f, angle), rotateSpeed * Time.deltaTime);
    }   
  }

}

 

2. Between Two Vectors

 

오브젝트의 위치에서 대상 오브젝트의 위치를 빼, 두 오브젝트 사이의 벡터 값을 구한다. 

target postion - transfrom.position

 

public class Rotation : MonoBehaviour
{
  public Vector3 targetPosition;
  
  void Update()
  {
     Vector3 direction = targetPosition - transform.postion;
     
     // two axis
     //float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
     
     // three axis
     float angle = Vector3.Angle(direction, transform.forward);
      
     transform.rotation = Quaternion.Euler(0, angle, 0);
  }
  
}

 

728x90