Menu
CoddyTech

물체 밀기

Coddy Unity 여정의 실제 게임 만들기 섹션에 포함된 레슨. 56개 중 40번째.

CharacterController는 아무것도 밀지 않습니다. Rigidbody가 있는 상자 쪽으로 걸어가면 벽에 부딪힌 것처럼 멈춥니다. 대신 Unity는 Move가 접촉하는 모든 콜라이더(바닥 포함)에 대해 컨트롤러 자체 스크립트의 OnControllerColliderHit(ControllerColliderHit hit)을 호출하고, 어떤 일이 일어날지는 스크립트가 결정합니다. hit.collider는 접촉한 대상이고, hit.moveDirection은 접촉을 일으킨 Move의 방향이며, hit.normal은 접촉 지점에서 표면이 향하는 방향입니다. 다음은 Unity 자체의 밀기 스크립트입니다.

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // 밀어낼 대상이 없음
    if (hit.moveDirection.y < -0.3f) return;        // 발밑에 있음

    Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
    body.linearVelocity = pushDir * pushPower;
}

각 return에는 이유가 있습니다. 바닥과 벽에는 Rigidbody가 없으므로 이들에 대해서는 body가 null이며, 거의 모든 Move에서 접촉하게 됩니다. 키네마틱 바디는 자체 스크립트가 움직일 때만 이동하므로, 속도를 설정해도 움직이지 않습니다. 아래쪽을 가파르게 향하는 Move는 발밑에 있는 대상과 접촉한 것이므로, 플레이어가 올라서 있는 상자를 밀어서는 안 됩니다.

밀기 방향은 x와 z만 유지하므로 상자는 바닥에 눌려 들어가는 대신 바닥을 따라 미끄러집니다. 힘을 더하는 대신 linearVelocity를 설정하면 가벼운 상자와 무거운 상자가 같은 속도로 움직입니다. body.AddForce(pushDir * pushPower, ForceMode.Impulse)를 사용하면 무거운 상자는 더 적게 밀립니다.

challenge icon

챌린지

중급

마당에서 공을 차 보세요. Player는 CharacterController를 사용해 움직입니다(Walker.cs, 준비됨). Player에도 Kicker.cs를 작성하세요. Inspector에서 kickPower(6)와 lift(4)를 설정합니다.

  • 플레이어가 밀 수 있는 물체에 부딪히면 해당 물체의 linearVelocity를 걷는 방향의 지면과 평행한 속도에 kickPower를 곱하고, 여기에 수직 위쪽 방향의 lift를 더한 값으로 설정하여 공이 앞쪽 위로 날아가게 하세요.
  • 지면과 기둥에는 Rigidbody가 없습니다. 오류 없이 건너뛰세요.
  • 플레이어 발밑에 있는 공은 차지 않습니다.

Play를 누르고 빨간 공을 찬 다음 Check를 누르세요.

직접 해보기

using UnityEngine;

public class Kicker : MonoBehaviour
{
    public float kickPower = 6f;
    public float lift = 4f;

    // 플레이어가 부딪히는 공을 차기
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

실제 게임 만들기의 모든 레슨