【recast-navigation-js】使用three.js辅助绘制Agent

说在前面

  • 操作系统: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有时候会失败,有时候感觉位置不对,得再看看是啥问题
  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值