본문 바로가기

Unity/3D

Unity 3d - Character Controller 충돌판정에 대한 이해 [C#]

반응형

예전에 벽점프를 구현하려고

반사벡터를 구한적이 있었다.



다 만들고 뿌듯해하며 지형을 제작중이었는데,

Mesh Collider를 사용중인 건물과의 충돌판정이 안나오는것을 알았다.

따라서 반사벡터를 구할 수 없어 벽점프가 불가능했는데,


이를 해결하기위해 충돌 함수를 변경했다.



기존에 사용하던 함수인

void OnCollisionStay(Collision col) 

을 사용하였을 때에는 캐릭터 컨트롤러가 rigidbody와 충돌되었을 때 발생한다.


하지만, mesh를 쓰는 건물은 rigidbody를 사용하면 오류가나 iskinematic을 사용해야하는데, 이러면 해당 함수로 충돌판정이 안난다.

따라서, 컨트롤러가 타 콜라이더와 충돌시 호출되는

void OnControllerColliderHit(ControllerColliderHit hit)

함수를 사용하였다.



----------------------------------- 기존 코드 -----------------------

void OnCollisionStay(Collision col)

    {

        if (tmpJumpPower > 25f * rushSpeed) return;

        ContactPoint cp = col.contacts[0];

        float dot = Mathf.Abs(Vector3.Dot(Camera.main.transform.forward, cp.normal));


        Debug.Log(dot);

        if (dot >  0.149f)

        {

            if(!ctrler.isGrounded && Input.GetButtonDown("Jump") && Input.GetKey(KeyCode.W))

            {

                delay = true;

                rushSpeed = 1.0f;

                wallJumpV=Vector3.Reflect(mmTmp.normalized, cp.normal).normalized * wallPower;

               

                    Debug.Log(mmTmp.normalized + " --- " + Camera.main.transform.rotation.eulerAngles.normalized + " --- "+ cp.point + " --- " + cp.normal + " --- " +wallJumpV);

                tmpJumpPower = wallJumpV.y * wallPowerY;

                wallJumpV.Set(wallJumpV.x, 0, wallJumpV.z);


            }

        }


    }

---------------------------------------------------------------- 변경된 코드 ------------------------------

void OnControllerColliderHit(ControllerColliderHit hit)

    {

        if (tmpJumpPower > 25f * rushSpeed) return;

        float dot = Mathf.Abs(Vector3.Dot(Camera.main.transform.forward, hit.normal));


        Debug.Log(dot);

        if (dot > 0.149f)

        {

            if (!ctrler.isGrounded && Input.GetButtonDown("Jump") && Input.GetKey(KeyCode.W))

            {

                delay = true;

                rushSpeed = 1.0f;

                wallJumpV = Vector3.Reflect(mmTmp.normalized, hit.normal).normalized * wallPower;


                Debug.Log(mmTmp.normalized + " --- " + Camera.main.transform.rotation.eulerAngles.normalized + " --- " + hit.point + " --- " + hit.normal + " --- " + wallJumpV);

                tmpJumpPower = wallJumpV.y * wallPowerY;

                wallJumpV.Set(wallJumpV.x, 0, wallJumpV.z);


            }

        }


    }

반응형