说在前面
- 操作系统:windows 11
- 浏览器:edge版本 124.0.2478.97
- recast-navigation-js版本:0.29.0
- golang版本:1.21.5
使用Tweakpane
fps
面板interface FPSGraph extends BladeApi<BladeController<View>> { begin(): void end(): void } export interface BindingItem { refresh(): void } // Debug export const gui = new Pane() gui.registerPlugin(EssentialsPlugin) export const fpsGraph = gui.addBlade({ view: 'fpsgraph', label: 'fpsgraph', }) as FPSGraph
- 鼠标点击位置
const controlFolder = gui.addFolder({ title: "SceneControl", }) this._sceneCtlBinding = controlFolder.addBinding(this._control, 'target', { format: (x) => x, }) as BindingItem
- 手动刷新值
按理说绑定之后应该要自动刷新界面上的值,但是不知道为啥没有刷新private refreshBinding() { if (this._sceneCtlBinding) { this._sceneCtlBinding.refresh() } }
- 监听事件
public onPointerDown(e: PointerEvent) { var pointer = new Vector2() pointer.set((e.clientX / window.innerWidth) * 2 - 1, - (e.clientY / window.innerHeight) * 2 + 1); this._raycaster.setFromCamera(pointer, this._camera); console.log(pointer) const intersects = this._raycaster.intersectObject(this._navMeshObj); if (intersects.length > 0) { switch (e.button) { case 0: // "Left button clicked."; break; case 1: // "Middle button clicked."; this._control.target = intersects[0].point break; case 2: // "Right button clicked."; this._agent.teleport(intersects[0].point) break; default: // `Unknown button code: ${e.button}`; } } }
- 结果
添加CrowAgent
- agent.ts
import { CrowdHelper } from "@recast-navigation/three"; import { Crowd, CrowdAgent, NavMesh, NavMeshQuery } from "recast-navigation"; import { MeshStandardMaterial, Vector3 } from "three"; export class RecastAgent { private _meshQuery: NavMeshQuery private _crowd: Crowd private _agent: CrowdAgent private _agentTarget: null | Vector3 public crowdHelper: CrowdHelper constructor(mesh: NavMesh) { this._meshQuery = new NavMeshQuery(mesh) this._crowd = new Crowd(mesh, { maxAgents: 1, maxAgentRadius: 0.5, }) const { point: agentPosition } = this._meshQuery.findClosestPoint({ x: 0, y: 0, z: 0 }) this._agent = this._crowd.addAgent( agentPosition, { radius: 0.5, height: 1, maxAcceleration: 1, maxSpeed: 1, } ) this.crowdHelper = new CrowdHelper({ crowd: this._crowd, agentMaterial: new MeshStandardMaterial({ color: 'red' }), }) this._agentTarget = null } public update(delta: number) { this._crowd.update(delta) this.crowdHelper.update() } public teleport(pos: Vector3) { const { point: target, success: ok } = this._meshQuery.findClosestPoint(pos); this._agent.teleport(target); console.log(ok ,pos, target) this._agentTarget = null } public setAgentTarget(pos: Vector3) { const { point: target } = this._meshQuery.findClosestPoint(pos); this._agent.requestMoveTarget(target); this._agentTarget = new Vector3().copy(target as Vector3) } }
- 右键点击事件调用
teleport
函数// ... case 2: // "Right button clicked."; this._agent.teleport(intersects[0].point) break; // ...
- 结果
其他
- 完整代码再等等
findClosestPoint
有时候会失败,有时候感觉位置不对,得再看看是啥问题