잔잔이네
article thumbnail

CharacterController

 

캐릭터 컨트롤러는 오브젝트가 위치 이동할 때 사용된다. Collider를 내장하고있다.
캐릭터 컨트롤러를 이용하면 Rigidbody가 없어도 장애물을 인식할 수 있다. (계단을 올라가는 예시)
Rigidbody를 이용했을 때는 오브젝트끼리 반작용이 있지만 컨트롤러는 없다. 통과만 못할 뿐이다.

 

Slope Limit : 경사각도 (46도 미만까지 올라간다)

Step Offset : 계단 높이 (0.6의 높이까지 올라간다)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CCMove : MonoBehaviour
{
    public float movSpeed = 20f;
    public float rotSpeed = 400f;

    Transform tr;
    CharacterController controller;
    Vector3 moveDirection;

    public float jumpSpeed = 10f;
    public float gravity = 20f;

    
    void Start()
    {
        tr = GetComponent<Transform>();
        controller = GetComponent<CharacterController>();    
    }

    
    void Update()
    {
        // 회전은 Transform의 기능을 사용한다.
        float h = Input.GetAxis("Horizontal");

        //tr.Rotate(Vector3.up * h * rotSpeed * Time.deltaTime);
        h = h * rotSpeed * Time.deltaTime;
        tr.Rotate(Vector3.up * h);

        if (controller.isGrounded)
        {
            float v = Input.GetAxis("Vertical");
           

            // 이동 방향을 로컬 좌표에서
            moveDirection = new Vector3(0f, 0f, v * movSpeed);
            // 절대 좌표로 변경한다 (CharacterController는 절대좌표로 이동한다)
            moveDirection = tr.TransformDirection(moveDirection);

            if (Input.GetButton("Jump"))
            {
                moveDirection.y = jumpSpeed;
            }
        }

        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move(moveDirection * Time.deltaTime);
    }
}

일반적인 이동과 점프가아닌 캐릭터 컨트롤러로 이동과 점프를 구현할 수도 있다.

회전은 if (controller.isGrounded)밖에 두어야 처음에 선언해둔 rotSpeed로 회전할 수 있다.

if (controller.isGrounded)는 컨트롤러의 기능으로 땅에 닿았는지 구분하는 것인데 잘 안될 수도 있다. 

이동 방향을 로컬 좌표에서 절대 좌표로 변경한다. (캐릭터 컨트롤러는 절대좌표로 이동한다)

 

 

CharacterController의 각종 이벤트와 IsTrigger 함께쓰기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CheckCollision : MonoBehaviour
{
    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log($"OnCollisionEnter - {collision.collider.name}");
    }
    
    // CharacterController에서 IsTrigger를 설정하면 OnTriggerEnter가 발생하게 된다.
    private void OnTriggerEnter(Collider other)
    {
        Debug.Log($"OnTriggerEnter - {other.name}");
    }

    // CharacterController의 이벤트
    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        // if (hit.collider.tag.Equals("WALL"))
        // if (hit.collider.CompareTag("WALL"))
        if (hit.collider.tag == "WALL")
        Debug.Log($"OnControllerColliderHit - {hit.collider.name}");
    }
}

 

트리거가 발생하여 관통한 모습

CharacterController에서 IsTrigger

캐릭터컨트롤러에서 IsTrigger를 체크하게되면 OnTriggerEnter가 발생할 수 있다.

 

 

OnControllerColliderHit

OnControllerColliderHit에서 충돌했을 때 collider의 태그를 비교한다 ( 위 세가지 모두 같은 의미이다)

태그는 오브젝트의 인스펙터에서 [Tag] - [Add Tag...] - [+] - WALL - [Save]로 만들 수 있다.

 

profile

잔잔이네

@잔잔잔잔

🌈

검색 태그