需求
不规则曲面、轨道的爬升与下降,是各种3d游戏项目中,尤其是第一人称游戏的常见需求。
效果展示
实现思路
版本:Cocos Creator 3.1
实现这类需求,本质上可转化为:水平面矢量速度在落脚点平面的投影矢量。而这个过程,Cocos Creator 3.0的api则已经提供,不需要我们自己实现。
实现步骤
- 加meshCollider组件,RPG发射一条垂直向下的射线
- 取得射线的第一个交点,于是可以获得所交平面的法向量normal(法向量可确定一个平面)
- 根据平面速度v0, normal法向量,使用Vec3.projectOnPlane()计算速度分量v1,v1为v0在noraml所代表平面的投影
核心代码
import { _decorator, Component, Node, geometry, Vec3, v3, PhysicsSystem, director } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Move')
export class Move extends Component {
nodeRay: Node = new Node;
moveAmount: Vec3 = new Vec3();
speed: number = 3;
start() {
this.nodeRay = this.node.getChildByName("nodeRay") as Node;
}
update(deltaTime: number) {
let startPos = this.nodeRay.worldPosition;
const outRay = new geometry.Ray(startPos.x, startPos.y, startPos.z, 0, -1, 0);
//默认行走方向,这里为了简便不做键盘左右方向控制
let moveDir = v3(-1, 0, 0).normalize();
let moveRes = new Vec3(moveDir);
if (PhysicsSystem.instance.raycast(outRay)) {
let result = PhysicsSystem.instance.raycastResults[0];
Vec3.projectOnPlane(moveRes, moveDir, result.hitNormal).normalize();
}
this.moveAmount = moveRes.multiplyScalar(this.speed * deltaTime)
}
lateUpdate() {
let originPos = this.node.worldPosition;
console.debug("moveAmount", this.moveAmount);
this.node.setPosition(originPos.add(this.moveAmount));
}
}
小结
不规则地形的行走,最核心的就是理解落脚点法向量、水平面速度、斜坡速度的关系,根据前面两个参数计算出最后一个参数,从而计算位移。以上就是不规则地形行走的实现核心,整体还是比较简单的。