Unity

[Unity][개념,방법] 오브젝트 이동 (Vector, Normalized, Magnitude)

usingsystem 2022. 10. 4. 15:12
728x90

Vector는 사용에 따라 위치와 방향 두 가지를 표현할 수 있다.

크기 공식
Length  = sqrt( X*X + Y*Y + Z*Z )

방향(Normalize) 공식
Normalize  = (X / sqrt(Length), Y / sqrt(Length), Z / sqrt(Length))

 

로컬포지션과 월드포지션 변환

  • Word포지션 -> Local포지션 && Local포지션 -> Word포지션 변환

TransformDirection -  word포지션에서 local포지션으로 변경할 경우

//Local -> Word
transform.TransformDirection(Vector3.forward);

//Word -> Local
transform.InverseTransformDirection(Vector3.forward)

Vector이동

  • Translate 
    • 현 위치에서 new vector만큼 이동시킨다.
transform.Translate( new Vector2(1,1) * Time.deltaTime)

Magnitude

Magnitude는 Vector3의 길이혹은 크기를 반환한다. 

이렇게 구한 길이를 통해 두 좌 표 사이의 거리를 구하거나 물체의 속력을 구할 수 있다.

(목적지 - 현재위치).magnitude = 남은 거리

 

  • 두 좌 표 사이의 거리
    • 두좌표 사이의 거리를 통해 근접했을 때 이벤트를 발생시킬 수 있다.
Vector3 dir = destPos - transform.position;
float distance = dir.magnitude
float distance = Vector3.Distance(objTransform.position, destPos);

 

유니티에서 Distance를 만들어놔서 따로 magnitude를 사용하여 만들지 않아도 된다.

  • 속도 구하기
int time = 1;
Vector3 dir = destPos - transform.position;
float distance = dir.magnitude
float speed = distance / time
int time = 1;
float distance = Vector3.Distance(objTransform.position, destPos);
float speed = (distance / tiem);

Nomalized

Nomalized는 Vector3의 방향을 정규화한다. 즉 방향을 구할 수 있다.

이렇게 구한 방향으로 일정한 속도로 같은 방향으로 이동할 수 있다.

Nomalized는  단위벡터로 단위벡터란 크기가 1이고 방향을 갖는 벡터를 말한다.

(목적지 - 현재위치).nomalized = 정규화된 이동할 방향

Vector3 direct = (destPos - transform.position).normalized;

프레임당 캐릭터이동

Unity는 프레임에 한 번씩 Update가 실행된다. 프레임은 1초 동안 화면이 변경되는 수를 의미하기 때문에 

프레임당 이동을 위해서는 방향과 프레임변경시간 속도를 곱해줘야 한다. 

  • 프레임사이 시간은 Time.deltaTime을 사용하여 구할 수 있다.
  • 캐릭터 이동 공식 (방향 (normalized) * 시간 * 속도)

키보드를 이용한 오브젝트 움직이기

        if (Input.GetKey(KeyCode.W))
        {
            transform.position += Vector3.forward * _speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.S))
        {
            transform.position += Vector3.back * _speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.A))
        {
            transform.position += Vector3.left * _speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.D))
        {
            transform.position += Vector3.right * _speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.Q))
        {
            transform.position += Vector3.up * _speed * Time.deltaTime;
        }
        else if (Input.GetKey(KeyCode.E))
        {
            transform.position += Vector3.down * _speed * Time.deltaTime;
        }

Translate 사용하면 로컬로 바로가능

    if (Input.GetKey(KeyCode.W))
            transform.Translate(Vector3.forward * Time.deltaTime * _speed);
        if (Input.GetKey(KeyCode.S))
            transform.Translate(Vector3.back * Time.deltaTime * _speed);
        if (Input.GetKey(KeyCode.A))
            transform.Translate(Vector3.left * Time.deltaTime * _speed);
        if (Input.GetKey(KeyCode.D))
            transform.Translate(Vector3.right * Time.deltaTime * _speed);

목적지에 따른 오브젝트 움직임

    void UpdateMove()
    {
        Vector3 moveDirect = _targetPosition - transform.position; //  목적지 - 현재위치     1. 거리, 2. 방향
        float distance = moveDirect.magnitude;//거리추출

        if (distance < _speed * Time.deltaTime)//목적지에 근접했을 경우
        {
            transform.position = _targetPosition;
        }
        else
        {
            Vector3 direct = moveDirect.normalized;//방향정규화  Vector3.forward;와 같은 의미
            transform.position += direct * _speed * Time.deltaTime;// 방향 * 속도 * 프레임시간

            #region
            //float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, moveDirect.magnitude);//디테일 최대값 최소값 거리를 넘지않도록하기위해.
            //Vector3 direct = moveDirect.normalized;//방향정규화  Vector3.forward;와 같은 의미
            //transform.position += direct * moveDist;
            #endregion

            #region
            /*
             * 1. Lerp 선형보간 - 그려진 가상의 호에서의 직선 거리,
             * 2. Slerp 구면선형보간 -  그려진 가상의 호를 그대로의 거리
             * 3. MoveTowards - 그냥 이동
             */
            //transform.position = Vector3.Lerp(transform.position, _targetPosition, _speed * Time.deltaTime);
            //transform.position = Vector3.Slerp(transform.position, _targetPosition, 5f * Time.deltaTime);
            //transform.position = Vector3.MoveTowards(transform.position, _targetPosition, _speed * Time.deltaTime);
            #endregion
        }
    }

region에 기입한 부분은 디테일 적인 부분이다.

728x90