Deff_Dev

[Unity/C#] 법선 벡터 본문

Unity(유니티)/유니티 공부

[Unity/C#] 법선 벡터

Deff_a 2024. 5. 29. 22:00

 

법선 벡터 : 특정 지점에서 표면에 수직으로 뻗어 있는 벡터

법선 벡터 그림


법선 벡터를 이용하여 점프대를 만들어보자

 

위와 같이 점프대를 만들 때 법선 벡터가 왜 필요할까 ?

    [Range(0f,15f)][SerializeField] private float jumpPadPower;
    
    private void OnCollisionEnter(Collision other)
    { 
        if (other.gameObject.CompareTag("Player"))
        {
            Rigidbody rigid = other.gameObject.GetComponent<Rigidbody>();
            rigid.velocity = Vector3.zero;
            rigid.AddForce(Vector2.up * jumpPadPower, ForceMode.Impulse);
        }    
    }

 

일단 간단하게 이런식으로 작성하고 JumpPad 오브젝트에 붙히면 점프대가 완성된다.

하지만 이 코드는 플레이어가 점프대의 위쪽 면이 아닌 옆면에 충돌 했을 때도 똑같이 작동하게된다.

 

법선 벡터를 이용해서 이 문제를 해결해보자.


Collision.contacts를 이용해 충돌 지점의 법선 벡터를 구할 수 있다.

other.contacts[0].normal

 

 위 코드는 첫 번째로 충돌한 오브젝트의 충돌 지점의 법선 벡터를 구한다.

 

other.contacts[0].normal.y > 0

 

그렇다면 법선 벡터의 y값이 양수라면 이 문제가 해결될 수 있을까 ?

 

 

직접 Debug를 찍어본다면 y는 -1이 나온다.

 

왜 1이 아니고 -1일까 ?

 

정답은 현재 구하고 있는 법선 벡터는 점프대 기준에서 법선 벡터가 아닌 플레이어 기준의 법선 벡터이기 때문이다.

플레이어는 아래로 떨어지고 있기 때문에 플레이어 기준에서 법선 벡터를 구한다면 -1이 나오는 것이다.

    [Range(0f,15f)][SerializeField] private float jumpPadPower;
    
    private void OnCollisionEnter(Collision other)
    { 
        if (other.gameObject.CompareTag("Player") && other.contacts[0].normal.y > 0)
        {
            Rigidbody rigid = other.gameObject.GetComponent<Rigidbody>();
            rigid.velocity = Vector3.zero;
            rigid.AddForce(Vector2.up * jumpPadPower, ForceMode.Impulse);
        }    
    }

 

이런식으로 코드를 작성하게된다면 플레이어는 점프대 위에서만 점프를 하게된다.

 

 

[Unity/C#] Quaternion.LookRotation()

Quaternion.LookRotation(Vector3 forward, Vector3 upwards = Vector3.up) forward 방향으로 회전하는 Quaternion 값을 반환한다.여기서 upwards는 기본 값으로 Vector3.up이 사용되고 회전할 오브젝트의 y축이 바라보는 방

deff-dev.tistory.com

법선 벡터에 관한 또 다른 예제이므로 같이 읽어보는 것도 좋을 것 같다.