Unity 3D Pushing Object
유니티 3D 게임에서 Character Controller에 게임오브젝트가 충돌할 때 밀어내기 예제
이동하는 사람이나 중량물에 다른 물체가 부딪힐 경우에는 부딪힌 물체가 밀려나는 효과를 구현하려고 한다.
First Person Controller에 Wrangler Jeep 차를 포함시키고 WASD 키를 이용하여 차를 타고 이동하는 중에 차가 바위에 충돌하면 바위가 밀려나도록 하려고 한다. 유니티에서는 이런 경우에 유용한 이벤트 핸들러 함수(메시지 함수)가 있는데, OnControllerColliderHit() 함수를 작성하여 First Person Controller 에 포함시키면 다른 오브젝트와 충돌할 경우 이 함수가 실행되므로 함수 안에서 충돌된 오브젝트의 충돌반응을 계산하여 적용하면 된다.
아래의 페이지에 접속하면 참고할만한 예제를 찾을 수 있다
http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.OnControllerColliderHit.html
First Person Controller 가 부모 오브젝트로써 Jeep 차를 포함하고 있기 때문에 차에 물체가 부딪힌 경우에 OnControllerColliderHit() 함수가 호출되도록 해야 하는데 First Person Controller 의 Radius와 Height를 조정하여 자동차 전체를 포함할 수 있도록 확장해주면 된다.
First Person Controller와 충돌할 대상 오브젝트에는 반드시 Rigidbody 콤포넌트가 포함되어 있어야 하므로 모델 오브젝트에 Rigidbody가 없는 경우에는 Component > Physics > Rigidbody 항목을 선택하여 추가해주고 Drag 값을 조정하여 움직일 때의 저항을 설정하면 무한정 이동하는 현상을 방지할 수 있다
예제에서 사용된 바위 모델은 tf3dm 사이트에서 'rock' 키워드로 검색하여 다운로드할 수 있다.
유니티 사이트의 예제를 사용하여 자동차가 충돌했을 경우에 충돌된 오브젝트가 밀려나가도록 하는 스크립트
아래의 스크립트를 작성하여 First Person Controller에 포함하도록 한다
#pragma strict
var pushPower : float = 10.0;
function OnControllerColliderHit (hit : ControllerColliderHit) {
if(hit.transform.name!="Rock") return;
var body : Rigidbody = hit.collider.attachedRigidbody;
// no rigidbody
if (body == null || body.isKinematic){
return;
}
// We dont want to push objects below us
if (hit.moveDirection.y < -0.3) {
return;
}
// Calculate push direction from move direction,
// we only push objects to the sides never up and down
//var pushDir : Vector3 = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);
var chMotor: CharacterMotor = this.GetComponent(CharacterMotor);
var speedX:float = 0;
var speedZ:float = 0;
// First Person Controller의 충돌시 속도를 구하여 충돌된 오브젝트가 밀려나가는 속도에 반영한다
if (chMotor){ // make sure CharacterMotor exists
speedX = chMotor.movement.maxSidewaysSpeed;
speedZ = chMotor.movement.maxForwardSpeed;
}
var pushDir : Vector3 = Vector3 (speedX/3, 0, speedZ/3);
// If you know how fast your character is trying to move,
// then you can also multiply the push velocity by that.
// Apply the push
body.velocity = pushDir * pushPower; //충돌된 객체의 밀려나가는 속도를 적용한다
}
실행모드로 테스트한다
자동차가 이동하는 길에 바위가 있고 바위를 향하여 차가 이동한다
자동차가 바위에 충돌한다
충돌된 바위가 길가로 밀려 나간다