unity character controller

背景

在使用摄像机游览场景的时候,需要控制摄像机不穿透场景中的物体,这需要用到碰撞。在unity物理引擎中有两类的情况可以检测到碰撞,一种是一方是刚体+碰撞器和另一方碰撞器碰撞(参加碰撞器和刚体),另一种就是Character Controller与其他的碰撞器碰撞的时候


在使用摄像机游览场景的时候,虽然需要去碰撞检测,但是一个特别的要求就是摄像机和其他物体碰撞之后不能对它们产生任何力的作用,同时摄像机本身也不需要受到模拟真实碰撞的反作用力,也就是说这个时候给摄像机挂载刚体属性还是不大适合的


这个时候Character Controller就被制作出来满足这种需求,Character Controller本身自带一个碰撞器,无需刚体即可完成触发(Trigger)和碰撞(Collision)功能。


使用

使用character controller来控制摄像机的移动,可以获取更加丰富的碰撞信息,完成更好的控制。


要使用角色控制器,首先将Character Controller 组件挂载到目标对象上,一般是摄像机的父节点,然后同时添加一个脚本,脚本获取Character Controller组件实例,并且在Update或者FixedUpdate函数中调用controller.Move更新控制器的位置(同时也会移动子节点摄像机的位置),假如与其他的碰撞器发生碰撞之后,角色控制器会被阻挡前进,同时会触发OnControllerColliderHit 函数。需要注意的是

OnControllerColliderHit要被触发,需要在同一脚本中同时要调用角色控制器的Move函数。character controller与其他的碰撞器发生碰撞后,会自动调用函数

void OnControllerColliderHit (ControllerColliderHit hit)


ControllerColliderHit

ControllerColliderHit is used by CharacterController.OnControllerColliderHit to give detailed information about the collision and how to deal with it.

Variables

collider

The collider that was hit by the controller.

controller

The controller that hit the collider.

gameObject

The game object that was hit by the controller.

moveDirection

Approximately the direction from the center of the capsule to the point we touch.

moveLength

How far the character has travelled until it hit the collider.

normal

The normal of the surface we collided with in world space.

point

The impact point in world space.

rigidbody

The rigidbody that was hit by the controller.

transform

The transform that was hit by the controller.


示例

创建一个空游戏对象FpsController,给它添加CharacterController组件,同时添加一个摄像机作为它的子成员,同时将如下代码挂到FpsController上

[RequireComponent (typeof(CharacterController))]
public class FPSNavigator : MonoBehaviour 
{


	public KeyCode mKeyLeft = KeyCode.LeftArrow;
	public KeyCode mKeyRight = KeyCode.RightArrow;
	public KeyCode mKeyForward = KeyCode.UpArrow;
	public KeyCode mKeyBackward = KeyCode.DownArrow;
	
	public float mKeyStrokeMoveStep = 0.07f;	//metre

	private CharacterController controller;
	private Vector3 mMoveDir ;
	
	void Start () {
	
		controller = GetComponent();

	}
	
	// Update is called once per frame
	void Update () {
	
		Vector3 vDir = Vector3.zero;
		if(Input.GetKey(mKeyLeft))
		{
			vDir.x -= mKeyStrokeMoveStep;
		}
		if(Input.GetKey(mKeyRight))
		{
			vDir.x += mKeyStrokeMoveStep;
		}

		if(Input.GetKey(mKeyForward))
		{
			vDir.z += mKeyStrokeMoveStep;
		}
		if(Input.GetKey(mKeyBackward))
		{
			vDir.z -= mKeyStrokeMoveStep;
		}
		mMoveDir = transform.rotation*vDir;

		controller.Move(mMoveDir);
	
	}
}




你可能感兴趣的:(Unity3d)