碰撞属性系统

From Valve Developer Community
< Zh
Jump to navigation Jump to search
English (en)中文 (zh)Translate (Translate)
Icon-callout-underlinked.png
This article needs more links to other pages (since Error: Invalid time.). You can help improve navigation by adding links to related documentation, such as entities or tools.

所有可碰撞实体都包含CollisionProperty组件。通过CBaseEntity(en)中的CollisionProp()访问器可操作碰撞功能,主要特性包括:

使用VPhysics(en)的实体还拥有IPhysicsObject接口,提供物理模拟相关的额外碰撞属性。

基础碰撞控制

实体运动时,碰撞属性的固体类型(CollisionProp()->SetSolid())决定使用的碰撞检测基元。

unsigned int CBaseEntity::PhysicsSolidMaskForEntity(void) const方法确定实体与哪些内容类型发生碰撞。多数情况使用CONTENTS_SOLID(en),但可通过内容标志(en)(主要由BSP编译器使用)进行特殊过滤。例如CONTENTS_GRATE(en)栅格材质,对移动实体有效但子弹和视线检测可穿透。

CBaseEntity::m_CollisionGroup决定实体间的碰撞关系,具体规则由CGameRules::ShouldCollide()实现,模组可自定义逻辑。

包围边界

包围边界用于碰撞检测和可见性查询的粗筛阶段。例如射线/盒体检测会先检查碰撞属性的包围边界,再决定是否检测玩家命中盒(hitbox)。因此包围边界必须完全包含所有需检测的命中盒。

默认包围边界是碰撞外壳的包围盒。若碰撞外壳小于命中盒,需通过以下调用扩展边界:

CollisionProp()->SetSurroundingBoundsType(USE_GAME_CODE);

可选参数类型:

enum SurroundingBoundsType_t {
    USE_OBB_COLLISION_BOUNDS = 0,    // 使用OBB碰撞边界
    USE_BEST_COLLISION_BOUNDS,       // 始终使用最佳边界(性能开销最大)
    USE_HITBOXES,                    // 基于命中盒计算
    USE_SPECIFIED_BOUNDS,            // 使用指定边界
    USE_GAME_CODE,                   // 由游戏代码自定义
    USE_ROTATION_EXPANDED_BOUNDS,    // 旋转扩展边界
    USE_COLLISION_BOUNDS_NEVER_VPHYSICS, // 非物理碰撞边界
    
    SURROUNDING_TYPE_BIT_COUNT = 3
};
Note.png注意: 不同边界类型在性能和精度上有显著差异,应根据实际需求选择