碰撞形状(ColliderShape)定义了碰撞器的物理外形。Galacean 提供了多种基础碰撞形状,可以通过组合这些形状来构建复杂的碰撞区域。
形状类型 | 特点 | 后端支持 |
---|---|---|
BoxColliderShape | 最基础的碰撞形状 适用于方形、矩形物体 可以通过 size 属性调整三个轴向的大小 | 所有物理后端 |
SphereColliderShape | 用于球形物体的碰撞检测 通过 radius 属性设置半径 | 所有物理后端 |
PlaneColliderShape | 无限大的平面碰撞体 通常用作地面 | 仅 physics-physx 后端 |
CapsuleColliderShape | 由圆柱体和两个半球组成 适用于角色碰撞器 可以设置 radius 和 height | 仅 physics-physx 后端 |
属性 | 描述 | 默认值 |
---|---|---|
staticFriction | 物体静止时的摩擦系数,值越大物体越难开始移动 | 0.6 |
dynamicFriction | 物体运动时的摩擦系数,值越大物体移动时受到的阻力越大 | 0.6 |
bounciness | 碰撞反弹程度,取值范围 0-1,0 表示完全不反弹,1 表示完全弹性碰撞 | 0 |
bounceCombine | 定义两个碰撞物体的弹性系数如何组合:
| Average |
frictionCombine | 定义两个碰撞物体的摩擦系数如何组合:
| Average |
有关碰撞和触发器事件的详细信息,请参阅碰撞事件文档。
// 创建盒形碰撞器
const boxShape = new BoxColliderShape();
boxShape.size = new Vector3(1, 1, 1);
boxShape.position = new Vector3(0, 0.5, 0);
// 创建球形碰撞器
const sphereShape = new SphereColliderShape();
sphereShape.radius = 0.5;
sphereShape.position = new Vector3(0, 1, 0);
// 创建胶囊体碰撞器
const capsuleShape = new CapsuleColliderShape();
capsuleShape.radius = 0.5;
capsuleShape.height = 2;
// 创建平面碰撞器
const planeShape = new PlaneColliderShape();
// 获取所有形状
const shapes = staticCollider.shapes;
// 增加形状
const boxShape = new BoxColliderShape();
staticCollider.addShape(boxShape);
// 移除特定形状
staticCollider.removeShape(boxShape);
// 清空所有形状
staticCollider.clearShapes();
// 创建物理材质并配置属性
const material = new PhysicsMaterial();
material.staticFriction = 0.6; // 静摩擦系数
material.dynamicFriction = 0.4; // 动摩擦系数
material.bounciness = 0.5; // 弹性系数
// 设置材质的组合模式
material.frictionCombine = PhysicsMaterialCombineMode.Average; // 摩擦力组合方式
material.bounceCombine = PhysicsMaterialCombineMode.Maximum; // 弹性组合方式
// 将材质应用到碰撞形状
const shape = new BoxColliderShape();
shape.material = material;
// 为不同的形状设置不同的材质
const iceShape = new BoxColliderShape();
const iceMaterial = new PhysicsMaterial();
iceMaterial.staticFriction = 0.1;
iceMaterial.dynamicFriction = 0.05;
iceMaterial.bounciness = 0;
iceShape.material = iceMaterial;
const bounceShape = new SphereColliderShape();
const bounceMaterial = new PhysicsMaterial();
bounceMaterial.bounciness = 0.8;
bounceMaterial.bounceCombine = PhysicsMaterialCombineMode.Maximum;
bounceShape.material = bounceMaterial;
// 不再使用时记得销毁材质
material.destroy();
iceMaterial.destroy();
bounceMaterial.destroy();
// 创建带有多个碰撞形状的物体
function createCompoundCollider(entity: Entity) {
const collider = entity.addComponent(DynamicCollider);
// 主体形状
const mainShape = new BoxColliderShape();
mainShape.size = new Vector3(2, 1, 1);
collider.addShape(mainShape);
// 顶部形状
const topShape = new BoxColliderShape();
topShape.size = new Vector3(1, 1, 1);
topShape.position = new Vector3(0, 1, 0);
collider.addShape(topShape);
return collider;
}
// 创建一个简单的地面
function createGround(width: number, length: number): Entity {
const entity = new Entity();
const collider = entity.addComponent(StaticCollider);
const groundShape = new BoxColliderShape();
groundShape.size = new Vector3(width, 0.1, length);
// 设置地面的物理材质
const material = new PhysicsMaterial();
material.staticFriction = 0.6;
material.dynamicFriction = 0.6;
material.bounciness = 0.0;
groundShape.material = material;
collider.addShape(groundShape);
return entity;
}
// 创建一个无限平面地面
function createInfinitePlane(): Entity {
const entity = new Entity();
const collider = entity.addComponent(StaticCollider);
const planeShape = new PlaneColliderShape();
// 设置地面材质
const material = new PhysicsMaterial();
material.staticFriction = 0.6;
material.dynamicFriction = 0.6;
planeShape.material = material;
collider.addShape(planeShape);
return entity;
}
// 创建一个可配置的墙壁
function createWall(width: number, height: number, depth: number, friction: number = 0.6): Entity {
const entity = new Entity();
const collider = entity.addComponent(StaticCollider);
const wallShape = new BoxColliderShape();
wallShape.size = new Vector3(width, height, depth);
// 设置墙壁的物理材质
const material = new PhysicsMaterial();
material.staticFriction = friction;
material.dynamicFriction = friction;
material.bounciness = 0.0;
wallShape.material = material;
collider.addShape(wallShape);
return entity;
}
// 创建一个带摩擦力的斜坡
function createSlope(width: number, height: number, angle: number): Entity {
const entity = new Entity();
const collider = entity.addComponent(StaticCollider);
const slopeShape = new BoxColliderShape();
slopeShape.size = new Vector3(width, 0.1, height);
slopeShape.rotation = new Vector3(0, 0, angle);
// 设置斜坡的物理材质
const material = new PhysicsMaterial();
material.staticFriction = 0.8; // 较大的摩擦力防止物体滑落
material.dynamicFriction = 0.8;
material.bounciness = 0.0;
slopeShape.material = material;
collider.addShape(slopeShape);
return entity;
}
// 创建一个混合材质的平台
function createMixedPlatform(): Entity {
const entity = new Entity();
const collider = entity.addComponent(StaticCollider);
// 创建主平台(普通摩擦力)
const platformShape = new BoxColliderShape();
platformShape.size = new Vector3(10, 0.5, 10);
const normalMaterial = new PhysicsMaterial();
normalMaterial.staticFriction = 0.6;
normalMaterial.dynamicFriction = 0.6;
platformShape.material = normalMaterial;
collider.addShape(platformShape);
// 添加冰面区域(低摩擦力)
const iceShape = new BoxColliderShape();
iceShape.size = new Vector3(3, 0.51, 3);
iceShape.position = new Vector3(3, 0, 0);
const iceMaterial = new PhysicsMaterial();
iceMaterial.staticFriction = 0.1;
iceMaterial.dynamicFriction = 0.05;
iceShape.material = iceMaterial;
collider.addShape(iceShape);
// 添加弹性区域
const bounceShape = new BoxColliderShape();
bounceShape.size = new Vector3(3, 0.51, 3);
bounceShape.position = new Vector3(-3, 0, 0);
const bounceMaterial = new PhysicsMaterial();
bounceMaterial.bounciness = 0.8;
bounceMaterial.bounceCombine = PhysicsMaterialCombineMode.Maximum;
bounceShape.material = bounceMaterial;
collider.addShape(bounceShape);
return entity;
}
形状选择
性能优化