您的位置:首页 > 移动开发 > Unity3D

unity character controller 碰撞

2014-05-23 19:03 429 查看

背景

在使用摄像机游览场景的时候,需要控制摄像机不穿透场景中的物体,这需要用到碰撞。在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上

[csharp]
view plaincopy





<span style="font-size:14px;">[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<CharacterController>();

}

// 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);

}
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: