前言
该文章主要讲元宇宙虚拟空间的角色状态更新,基本核心技术点
角色状态更新
对角色设置一个位置判断(从中心点向下投射一射线确定角色的位置)
character.feetRaycast();
feetRaycast的start获取碰撞体的位置,end射线结束的位置,
对character 给一个属性,判断rayHasHit在物理世界中判断是否找到与射线相交的物体(返回一个布尔值)
let body = this.characterCapsule.body;
const start = new CANNON.Vec3(body.position.x, body.position.y, body.position.z);
const end = new CANNON.Vec3(body.position.x, body.position.y - this.rayCastLength - this.raySafeOffset, body.position.z);
const rayCastOptions = {
collisionFilterMask: CollisionGroups.Default,
skipBackfaces: true };
//在物理世界中找到与射线相交的物体
this.rayHasHit = this.world.physicsWorld.raycastClosest(start, end, rayCastOptions, this.rayResult);
定义一个角色状态physicsPostStep的处理,角色在物理世界不同状态下的移动速度
比如在斜坡的情况下进行一个处理
//如果碰到了地面,就贴着地面
if (character.rayHasHit)
{
newVelocity.y = 0;
//如果是斜坡,加速度方向指向后面,脚踩的法向量不会指向人物中心点
if (character.rayResult.body.mass > 0)
{
let pointVelocity = new CANNON.Vec3();
character.rayResult.body.getVelocityAtWorldPoint(character.rayResult.hitPointWorld, pointVelocity);
newVelocity.add(Utils.threeVector(pointVelocity));
}
定义一个update时刻监听角色更新的状态,如角色行为的更新(跑步的时候的动作,待机的动作等)
this.behaviour?.update(timeStep);
this.vehicleEntryInstance?.update(timeStep);
this.charState?.update(timeStep);
if (this.physicsEnabled) this.springMovement(timeStep);
if (this.physicsEnabled) this.springRotation(timeStep);
if (this.physicsEnabled) this.rotateModel();
if (this.mixer !== undefined) this.mixer.update(timeStep);