鍓嶈█3D娓告垙锛屾€讳細鏈変富瑙掋€傛垜浠彲浠ラ€氳繃鐐瑰嚮娓告垙涓殑鍏朵粬鍦版柟锛岃娓告垙涓昏绉诲姩鍒拌鐐瑰嚮鐨勫湴鏂广€傞偅涔堝綋鎴戜滑瑕佸疄鐜颁竴涓€滅偣鍑诲湴闈紝瑙掕壊绉诲姩鍒扮偣鍑荤殑鍦版柟鈥濈殑鍔熻兘鏃讹紝闇€瑕佸摢浜涘墠缃潯浠讹紝鍙堟槸濡備綍瀹炵幇鐨勫憿锛熸湰鏂囧甫浣犱竴姝ユ瀹炵幇瑙掕壊杈硅蛋杈圭Щ鍔ㄧ殑鍔熻兘锛屽悓鏃舵敼鍙樼姸鎬併€?銆侀楠煎姩鐢婚楠煎姩鐢诲張绉伴楠煎姩鐢伙紝鏄竴绉嶅皢涓夌淮妯″瀷鍒嗕负涓ら儴鍒嗙殑璁$畻鏈哄姩鐢绘妧鏈細鐢ㄤ簬缁樺埗妯″瀷鐨勭毊鑲わ紙Skin锛夊拰鐢ㄤ簬鎺у埗鍔ㄤ綔鐨勯楠笺€備竴鑸?D娓告垙涓殑涓昏锛屽叾濂旇窇銆佽璧般€佺珯绔嬬瓑鍔ㄤ綔閮芥槸妯″瀷鏂囦欢鐨勯楠煎姩鐢汇€傛敼鍙橀楠煎姩鐢荤殑鏉冮噸鍙互璁╁姩鐢讳箣闂寸殑杩囨浮鏇村姞鑷劧銆傛瘮濡傚湪浣撹兘娴嬭瘯涓紝褰撲綘鍒拌揪缁堢偣鏃讹紝浣犱細閫愭笎鍑忛€燂紝璺戞鐨勫姩浣滃箙搴︿細瓒婃潵瓒婂皬锛岀劧鍚庡彉鎴愭琛岋紝鏈€鍚庡仠涓嬫潵銆傛垜浠潵鐪嬩竴涓袱涓姩浣滄潈閲嶆搴︾殑渚嬪瓙锛氭湰渚嬩腑锛屼粠浼戦棽鍒拌璧帮紝浼戦棽鍔ㄧ敾鐨勬潈閲嶄粠1閫掑噺鍒?锛岃€岃璧板姩鐢荤殑鏉冮噸浠?閫掑鍒?銆傚彲浠ュ湪鏈珯鐐瑰嚮馃憠>Crossfading>浠庨棽缃埌璧拌矾鏉ヤ綋楠屽惂銆傚湪杩欐3D娌欑洅娓告垙涓紝瑙掕壊鐘舵€佺殑鍙樺寲涓昏鏄紶鏍囩偣鍑诲湴闈㈠悗锛岃鑹蹭粠浼戦棽鐘舵€佸彉涓哄璺戠姸鎬侊紝褰撹鑹插埌杈剧洰鐨勫湴鍚庯紝鍐嶆鍙樹负浼戦棽鐘舵€併€傛垜浠潵鐪嬬湅杩欎簺鐘舵€佸彉鍖栨槸濡備綍瀹炵幇鐨勩€傞鍏堬紝鎴戜滑闇€瑕佽璁¤€呮彁渚涗竴涓甫鏈夐楠煎姩鐢荤殑妯″瀷锛屽畠鏈変袱绉嶉楠煎姩鐢伙紝涓€绉嶇敤浜庣┖闂诧紙idle锛夌姸鎬侊紝涓€绉嶇敤浜庤繍琛岋紙run锛夌姸鎬併€?.1鎬濊矾1.2鍔ㄧ敾鍒濆鍖栬鎴戜滑鎶婇楠煎姩鐢汇€佸姩鐢诲悕绉般€佹潈閲嶅悎璧锋潵瀛樺偍鍦ㄤ竴涓璞′腑锛宨dleAnimConfig={name:string;鍔ㄧ敾锛氬姩鐢荤粍锛泈eight:number;}閭d箞濡備綍鍒ゆ柇鏄惁鍦ㄨ璧板憿锛熷畠闇€瑕佸綋鍓嶅姩鐢荤殑鏍囧織銆傚垵濮嬪寲鏃讹紝璁剧疆idle涓哄綋鍓嶅姩鐢汇€俢urrentAnimConfig=idleAnimConfig1.3鍔ㄧ敾鏉冮噸鍙樺寲濡傚浘銆傚綋瑙掕壊鐘舵€佸彂鐢熷彉鍖栨椂锛屾垜浠渶瑕佸鍔犲綋鍓嶇姸鎬佺殑鍔ㄧ敾鏉冮噸锛屽噺灏戝叾浠栫姸鎬佺殑鍔ㄧ敾鏉冮噸锛堟敞鎰忔潈閲嶅€奸渶瑕侀檺鍒跺湪[0,1]锛夈€傛垜浠湅浼唬鐮侊紝鍋囪deltaWeight涓烘鏁癱hangeAnimWeight(){//褰撳墠鍔ㄧ敾->澧炲姞if(currentAnimConfig){setAnimationWeight(currentAnimConfig,deltaWeight)}//鍏朵粬鍔ㄧ敾->鍑忓皯锛屾瘮濡備粠绔欑珛鍒囨崲鍒拌璧癷f(currentAnimConfig!==idleAnimConfig){setAnimationWeight(idleAnimConfig,-deltaWeight)}//鍏朵粬鍔ㄧ敾->閫掑噺锛屾瘮濡備粠琛岃蛋鍒囨崲鍒扮珯绔媔f(currentAnimConfig!==runAnimConfig){setAnimationWeight(runAnimConfig,-deltaWeight)}}鐒跺悗鍦ㄦ覆鏌撶殑鏃跺€欙紝杩涜涓€娆$姸鎬佸垏鎹nRender(){if(鍑嗗鍒拌揪鐩殑鍦?{setCurAnimation(runAnimConfig)}else{setCurAnimation(idleAnimConfig)}changeAnimWeight()}1.4缂哄皯鍔ㄧ敾濡傛灉鍙湁涓€涓€庝箞鍔炲湪鍔ㄧ敾缁勪腑杩愯鍔ㄧ敾锛熺瓟妗堣繕鏄竴鏍凤紝鍙槸灏唅dle鍔ㄧ敾鐨勯楠煎姩鐢昏缃负null锛屽儚杩欐牱锛歩dleAnimConfig={name:string;鍔ㄧ敾锛氱┖锛泈eight:number;}鍗充娇鍚庨潰鐢ㄤ袱涓姩鐢绘敼鍙樿鑹叉ā鍨嬶紝涔熷彲浠ラ噸澶嶄娇鐢ㄣ€傚姩鐢荤姸鎬佸垏鎹㈠疄鐜版晥鏋?.琛岃蛋鍜岀Щ鍔ㄦ垜浠钩鏃跺啓鍔ㄧ敾鐨勬椂鍊欙紝浼氫娇鐢╮AF锛岄€掑綊璋冪敤娓叉煋鍑芥暟锛屽疄鐜颁竴甯т竴甯х殑娓叉煋鍔ㄧ敾銆傚綋瑙掕壊鍦ㄥ钩鍦颁笂琛岃蛋鏃讹紝涔熷彲浠ラ€氳繃閫愬抚绉诲姩鏉ュ疄鐜颁綅绉诲姩鐢汇€傛瘮濡俠abylon灏卞凡缁忓皝瑁呬簡render浜嬩欢鐨凙PI锛屾垜浠彧瑕佹妸娓叉煋鍔ㄧ敾缁戝畾鍒皉ender浜嬩欢涓婂氨鍙互浣跨敤浜嗐€傛垜浠潵鐪嬬湅鍏蜂綋鐨勬€濊矾锛?.1杩愬姩浠庝笂闈㈢殑鎬濊矾鍙互鐪嬪嚭锛屾垜浠湪杩愬姩鐨勬椂鍊欓渶瑕佺敤鍒板嚑涓彉閲忥細璺濈缁堢偣鐨勮窛绂伙紙distance锛夊拰杩愬姩鐨勬柟鍚戯紙direction锛夈€傜劧鍚庢垜浠渶瑕佽幏鍙栬繖浜涘彉閲忋€俤istance鍙互閫氳繃鐭╅樀瀵瑰簲鍧愭爣鐨勫姞鍑忚绠楀緱鍒帮紝direction鏄洰鏍囦綅缃噺鍘诲垵濮嬩綅缃殑娉曞悜閲廳irectToPath(){//璁剧疆瑙掕壊鐨勪綅缃负鍒濆浣嶇疆initVec=this.player.position//璁$畻鍒濆浣嶇疆鍜岀粨鏉熺偣涔嬮棿鐨勮窛绂籨istance=Distance(targetVec,initVec)//浠庡垵濮嬩綅缃噺鍘荤粨鏉熶綅缃畉argetVec=targetVec.subtract(initVec)//浣跨敤娉曞悜閲忚绠梔irection=Normalize(targetVec)player.lookAt(targetVec)}onClick(){//...directToPath()}鍦ㄦ覆鏌撴湡闂磋缃崲onRender(){if(distance>READY_ARRIVE){distance-=SPEED//瑙掕壊鍚慡PEED鏂瑰悜绉诲姩璺濈player.translate(direction,SPEED,Space.WORLD)}}浣嶇Щ瀹炵幇鏁堟灉2.2缁撳悎鍔ㄧ敾褰撴垜浠殑杩愬姩缁撳悎妯″瀷鐨勯楠煎姩鐢绘椂锛岃鎴戜滑鐪嬩吉浠g爜锛歰nRender(){if(distance>READY_ARRIVE){distance-=SPEED//瑙掕壊闈㈠悜鏂瑰悜DirectionmovementSPEEDdistanceplayer.translate(direction,SPEED,Space.WORLD)setCurAnimation(runAnimConfig)}else{setCurAnimation(idleAnimConfig)}changeAnimWeight()}浣嶇Щ鍜岀姸鎬佸彉鍖栧疄鐜版晥鏋?.瑙掕壊閬块殰3.1鎬濊矾瑙掕壊琛岃蛋閬块殰锛屽叾瀹炲氨鏄粠璧风偣鍒扮粓鐐癸紝鍔犲叆涓棿鐐广€傚鍥撅紝鎴戜滑鍙渶瑕佽褰曚粠褰撳墠璧风偣鍒扮粓鐐圭殑璺緞鏁扮粍锛屾瘡娆″悜鏁扮粍鐨勭N涓偣璧帮紝灏卞彲浠ヨ浆寮簡銆備笅闈㈡垜浠牴鎹€濊矾鍜屼吉浠g爜缁嗗寲涓€涓嬫楠ゃ€?1)璁板綍璺緞骞跺垵濮嬪寲褰撳墠璺緞绱㈠紩path=getPath(targetVec)prePathIdx=0(2)褰撳埌杈惧綋鍓嶄腑闂寸偣鏃讹紝鍒囨崲鍒颁笅涓€涓腑鈥嬧€嬮棿鐐广€傚綋浣犲埌杈炬渶鍚庝竴涓椂锛屽仠姝nRender(){if(distance>READY_ARRIVE){//...绉诲姩鍜屽姩鐢绘潈閲嶅垏鎹?..}else{switchPath()//...}//...}switchPath(){prePathIdx+=1directToPath()}directToPath(){constcurPath=path[prePathIdx]if(!curPath)return//...瑙掕壊绉诲姩鍜岃浆鍚?..}3.2瀹為檯閬块殰绠楁硶鎺ュ叆鐢?.1鍙煡锛岃鑹茬殑琛岃蛋杩愬姩闇€瑕佽繛鎺ラ伩闅滅畻娉曪紝闇€瑕佺敤鍒扮畻娉曟彁渚涚殑璺緞瑙勫垝鏁扮粍銆傚湪瀹為檯搴旂敤涓紝鎴戜滑鍙渶瑕佸皢浼唬鐮佷腑鐨刧etPath()鏂规硶鏇挎崲涓虹畻娉曡绠楅亾璺殑鏂规硶鍗冲彲銆?.2.1RecastJSPlugin鎺ヤ笅鏉ユ垜浠娇鐢˙abylon鑷甫鐨凴ecast鎻掍欢鏉ヨ缁嗚鏄庡浣曟帴鍏ラ伩闅滅畻娉曘€傛柟娉?鍦╮ecast涓紝鍙互閫氳繃computePath鑾峰彇璺緞锛歝onstclosestPoint=this.navigationPlugin.getClosestPoint(pickedPoint)constpath=this.navigationPlugin.computePath(this._crowd.getAgentPosition(0),closestPoint)鐒跺悗鍒╃敤鎬濊矾3.1閫氳繃Pathindextoggle杩涜绉诲姩銆傛柟娉?recast浼氬厛鍒涘缓涓€涓鑸綉鏍硷紝鐒跺悗閫氳繃娣诲姞agent璁╀粬浠害鏉熷湪杩欎釜瀵艰埅缃戞牸涓紝杩欎簺agent鐨勯泦鍚堢О涓篶rowd銆傚苟涓攔ecast鑷甫浜嗕竴涓Щ鍔ˋPI鈥斺€攁gentGoto銆傛鏃朵笉闇€瑕佽绠楄窛绂诲拰鏂瑰悜锛屼篃涓嶉渶瑕佹墜鍔ㄥ垏鎹㈣繍鍔ㄨ矾寰勩€傝鎴戜滑鐪嬬湅瀹冩槸濡備綍瀹屾垚鐨勩€?1)鍒濆鍖栨彃浠讹紝璁剧疆WebWorker鑾峰彇缃戞牸鏁版嵁锛屼紭鍖栨€ц兘meshnavigationPlugin.createNavMesh([ground,...obstacleList,//obstaclelistmesh],NAV_MESH_CONFIG,(navMeshData)=>{navigationPlugin.buildFromNavmeshData(navMeshData)}this.navigationPlugin=navigationPlugin}(2)鍒濆鍖朿rowd(crowd:Constrains瀵艰埅缃戞牸涓唬鐞嗙殑闆嗗悎)initCrowd(){this.crowd=this.navigationPlugin.createCrowd(1,MAX_AGENT_RADIUS,this.scene)consttransform=newTransformNode('playerTrans')this.crowd.addAgent(this.player锛?pickedPoint)this.crowd.agentGoto(0,closestPoint)(4)鍒ゆ柇鏄惁鍋滄锛屽鏋滀笉鍋滄锛屾敼鍙樿鑹茬殑鏂瑰悜閭d箞濡備綍鏀瑰彉瑙掕壊鐨勬柟鍚戯紝鎴戜滑闇€瑕佷笅涓€涓腑闂寸偣鐨勪綅缃紝璁╄鑹茬湅鐫€瀹冦€傛墍浠ュ洖鍒颁箣鍓嶅垵濮嬪寲鐨勫湴鏂癸紝鍒涘缓涓€涓鑸櫒銆俰nitCrowd(){//...constnavigator=MeshBuilder.CreateBox('navBall',{size:0.1,height:0.1,},this.scene)瀵艰埅鍣ㄣ€俰sVisible=false杩欎釜銆俷avigator=navigator//...}鍦ㄦ覆鏌撹繃绋嬩腑锛屽彲浠ラ€氳繃agent褰撳墠鐨勭Щ鍔ㄩ€熷害鏉ュ垽鏂鑹叉槸鍚﹀仠姝€傛敼鍙樻柟鍚戞槸閫氳繃灏嗗鑸櫒绉诲姩鍒颁笅涓€鏉¤矾寰勭殑涓棿鐐癸紝浠ヤ究瑙掕壊娉ㄨ瀹冦€俹nRender(){//绗竴涓唬鐞嗗璞$殑绉诲姩閫熷害constvelocity=this.crowd.getAgentVelocity(0)//灏嗚鑹茬Щ鍔ㄥ埌浠g悊鐨勪綅缃畉his.player.position=this.crowd.getAgentPosition(0)//璁剧疆瀵艰埅鍣ㄧ殑浣嶇疆绉诲姩鍒颁笅涓€涓偣this.crowd.getAgentNextTargetPathToRef(0,this.navigator.position)if(velocity.length()>0){this.player.lookAt(this.navigator.position)//...}else{//...}//...}4.閬块殰鏁堟灉鐪嬬湅鏈€缁堟晥鏋?.閬囧埌鐨勯棶棰樻暣涓紑鍙戣繃绋嬩笉鏄緢椤哄埄銆傞棶棰橈紝浣犲彲浠ュ弬鑰冧竴涓嬨€?1)骞村吔鍦ㄧЩ鍔ㄦ椂锛屾湁鏃朵細鈥滃埞涓嶄綇鈥濓紝瀵艰嚧瀹冨弽澶嶅仠鍦ㄧ粓鐐癸紱涓?銆傛墍浠ュ彧鑳解€滀粠澶翠笂璧拌繃鍘烩€濓紝鐒跺悗鈥滃線鍥炶蛋鈥濓紝鐩村埌閫熷害闄嶄负0锛屾渶鍚庡仠涓嬨€傛鏃讹紝浣犲彧闇€瑕乭ack锛屽皢agent鐨刴axAcceleration璁剧疆涓烘渶澶э紝璁╁畠鏈変竴绉嶅寑閫熻璧帮紝椹笂鍋滀笅鐨勬劅瑙夈€俥xportconstAGENTS_CONFIG:IAgentParameters={maxAcceleration:1000//...}(2)鍔ㄦ€佸鍑忛殰纰嶇墿濡傛灉鍦烘櫙鍒濆鍖栧悗闅滅鐗╀綅缃彂鐢熷彉鍖栵紝姝ゆ椂闇€瑕侀攢姣佸苟鍒涘缓涓€涓猲avMesh.鏄潪甯歌€楄垂鎬ц兘銆備簬鏄垜浠煡浜嗕笅鏂囨。锛岀湅鍒颁篃鏈夊姩鎬佹坊鍔犻殰纰嶇墿鐨凙PI銆傜珛椹皟鏁翠簡鏂囨。涓殑Playground锛屽彂鐜板彲浠ョ敤浜嗐€備絾鏄綋鎴戜滑鏀惧ぇ闅滅鐗╂椂锛屾ā鍨嬭鍒虹┛浜嗮煈夌湅杩欓噷銆傛墍浠ユ垜鍦ㄥ反姣斾鸡璁哄潧涓婇棶浜嗚繖涓棶棰橈紝20鍒嗛挓鍚庡緱鍒颁簡鍥炲銆傝繖閫熷害馃憤銆傚師鏉ラ渶瑕佽皟鏁碞avMeshParameters鐨刢h/cs/tileSize鍙傛暟鏉ラ€傞厤椤圭洰銆傞偅涔堝鏋滄垜浠兂瑕佸疄鐜伴伩闅滐紝鍒涘缓涓€涓洿蹇殑navMesh锛屾垜浠簲璇ユ€庝箞鍋氬憿锛熷彲浠ョ湅鐪嬭繖绡囨枃绔狅細3D娌欑洅娓告垙閬块殰韪╁潙瀹炵幇鏃呯▼鎬荤粨杩欑瘒鏂囩珷锛屾垜浠粠涓変釜鏂归潰鍏ユ墜锛氶楠煎姩鐢荤殑浠嬬粛鍜屼娇鐢紝妯″瀷鐨勮繍鍔ㄥ拰鐘舵€佸彉鍖栵紝浠ュ強璺緞瑙勫垝鐨勯€傚簲鎬с€傞槓杩颁簡鍦?D娌欑洅娓告垙涓疄鐜拌鑹茶璧扮Щ鍔ㄥ拰鏀瑰彉鐘舵€佺殑鎬濊矾鍜屾楠ゃ€傚笇鏈涙柊浜虹湅瀹屽悗鑳芥棭鏃ヤ笂鎵嬭繖涓姛鑳姐€傚綋鐒讹紝鏈枃浠嬬粛鐨勫疄鐜版柟娉曡繕鏄湁涓€浜涗笉瓒充箣澶勩€傛瘮濡傚彲浠ュ湪鍔ㄤ綔涓姞鍏ュ姞閫熷害锛岃鍔ㄤ綔鍜岀Щ鍔ㄩ€熷害鍖归厤鐨勬洿鑷劧銆傚鏋滃ぇ瀹惰繕鏈夊叾浠栧悎閫傜殑寤鸿锛屾杩庡ぇ瀹剁暀瑷€浜ゆ祦銆傚弬鑰冭祫鏂欓楠煎姩鐢?缁村熀鐧剧锛屽厤璐圭殑鐧剧鍏ㄤ功Babylon.js鏂囨。楂樼骇鍔ㄧ敾鏂规硶|Babylon.js鏂囨。鍚戦噺3|Babylon.js鏂囨。浜虹兢瀵艰埅绯荤粺|Babylon.jsDocumentationWebWorkersAPI璁╀汉缇ゆ櫤鑳戒綋鍖€閫熺Щ鍔?闂-.js娆㈣繋鍏虫敞鍌插厰瀹為獙瀹ゅ崥瀹細aotu.io鎴栧叧娉ㄥ偛鍏斿疄楠屽鍏紬鍙凤紙鍌插厰瀹為獙瀹わ級锛屼笉瀹氭湡鍙戞枃銆?/p>
