PhysX官方手册翻译(Character Controller)

Character Controller

Character Controller – Creation

创建一个角色控制器,第一步要做的事情是决定边界体。就目前来说,PhysX只支持立方体(NxBoxController)和胶囊(NxCapsulesController)。

 

第二,创建一个控制器管理器(controller manager)。如:

NxControllerManager* gManager = NxCreateControllerManager(myAllocator);

注意:控制器管理器是单件(同一时间只存在一个实例)。

 

第三、创建一个角色控制器。如:

       NxScene* scene;

       NxCapsuleControllerDesc desc;

       <填充控制器描述符>

       NxController* cpController = gManager->createController(scene,desc);

 

当你不需要控制器管理器的时候,应该释放它。

NxReleaseControllerManager( gManager);

 

注意:以前的类名“ControllerManager”现在也有效,但是不建议使用,并且它将在下一个版本被取消掉。

 

Character Controller - Update

每一贞都可以调用以下函数来移动角色。

NxController::move(constNxVec3& disp,
    
    
NxU32 activeGroups,

NxF32 minDist,

NxU32& collisionFlags,

NxF32 sharpness=
    
    
     
     1.0f
    
    ,

const NxGroupsMask* groupsMask=NULL);
     
     

 

Disp 位移向量

activeGroups 碰撞组掩码

minDist:最小距离,角色的位移低于这个值将不发生位移。

collisionFlags:碰撞检测类型掩码

sharpness:锐度?

groupsMask?

 

Graphics Update

在每一贞里,可以通过角色控制器的position信息来保持外观模型的位置同步。一个控制器从来都不管旋转的事。因此也只能得到位置相关的信息。如:

 

const NxVec3& NxController::getPosition() const;

 

把这个信息传递给你的世界坐标矩阵,然后去渲染,这样你的角色位置就是经过碰撞检测修正过的,并且表现出更加平滑的移动。

 

Character Controller - Volume

角色使用的边界体只限于PhysX提供的标准几何体。

目前只支持2种不同的形状:

AABB:轴对齐的边界盒。由一个position和一个extents向量定义。这个盒子不会随着角色的旋转而旋转,始终是与世界的XYZ 3个轴对齐的。

Capsule:胶囊。由一个position, 一个 height 一个 radius定义。(2个球+1个圆柱)。它可以获得更加平滑的移动,但是也会稍微多花些CPU时间。

 

注意:在版本2.3之前,有一个 球型控制器 NxSphereController,但是自从有了胶囊,它就被抛弃了。

 

注意:两种控制器都使用 Sweep API ,这就意味着并不是所有的可碰撞的形状都可以用于角色运动,只有那些可以被扫描的形状才能用于角色运动的判定。

 

角色碰撞体周围有一层被定义为“皮肤”,它被用来决定是否与其他形状有接触。皮肤的厚度由用户定义。如果为了Debug而显示角色碰撞体,别忘了还有个皮肤的概念。

 

AABB相关变量:

NxControllerDesc::position

NxControllerDesc::skinWidth

NxBoxControllerDesc::extents

 

Capsule相关变量

NxControllerDesc::position

NxControllerDesc::skinWidth

NxCapsuleControllerDesc::radius

NxCapsuleControllerDesc::height

 

关于AABB的一些解释:

皮肤:外表面

Extents:内表面

Character Controller - Auto-Stepping

如果没有自动上台阶(跨越障碍)的功能,地面上一个非常小的台阶都会阻挡角色的移动。显然这不自然,因为如果台阶不是很高的话,我们可以轻松的走上去才对。但是台阶太高了的话,就不应该走上去。这个界定值由以下变量给出:

NxControllerDesc::stepOffset

 

为了实现自动上台阶,PhysX需要知道“上”的方向。当前PhysX只支持3个轴向向量:

NX_X   ( 1, 0, 0 )

NX_Y   ( 0, 1, 0 )

NX_Z   ( 0, 0, 1 )

相关的变量为:

       NxControllerDesc::upDirection

 

Character Controller - Walkable Parts

默认情况下,角色可以走到任何地方。不过在现实世界总是有限制存在。因此,“不允许在角度很大的多边形上走”的限制就有存在的必要。只要用户给出角度界定,PhysX就可以自动的把多边形分为“可以在上面行走的”和“不可以在上面行走的”。将来可能把检测级别推到三角面级别的精确度。

 

可以通过以下变量来设置界定值:

NxControllerDesc::slopeLimit

它是角度的cos。下面的代码规定了只有小于45度的多边形上才可以行走:

slopeLimit = cosf( NxMath::degToRad( 45.0F ));

如果值设置为 0.0f ,该特性就自动关闭(那样的话,角色哪都能走了)

 

这个特性并不总是需要的。一个更加普遍的做法是关掉这个特性,然后使用看不见的墙来限制角色的运动范围。

 

Character Controller - Volume Update

有时候实时的改变角色碰撞体的大小非常有用。比如如果你的角色可以蹲下,那么如果可以把碰撞体的高度减少的话,就可以移动到之前不能去的地方了

 

       角色控制库支持动态更新碰撞体。但是如果不经过检测就直接改变碰撞体大小,很可能会使碰撞体在设置完之后与其他几何体相交或重叠。为了避免这种情况,首先应该调用PhysX为此准备的一些API来进行测试,保证碰撞体有足够的空间来更改大小,只有通过这些API检测之后,才对碰撞体进行更新。

 

AABB相关的函数:

       bool NxBoxController::setExtents( const NxVec3& extents) = 0;

跟胶囊相关的函数:

       bool NxCapsuleController::setRadius(NxF32 radius) = 0;

       bool NxCapsuleController::setHeight(NxF32 radius) = 0;

相关的检测函数:

bool NxScene::checkOverlapSphere();

bool NxScene::checkOverlapAABB();

bool NxScene::checkOverlapCapsule();

 

Character Controller - Callbacks

当控制器发生一些事件的时候,可以设置回调函数。(比如当一个角色撞到了一个形状,或者另外一个角色)

当一个角色碰撞了另外一个形状,可以得到以下信息:

1、  当前控制器

2、  被碰撞的形状

3、  碰撞点

4、  碰撞点的法向量

5、  一个特征码(比如三角形序号)

6、  额外的运动数据。

 

这些信息可以应用于游戏的其他方面,比如播放音效、渲染细节、应用作用力或者别的什么。

注意:现在还不是所有的信息都可以得到,这取决于角色撞上了什么样的形状。最终会支持所有的形状。

 

当一个角色碰撞了另外一个角色,比如一个角色撞到了一个NPC,可以得到以下信息:

1、一对控制器

 

Character Interactions

在游戏中,根据回调函数中返回的不同的动作编号,会产生不用的行为。例如PhysX要是觉得角色足够强壮,那他就可以推动某些箱子。

现在支持的动作编号如下:

NX_ACTION_NONE => 不允许物理(角色推不动对象)

NX_ACTION_PUSH => 允许物理(角色推的动对象)

 

如果给接触点一个作用力,物理引擎就会模拟出自然的推动过程,听起来是非常Cool的。不过这个特性对游戏来说可能会起反作用。边界体的形状是人为控制的,但是你不希望因为从Box控制器切换到Capsule控制器而导致了推动的效果发生变化。推动的效果应该游戏说了算。因此通常比较好的办法是在回调函数中给接触点一个作用力,而不是完全交给物理引擎去计算。另外如果是个胶囊的话,也很难推动一个盒子,因为你几乎不可能对着盒子的中间,推动盒子就会使盒子旋转,虽然你可能只是想把盒子沿直线推一点点。

 

注意:NX_ACTION_PUSH 当前还没有实现,例子中的效果是使用碰撞时提供的信息来实现的。

 

Character Controller - Hidden Kinematic Actors

角色控制库 为每个角色创建了一个隐藏的运动学Actor。有时候这就是引起Actors数量混乱的原因。因此可能得到一个错误的Actor数量,或者在查询Actor的时候,返回了一个未知的Actor

 

当角色控制器处理角色移动的时候,也会同步这个Actor

可以通过以下函数得到这个Actor

       NxActor* NxController::getActor() const;

 

不过,应该避免直接操作这个Actor,这会导致问题。不过只是读取信息则没有问题。

 

Character Controller - Time Stepping

NxCharacter 库里对Actor的操作跟普通的Actor没什么区别。精确的讲,他们使用相同的时间片策略(定长/变长)。当使用定长时间片策略时,会造成一些麻烦。因为NxController总是使用变长时间片策略(大多数情况下,是每贞的间隔)。因此在这种情况下NxController对象并不会跟Actor对象总是精确的同步。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值