Unity Engine

[Unity]CollisionFlag - CharacterController

Aostols 2022. 11. 6. 08:00
반응형

객체가 현재 어떻게 충돌하고 있는지 판단하는 방법은 여러가지나 CharacterController를 사용하고 있다면 비교적 쉽게 판단 할 수 있습니다.

CharacterController.Move()를 사용한다면 CollisionFlags를 반환하게 되는데 이것은 현재 어떤 충돌상황인지를 나타내고 있습니다.

 

우선 단순한 바닥을 만들고 그 위에 캡슐을 올리고 CharacterController를 붙여 줍니다.

기본형 객체를 만들면 Collider가 붙어있는데 그것은 제거해 줍니다.

 

void Start()
{
    _controller = GetComponent<CharacterController>() as CharacterController;
    print("1 : " + _controller.collisionFlags);
    CollisionFlags flag = _controller.Move(Vector3.forward);
    print("2 : " + flag);
}

코드는 아주 간단한데 결과는 다음과 같습니다.

 

1번은 None이고 2번은 Below입니다.

Move()메소드를 보시면 알겠지만 CollisionFlags는 Move()이후에 계산됩니다.

따라서 최초 배치상태에서는 None이되고 한번이라도 Move()를 수행 해야 그다음 올바른 값을 나타냅니다.

 

이제 조금 다른 테스트를 진행 하겠습니다.

void Update()
{
    Vector3 moveStep = Vector3.zero;
    if(Input.GetKey(KeyCode.LeftArrow))
    {
        moveStep += Vector3.left * Time.deltaTime;
    }
    else if(Input.GetKey(KeyCode.RightArrow))
    {
        moveStep += Vector3.right * Time.deltaTime;
    }
    else if(Input.GetKey(KeyCode.UpArrow))
    {
        moveStep += Vector3.forward * Time.deltaTime;
    }
    else if(Input.GetKey(KeyCode.DownArrow))
    {
        moveStep += Vector3.back * Time.deltaTime;
    }

    if (moveStep != Vector3.zero)
    {
        CollisionFlags flag = _controller.Move(moveStep);
        print("## " + flag);
        print(((flag & CollisionFlags.Sides) != 0));
        print(((flag & CollisionFlags.Above) != 0));
        print(((flag & CollisionFlags.Below) != 0));
    }
}

아주 단순하게 이동하는 코드를 집어 넣습니다.

Scene은 이렇게 구성하여 실제 벽을 만들어 줍니다.

이후 벽을 밀었을 경우 어떻게 처리 되는지 확인합니다.

 

생각했던 내용과 결과가 약간 다른데 Below도 있을줄 알았는데 Sides만 결과를 얻었습니다.

이유는 Move()를 했을경우 충돌했는가를 CollisionFlags로 받기 때문에 우리는 옆으로만 이동했고 아래방향으로는 이동하지 않았기 때문에 아래방행으로는 충돌이 없었습니다.

따라서 CollisionFlags는 Sides만 얻게 됩니다.

그렇다면 여기서 Rigidbody를 추가해서 Gravity를 넣으면 결과는 어떻게 되는지 확인해 봅시다.

 

여전히 결과는 Sides만 있습니다.

아까도 써있지만 CollisionFlags는 Move()의 결과값 이기 때문에 Rigidbody의 Gravity는 Move()에 직접적인 영향을 주지 않기 때문에 CollisionFlags에 Below 결과를 얻지 못합니다.

 

if (moveStep != Vector3.zero)
{
    moveStep += new Vector3(0, -0.1f, 0);
    CollisionFlags flag = _controller.Move(moveStep);
    print("## " + flag);
    print(((flag & CollisionFlags.Sides) != 0));
    print(((flag & CollisionFlags.Above) != 0));
    print(((flag & CollisionFlags.Below) != 0));
}

이제 맨 마지막에 y축을 -0.1f로 움직이도록 추가해 줍니다.

방향키 외에 항상 아래로 향하게 됩니다.

 

이제 결과값이 5가 나오게 되었습니다.

Sides 와 Below가 같이 나온 상태 입니다.

 

만일 서버에서 계산을 하게 된다면 중력을 같이 계산식에 넣어서 계산 해 준다면 자연스러운 결과를 얻을 수 있을것 같습니다.

반응형