Version: 2023.2
언어: 한국어
휠 콜라이더 서스펜션
휠 콜라이더 컴포넌트 레퍼런스

휠 콜라이더로 차량 생성

이 튜토리얼에서는 기본적으로 작동하는 사륜구동 차량을 PhysX 휠 콜라이더로 생성하는 프로세스를 안내합니다.

이 단계에는 다음이 포함됩니다.

  1. 프로젝트를 준비합니다.
  2. 차량 모델을 준비합니다.
  3. 휠 콜라이더를 추가하고 위치 및 반지름을 설정합니다.
  4. 차량 이동 및 휠 회전을 포함하여 차량 동작을 제어하는 스크립트를 추가합니다.
  5. 차량을 테스트합니다.

프로젝트 준비

지침을 따르려면 다음이 필요합니다.

  • 새로운 비어 있는 씬
  • 데모 차량 모델(다운로드: car.fbx)을 열린 프로젝트에 임포트
  • 차량이 이동할 지면

지면을 생성하려면 다음을 따르십시오.

    • 평면 게임 오브젝트를 만들고 이름을 Ground로 변경합니다. 이 평면은 차량이 주행할 지면입니다.
  1. 위치를 (0,0,0)으로, 스케일을 (100,1,100)으로 설정합니다.

차량 모델 준비

먼저 차량 모델을 씬에 배치합니다.

  1. 프로젝트(Project) 창에서 임포트한 Car 에셋을 선택합니다.
  2. Unity가 씬에서 표시할 수 있도록 차량 모델의 텍스처를 추출합니다. 이렇게 하려면 인스펙터(Inspector) 창의 Import Settings로 이동하여 다음을 따르십시오.
    1. Materials를 선택합니다.
    2. Textures > Extract Textures를 선택합니다. 파일 탐색기가 열리면 Assets 폴더(기본 위치)에 저장합니다.
    3. Apply를 선택합니다.
  3. 차량 에셋을 씬에서 지면 위에 배치합니다.

계층(Hierarchy) 창에서 차량 게임 오브젝트의 계층 구조를 확인합니다. Car라고 하는 루트 게임 오브젝트가 있고, 차체 모델 및 각 휠 모델의 자식 게임 오브젝트가 있습니다.

차체를 충돌에 대해 설정합니다.

  1. Car 루트 게임 오브젝트에 Rigidbody 컴포넌트를 추가합니다.
  2. Rigidbody의 Mass1500으로 설정합니다. 이 값은 차량의 무게를 킬로그램 단위로 정의합니다. 1500은 휠 콜라이더의 기본 서스펜션 설정에 적합한 무게입니다. 자세한 내용은 휠 콜라이더 서스펜션: 질량 및 서스펜션 값을 참조하십시오.
  3. Car Body 게임 오브젝트에 Mesh Collider 컴포넌트를 추가합니다.
  4. 새로운 Mesh Collider 컴포넌트에서 Convex를 활성화합니다.

휠 콜라이더 추가

휠 모델에 휠 콜라이더를 추가하려면 4개의 새로운 별도 게임 오브젝트를 휠 모델과 동일한(하지만 휠의 자식 게임 오브젝트와는 다른) 위치에 생성해야 합니다.

거의 동일한 위치에 설정하는 빠른 방법은 휠 게임 오브젝트를 복제하고 새 게임 오브젝트를 설정하는 것입니다.

  1. 네 개의 휠 게임 오브젝트를 모두 선택합니다.
  2. 게임 오브젝트를 복제(Ctrl/Cmd+D)합니다.
  3. 복제한 게임 오브젝트를 모두 선택하고 다음을 수행합니다.
    1. Mesh Renderer 및 Mesh Filter 컴포넌트를 삭제합니다.
    2. Wheel Collider 컴포넌트를 추가합니다.
  4. 새 휠 콜라이더 게임 오브젝트의 이름을 변경합니다. 기본적으로 Unity에서 복제된 게임 오브젝트는 동일한 이름 뒤에 괄호 사이 숫자가 붙습니다(예: Wheel Back Left (1)). 명확성을 위해 게임 오브젝트 이름에 ‘Collider’라는 단어를 추가합니다(예: Wheel Back Left collider).

이제 차량 게임 오브젝트 계층 구조는 다음과 같습니다.

루트 차량 게임 오브젝트와 차체, 4개의 휠 모델 게임 오브젝트, 4개의 휠 콜라이더 게임 오브젝트를 포함한 모든 자식 게임 오브젝트
루트 차량 게임 오브젝트와 차체, 4개의 휠 모델 게임 오브젝트, 4개의 휠 콜라이더 게임 오브젝트를 포함한 모든 자식 게임 오브젝트

다음으로 휠 모델에 맞게 휠 콜라이더의 위치와 크기를 조정해야 합니다.

휠 콜라이더를 선택하면 씬 뷰에 휠 콜라이더 설정을 시각화하는 기즈모가 표시됩니다. 휠 콜라이더 시각화를 참조하십시오. 기즈모를 사용하면 휠 모델의 위치 및 크기와 비교하여 휠 콜라이더의 위치와 크기를 확인할 수 있습니다.

휠 방향과 기즈모를 더 명확하게 보려면 씬의 드로우 모드Wireframe으로, 씬 방향Isometric으로 설정합니다.

휠 콜라이더 위치 설정

휠 콜라이더 추가에 설명된 워크플로로 휠 콜라이더를 처음 추가하면 위치가 너무 낮게 나타납니다(씬 뷰에서 휠 모델 메시 아래에 휠 콜라이더 원이 나타남). 이는 Suspension Distance가 이러한 게임 오브젝트의 위치에서 시작하여 Suspension Distance 설정에 지정된 거리만큼 아래쪽으로 확장되기 때문입니다. 씬 뷰 시각화에서는 Suspension Distance가 휠 콜라이더 기즈모의 Y축 아래 주황색 선으로 표시됩니다.

녹색 원 윤곽선은 서스펜션 거리 범위의 중간 지점에 있는 휠을 표시하며, 자동차가 서스펜션에 눌리거나 올라가지 않았을 때 휠의 일반적인 위치로 간주해야 합니다. 따라서 각 휠 콜라이더의 녹색 윤곽선은 해당 휠 메시의 중앙에 있어야 합니다.

휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서는 휠 콜라이더가 너무 크고 너무 낮습니다.
휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서는 휠 콜라이더가 너무 크고 너무 낮습니다.

이 문제를 해결하려면 WheelCollider 게임 오브젝트를 휠 콜라이더의 Suspension Distance 값의 절반만큼 Y축을 따라 위로 옮겨야 합니다. 이 예제 프로젝트에서 Suspension Distance는 0.3(기본값)이므로 휠 콜라이더 게임 오브젝트를 0.15유닛만큼 위로 옮겨야 합니다.

Unity에서는 숫자 필드에 간단한 수학 계산식을 입력할 수 있습니다. 이를 사용하여 Y축 값에 수를 더할 수 있습니다.

  1. 네 개의 휠 콜라이더 게임 오브젝트를 모두 선택합니다.
  2. 인스펙터에서 Transform의 Position 프로퍼티로 이동합니다.
  3. Y 축 값에서 커서를 값 끝에 놓습니다. 값 끝에 +0.15를 더합니다. 예를 들어, 값이 0.5인 경우 이제 값은 0.5+0.15가 되어야 합니다.
  4. Return 키를 누릅니다.

Unity가 이전 값에 +0.15를 적용하여 휠 콜라이더 게임 오브젝트를 Y축에서 위로 0.15유닛만큼 옮깁니다.

이제 휠 콜라이더 기즈모가 완벽하게 휠 메시의 중앙에 위치해야 합니다.

휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서는 휠 콜라이더가 휠 모델의 중앙에 올바르게 배치되어 있습니다.
휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서는 휠 콜라이더가 휠 모델의 중앙에 올바르게 배치되어 있습니다.

휠 콜라이더 반지름 설정

휠 콜라이더 추가에 설명된 워크플로로 휠 콜라이더를 처음 추가하면 셰이프가 너무 크게 나타납니다(씬 뷰에서 휠 콜라이더 기즈모가 휠 모델 메시보다 큼).

이 문제를 정확하게 수정하려면 휠 모델의 정확한 반지름을 알아야 합니다. 이 정보는 3D 모델링 소프트웨어 또는 모델을 저작한 테크니컬 아티스트를 통해 제공받아야 합니다.

이 예시 프로젝트에서 휠 모델의 반지름은 0.44입니다.

  1. 네 개의 휠 콜라이더 게임 오브젝트를 모두 선택합니다.
  2. 인스펙터에서 Wheel Collider 컴포넌트의 Radius 프로퍼티로 이동합니다.
  3. Radius0.44로 설정합니다.

휠 모델의 정확한 반지름을 알 수 없거나 사용할 수 없는 경우 휠 콜라이더 기즈모를 사용하여 반지름을 모델과 대략적으로 맞출 수 있습니다. 또는 스피어 콜라이더를 사용하여 반지름을 구할 수 있습니다. 스피어 콜라이더는 연결된 모델의 메시를 포함하도록 자동으로 크기가 조정되기 때문입니다.

스피어 콜라이더로 반지름을 구하려면 다음을 따르십시오.

  1. 휠 모델 게임 오브젝트를 선택합니다.
  2. 스피어 콜라이더를 추가합니다.
  3. 스피어 콜라이더의 Radius 프로퍼티 값을 기록합니다.
  4. 스피어 콜라이더를 제거합니다.
  5. 네 개의 휠 콜라이더 게임 오브젝트를 모두 선택합니다.
  6. 인스펙터에서 Wheel Collider 컴포넌트의 Radius 프로퍼티로 이동합니다.
  7. 휠 콜라이더 Radius를 기록해 두었던 스피어 콜라이더의 Radius 값으로 설정합니다.

이제 휠 콜라이더가 휠 모델의 위치 및 크기와 정확히 일치합니다.

두 개의 휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서 휠 콜라이더는 휠 모델의 중앙에 올바르게 배치되어 있으며 반지름도 휠 모델의 반지름과 정확하게 일치합니다.
두 개의 휠 콜라이더 기즈모는 휠 모델에 대한 휠 콜라이더의 위치를 나타냅니다. 이 이미지에서 휠 콜라이더는 휠 모델의 중앙에 올바르게 배치되어 있으며 반지름도 휠 모델의 반지름과 정확하게 일치합니다.

차량 동작을 제어하는 스크립트 추가

차량을 제어하려면 프로젝트에 스크립트를 추가하여 다음을 수행해야 합니다.

  • 차량 움직임 제어: 사용자 입력을 기반으로 스티어링, 토크 및 제동 값을 휠 콜라이더에 전송합니다.
  • 휠 움직임 제어: 각 휠 콜라이더의 상태에 따라 휠 메시를 움직이고 회전시킵니다.

이 예시에서는 이를 위해 두 개의 스크립트인 CarControl.csWheelControl.cs를 사용합니다.

차량 이동에 대한 제어 추가

CarControl.cs라는 C# 파일을 생성하고 아래 코드를 붙여 넣습니다.

using UnityEngine;

public class CarControl : MonoBehaviour
{
    public float motorTorque = 2000;
    public float brakeTorque = 2000;
    public float maxSpeed = 20;
    public float steeringRange = 30;
    public float steeringRangeAtMaxSpeed = 10;
    public float centreOfGravityOffset = -1f;

    WheelControl[] wheels;
    Rigidbody rigidBody;

    // Start is called before the first frame update
    void Start()
    {
        rigidBody = GetComponent<Rigidbody>();

        // Adjust center of mass vertically, to help prevent the car from rolling
        rigidBody.centerOfMass += Vector3.up * centreOfGravityOffset;

        // Find all child GameObjects that have the WheelControl script attached
        wheels = GetComponentsInChildren<WheelControl>();
    }

    // Update is called once per frame
    void Update()
    {

        float vInput = Input.GetAxis("Vertical");
        float hInput = Input.GetAxis("Horizontal");

        // Calculate current speed in relation to the forward direction of the car
        // (this returns a negative number when traveling backwards)
        float forwardSpeed = Vector3.Dot(transform.forward, rigidBody.velocity);


        // Calculate how close the car is to top speed
        // as a number from zero to one
        float speedFactor = Mathf.InverseLerp(0, maxSpeed, forwardSpeed);

        // Use that to calculate how much torque is available 
        // (zero torque at top speed)
        float currentMotorTorque = Mathf.Lerp(motorTorque, 0, speedFactor);

        // …and to calculate how much to steer 
        // (the car steers more gently at top speed)
        float currentSteerRange = Mathf.Lerp(steeringRange, steeringRangeAtMaxSpeed, speedFactor);

        // Check whether the user input is in the same direction 
        // as the car's velocity
        bool isAccelerating = Mathf.Sign(vInput) == Mathf.Sign(forwardSpeed);

        foreach (var wheel in wheels)
        {
            // Apply steering to Wheel colliders that have "Steerable" enabled
            if (wheel.steerable)
            {
                wheel.WheelCollider.steerAngle = hInput * currentSteerRange;
            }
            
            if (isAccelerating)
            {
                // Apply torque to Wheel colliders that have "Motorized" enabled
                if (wheel.motorized)
                {
                    wheel.WheelCollider.motorTorque = vInput * currentMotorTorque;
                }
                wheel.WheelCollider.brakeTorque = 0;
            }
            else
            {
                // If the user is trying to go in the opposite direction
                // apply brakes to all wheels
                wheel.WheelCollider.brakeTorque = Mathf.Abs(vInput) * brakeTorque;
                wheel.WheelCollider.motorTorque = 0;
            }
        }
    }
}

CarControl.cs 스크립트를 Car 루트 게임 오브젝트에 추가합니다.

CarControl.cs 스크립트는 사용자 입력을 기반으로 가속화, 토크, 제동과 같은 차량 동작을 처리합니다. 자세한 내용은 코드 주석을 참조하십시오.

CarControl.cs 스크립트의 일부 요소는 다음 섹션에서 생성되는 WheelControl.cs 스크립트를 참조합니다.

휠 움직임을 위한 컨트롤 추가

WheelControl.cs라는 C# 파일을 생성하고 다음 코드를 붙여 넣습니다.

using UnityEngine;

public class WheelControl : MonoBehaviour
{
    public Transform wheelModel;

    [HideInInspector] public WheelCollider WheelCollider;

    // Create properties for the CarControl script
    // (You should enable/disable these via the 
    // Editor Inspector window)
    public bool steerable;
    public bool motorized;

    Vector3 position;
    Quaternion rotation;

    // Start is called before the first frame update
    private void Start()
    {
        WheelCollider = GetComponent<WheelCollider>();
    }

    // Update is called once per frame
    void Update()
    {
        // Get the Wheel collider's world pose values and
        // use them to set the wheel model's position and rotation
        WheelCollider.GetWorldPose(out position, out rotation);
        wheelModel.transform.position = position;
        wheelModel.transform.rotation = rotation;
    }
}

이 스크립트를 각 휠 콜라이더 게임 오브젝트에 추가합니다.

WheelControl.cs 스크립트는 WheelCollider.GetWorldPose를 사용하여 휠 콜라이더의 씬 내 포지션을 얻습니다. 그러면 스크립트가 해당 포지션 정보를 지정된 휠 모델 게임 오브젝트에 할당합니다. 자세한 내용은 코드 주석을 참조하십시오.

WheelControl.cs 스크립트의 각 인스턴스는 해당 휠 모델 게임 오브젝트에 대한 레퍼런스를 포함해야 합니다.

각 휠 콜라이더에 맞는 휠 모델 게임 오브젝트를 할당하려면 다음을 따르십시오.

  1. 휠 콜라이더 게임 오브젝트를 선택합니다.
  2. 인스펙터 창에서 스크립트를 통해 생성된 Wheel Control 컴포넌트로 이동합니다.
  3. Wheel Model을 해당 휠 모델 게임 오브젝트에 설정합니다(예: ‘Wheel Rear Left collider’ 게임 오브젝트에서 ‘Wheel Rear Left’ 휠 모델 게임 오브젝트 할당).
  4. 각 휠 콜라이더에 대해 이를 반복합니다.

또한 CarControl 스크립트에서 모터 입력과 스티어링 입력을 받을 휠을 선택해야 합니다. Wheel Control 프로퍼티를 통해 사륜구동 차량을 시뮬레이션하려면 다음을 따르십시오.

  1. 네 개의 휠 콜라이더 게임 오브젝트 모두에서 Motorized를 활성화합니다.
  2. 두 개의 앞쪽 휠 콜라이더 게임 오브젝트에서 Steerable을 활성화합니다.

차량 테스트

차량을 테스트하려면 플레이 모드로 들어가서 화살표 또는 WASD 키를 사용하여 옮기고 스티어링합니다. 입력 컨트롤은 Game(게임) 뷰에 포커스가 있을 때만 작동합니다.

씬에서 움직이는 차량을 더 잘 보려면 다음을 따르십시오.

  1. 씬 뷰와 게임 뷰가 동시에 표시되도록 에디터 창을 정렬합니다.
  2. 씬 뷰의 포커스를 차량에 고정합니다. 이렇게 하려면 씬 뷰에서 Car 루트 게임 오브젝트를 선택한 다음 Shift + F를 누릅니다.

이제 기본 설정이 완료되었으므로 다양한 설정을 변경하여 차량의 움직임에 어떤 영향을 미치는지 살펴볼 수 있습니다. 다른 차량 모델에 대해서도 이 지침을 따라 설정의 유사점과 차이점을 살펴볼 수 있습니다.

휠 콜라이더 서스펜션
휠 콜라이더 컴포넌트 레퍼런스