조인트 및 래그돌 안정성
스크립팅(Scripting)

휠 콜라이더 튜토리얼

Wheel Collider 컴포넌트에는 PhysX 3 Vehicles SDK가 사용됩니다.

이 튜토리얼에서는 기본 기능만 있는 자동차를 만드는 절차를 설명합니다.

시작하려면 GameObject > 3D Object > Plane 을 선택합니다. 지금 선택되는 항목은 차를 운전할 지면입니다. 간단하게 유지하기 위해, 지면의 Transform이 0 인지 확인합니다(인스펙터 창의 Transform 컴포넌트에서 설정 톱니바퀴 아이콘을 클릭한 다음 Reset 을 클릭). Transform의 Scale 필드를 100 으로 높여 평면이 더 커지게 합니다.

기본 자동차 골격 생성

  1. 먼저 자동차 루트 오브젝트의 역할을 할 게임 오브젝트 추가합니다. 이렇게 하려면 GameObject -> Create Empty 로 이동하여 게임 오브젝트의 이름을 car_root로 변경합니다.
  2. car_root에 Physics 3D Rigidbody 컴포넌트를 추가합니다. 기본 질량이 1kg로 설정되어 있는데, 기본 서스펜션 설정으로는 너무 가벼우므로 1,500kg으로 변경하여 훨씬 더 무겁게 설정합니다.
  3. 다음으로, 자동차 바디 콜라이더를 만듭니다. GameObject > 3D Object -> Cube 를 선택합니다. 이 큐브를 car_root 아래의 자식 게임 오브젝트로 지정합니다. 로컬 공간에서 완벽하게 정렬되도록 Transform을 0 으로 초기화합니다. 자동차 방향이 Z축을 따르므로 Transform의 Z Scale3 으로 설정합니다.
  4. 휠 루트를 추가합니다. car_rootGameObject > Create Empty Child 를 선택합니다. 이름을 wheels로 변경합니다. 해당 Transform을 초기화합니다. 이 게임 오브젝트는 필수는 아니지만 나중에 튜닝하고 디버깅하는 데 유용합니다.
  5. 첫 휠을 생성하려면 wheels 게임 오브젝트를 선택하고 GameObject > Create Empty Child 를 선택한 후 이름을 frontLeft로 지정합니다. Transform을 초기화한 후 Transform Position X 를 –1로, Y 를 0으로, Z 를 1로 설정합니다. 콜라이더를 휠에 추가하려면 Add component > Physics > Wheel Collider 를 선택합니다.
  6. frontLeft 게임 오브젝트를 복제합니다 TransformX 위치를 1로 변경합니다. 이름을 frontRight로 변경합니다.
  7. frontLeftfrontRight 게임 오브젝트를 모두 선택하고 복제합니다. 두 오브젝트의 Transform Z 위치를 모두 –1로 변경합니다. 이름을 각각 rearLeftrearRight로 변경합니다.
  8. 마지막으로, car_root 게임 오브젝트를 선택하고 이동 도구를 사용하여 지면에서 약간 위로 올립니다.

이제 다음과 같이 표시됩니다.

이 자동차를 실제로 운전할 수 있게 하려면 자동차 컨트롤러를 작성해야 합니다. 다음 코드 샘플이 컨트롤러로 작동합니다.

    using UnityEngine;
        using System.Collections;
        using System.Collections.Generic;
    
        public class SimpleCarController : MonoBehaviour {
            public List<AxleInfo> axleInfos; // the information about each individual axle
            public float maxMotorTorque; // maximum torque the motor can apply to wheel
            public float maxSteeringAngle; // maximum steer angle the wheel can have
        
            public void FixedUpdate()
            {
                float motor = maxMotorTorque * Input.GetAxis("Vertical");
                float steering = maxSteeringAngle * Input.GetAxis("Horizontal");
            
                foreach (AxleInfo axleInfo in axleInfos) {
                    if (axleInfo.steering) {
                        axleInfo.leftWheel.steerAngle = steering;
                        axleInfo.rightWheel.steerAngle = steering;
                    }
                    if (axleInfo.motor) {
                        axleInfo.leftWheel.motorTorque = motor;
                        axleInfo.rightWheel.motorTorque = motor;
                    }
                }
            }
        }
    
        [System.Serializable]
        public class AxleInfo {
            public WheelCollider leftWheel;
            public WheelCollider rightWheel;
            public bool motor; // is this wheel attached to motor?
            public bool steering; // does this wheel apply steer angle?
        }

새 C# 스크립트(Add Component > New Script)를 생성하고 car_root 게임 오브젝트에서 이 샘플을 스크립트 파일로 복사한 후 저장합니다. 아래 그림과 같이 스크립트 파라미터를 조정할 수 있습니다. 설정을 다양하게 해서 실험해보고 재생 모드로 전환하여 결과를 테스트합니다.

자동차 컨트롤러로는 다음 설정이 매우 효과적입니다.

자동차 인스턴스 하나에 스티어링, 모터, 제동 토크를 가하는 휠을 20개까지 포함할 수 있습니다.

다음으로, 비주얼 휠로 넘어갑니다. 그림에서 볼 수 있듯이, 휠 콜라이더는 시뮬레이션된 휠 포지션과 회전을 휠 콜라이더의 트랜스폼에 다시 적용하지 않으므로 비주얼 휠을 추가하려면 몇 가지 팁을 활용해야 합니다.

우선 휠 지오메트리가 필요합니다. 원기둥으로 간단한 휠 모양을 만들 수 있습니다. 스트립트 프로퍼티에서 비주얼 휠을 수동으로 할당하거나, 대응되는 비주얼 휠을 자동으로 찾는 로직을 작성하는 등의 몇 가지 방법으로 비주얼 휠을 추가할 수 있습니다. 이 튜토리얼에서는 두 번째 방법을 사용합니다. 비주얼 휠을 휠 콜라이더 게임 오브젝트에 부착합니다.

다음으로, 컨트롤러 스크립트를 다음과 같이 변경합니다.

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

        [System.Serializable]
        public class AxleInfo {
            public WheelCollider leftWheel;
            public WheelCollider rightWheel;
            public bool motor;
            public bool steering;
        }
     
        public class SimpleCarController : MonoBehaviour {
            public List<AxleInfo> axleInfos; 
            public float maxMotorTorque;
            public float maxSteeringAngle;
     
            // finds the corresponding visual wheel
            // correctly applies the transform
            public void ApplyLocalPositionToVisuals(WheelCollider collider)
            {
                if (collider.transform.childCount == 0) {
                    return;
                }
     
                Transform visualWheel = collider.transform.GetChild(0);
     
                Vector3 position;
                Quaternion rotation;
                collider.GetWorldPose(out position, out rotation);
     
                visualWheel.transform.position = position;
                visualWheel.transform.rotation = rotation;
            }
     
            public void FixedUpdate()
            {
                float motor = maxMotorTorque * Input.GetAxis("Vertical");
                float steering = maxSteeringAngle * Input.GetAxis("Horizontal");
     
                foreach (AxleInfo axleInfo in axleInfos) {
                    if (axleInfo.steering) {
                        axleInfo.leftWheel.steerAngle = steering;
                        axleInfo.rightWheel.steerAngle = steering;
                    }
                    if (axleInfo.motor) {
                        axleInfo.leftWheel.motorTorque = motor;
                        axleInfo.rightWheel.motorTorque = motor;
                    }
                    ApplyLocalPositionToVisuals(axleInfo.leftWheel);
                    ApplyLocalPositionToVisuals(axleInfo.rightWheel);
                }
            }
        }

Wheel Collider 컴포넌트의 중요한 파라미터 중 하나는 정지된 휠의 베이스에서 휠의 힘이 가해지는 점까지의 거리인 Force App Point Distance 입니다. 기본값은 0으로, 정지된 휠의 베이스에 힘을 가하도록 설정되어 있는데 실제로는 이 점을 자동차의 무게 중심보다 약간 낮은 위치로 지정하는 것이 좋습니다.

참고: 휠 콜라이더의 실제 사례를 보려면 휠이 있는 자동차를 조립하고 휠 콜라이더의 서스펜션을 생성하는 데 필요한 도구가 포함된 Vehicle Tools 패키지를 다운로드하십시오.


  • 2017–11–24 일부 편집 리뷰를 거쳐 페이지 수정됨
조인트 및 래그돌 안정성
스크립팅(Scripting)