角色控制是游戲設(shè)計中必不可少的一個設(shè)計環(huán)節(jié)冈在,這一節(jié)我們講一講如何制作基本的角色運動控制交互邏輯礼搁。
因為是簡單實例教程钓猬,所以一律不涉及角色動畫控制普舆,只談運動控制誊锭。
Demo演示:Simple Movement Control
常見的運動控制交互設(shè)計有這么幾種:
- 方向控制類
- 使用單方向控制角色在特定平面內(nèi)自由運動表悬,角色始終面朝運動方向
- 使用雙方向分別控制角色在特定平面內(nèi)自由運動的位置以及運動方向(“雙搖桿”射擊)
- 使用單方向控制角色在棋盤格內(nèi)非自由運動移動
- 目的地控制類
- 設(shè)置目的地讓角色自動運動過去(“點擊移動”式)
與運動控制息息相關(guān)的是攝影機運動控制,通常會有這么幾種形式:
- 大鳥瞰視角攝影機不運動
- 固定視角攝影機(正俯視丧靡、斜俯視蟆沫、正平視)跟隨或半跟隨角色
- 第三人稱可變視角跟隨攝影機
- 第一人稱主視角攝影機
在Unity3D中,控制游戲物體的運動主要有這樣幾種實現(xiàn)方法:
- 完全依靠物理解算温治,基本不控制:比如我們在PlayMaker簡單實例(1):PM_Cube中最后做的發(fā)射小方塊的例子饭庞,設(shè)置力量、初始速度熬荆,然后就都交給物理引擎去計算了舟山。
- 完全通過transform參數(shù)控制位移和旋轉(zhuǎn):比如我們讓游戲物體永遠(yuǎn)跟隨鼠標(biāo)運動。
- 借助物理引擎進(jìn)行部分控制:
- 對Rigidbody持續(xù)施加動力(force)或持續(xù)設(shè)定速度(velocity)惶看;
- 對Character Controller設(shè)置運動(move)捏顺;
- 對NavMesh Agent設(shè)置運動(move)或設(shè)置目的地(set destination)。
完全依靠物理解算不適合用來進(jìn)行準(zhǔn)確操控纬黎,完全通過位移和旋轉(zhuǎn)參數(shù)進(jìn)行控制很難處理碰撞問題幅骄,所以最后一種方式是我們常用的。方向控制類通常借助Rigidbody或者Character Controller本今,目的地控制類通常借助NavMesh Agent拆座。
范例01:單方向運動控制
分析:
單方向運動控制是持續(xù)不斷給運動物體指明其運動方向和速度,且運動物體始終面向運動方向的一種控制方法冠息,我們用鍵盤方向鍵挪凑、手柄搖桿、甚至用鼠標(biāo)指針位置來為物體指引方向逛艰。
“速度”本質(zhì)上是一個矢量躏碳,其方向代表了運動的方向,其長度代表了運動的快慢散怖。
如果是鍵盤或者手柄的話菇绵,使用input axis就可以獲取一個二維的矢量輸入作為方向指示肄渗,再添加一個自定義的speed屬性就可以了;如果是鼠標(biāo)咬最,則可以用鼠標(biāo)相對于運動物體的位置作為其方向指示翎嫡,鼠標(biāo)離運動物體的距離長短作為速度指示。
準(zhǔn)備場景
依舊沿用PM_Cube的項目文件永乌,新建一個名叫Movement的場景惑申。創(chuàng)建地面,并拼一個簡易的Player角色出來翅雏。
Player角色由一個方塊身體圈驼,一個方塊頭部,再加一個黑球以指示正面方向枚荣。其實用什么模型都可以碗脊,我習(xí)慣于用一個Player
空物體作為頂級節(jié)點,把其他的視覺元素都放在Player
下方橄妆。三個視覺元素的Collider
組件我都刪掉了衙伶,不需要它們進(jìn)行碰撞解算,然后在Player
上添加了一個Box Collider
組件害碾,調(diào)整到合適位置矢劲。
FSM_Movement
為Player
添加Fsm,改名為FSM_Movement
慌随。
在State 1
中添加一個Get Axis Vector
的行為以獲得Axis Input芬沉,再添加一個Set Velocity
的行為給Player設(shè)置速度。
出現(xiàn)這個提示代表我們?nèi)鄙?code>Rigidbody組件阁猜,Set Velocity
只能作用于Rigidbody丸逸,點擊提示自動添加。
在Get Axis Vector
中剃袍,默認(rèn)已經(jīng)把Horizontal Axis
和Vertical Axis
填好了黄刚,這個名稱是和Input面板中的設(shè)置一一對應(yīng)的,大家可以從菜單Edit
> Project Settings
> Input
查看民效。設(shè)置Store Vector
參數(shù)為一個新的變量input axis
憔维,讓Get Axis Vector
把輸入矢量儲存到這個變量中。
比如我們按下AWSD鍵畏邢,由于A
和D
被map到了Horizontal Axis
业扒,W
和D
被map到了Vertical Axis
,因此會造成Horizontal Axis
和Vertical Axis
的輸入值從0快速變成1或者-1(W和D代表正向舒萎,為1程储,A和S代表反向,為-1),然后由于Get Axis Vector
中Map To Plane設(shè)置的是“XZ”章鲤,所以輸出矢量的X值會取得Horizontal Axis
值致板,輸出矢量的Z值會取得Vertical Axis
值,輸出矢量的Y為0咏窿。
在Set Velocity
中可以直接將input axis
變量賦給Vector
參數(shù),然后設(shè)置運動坐標(biāo)系(Space
)為World素征,勾選上Every Frame
選項集嵌。這樣,游戲每時每刻都會監(jiān)控Horizontal Axis和Vertical Axis的輸入御毅,并以此調(diào)整游戲物體的速度根欧。
Get Axis Vector
的Multiplier
參數(shù)會將輸出矢量放大,所以我們也可以為Multiplier
設(shè)置一個新變量speed
端蛆,并在Variable面板中設(shè)置speed
為10凤粗,并使其在Inspector中可見。
測試場景今豆,Player在場景中翻滾嫌拣,這是因為我們給了速度,但物體很輕呆躲,地面摩擦力造成其重心不穩(wěn)容易傾倒(畢竟是剛體物理解算耙熘稹)。
一個解決方法是對其Rigidbody的旋轉(zhuǎn)予以約束插掂,不讓其沿著x軸和z軸旋轉(zhuǎn)灰瞻。
另一個辦法是讓地面變得沒有摩擦力。新建一個Physic Material辅甥,命名為slippery
酝润,拖到場景中賦給Ground
地面物體,然后修改slippery
的運動摩擦(Dynamic Friction
)和靜態(tài)摩擦(Static Friction
)為0璃弄。
我這里選擇第一種方法要销,也就是約束Rigidbody的x軸和z軸旋轉(zhuǎn)。同時我把Player
的speed
值修改為5谢揪,10米/秒的運動速度對于一個1米25高的Player來說有點太快了蕉陋。
接下來添加Player旋轉(zhuǎn)的控制。
在Action Browser里輸入“rotate”拨扶,會出現(xiàn)很多一些關(guān)于旋轉(zhuǎn)的Action凳鬓,但這都不是我們會用到的。實際上患民,適合我們需求的Action的名稱并不包含“rotate”缩举,而是包含“l(fā)ook at”。所以說,對于常用的Action命令還是要記憶一下仅孩,否則連關(guān)鍵字都打不出來就不好了托猩。
在Transform類別下有很多種“Look At”,看名字知道帶“2d”字眼的肯定是用于二維游戲制作辽慕,而帶“Smooth”字眼的很有可能是平滑過渡京腥,而不帶“Smooth”的則可能是突然變化。
選擇Look At
或者Smooth Look At
都可以溅蛉。
Look At
:
讓Game Object
的正面(Z軸正方向)立刻指向目標(biāo)物體(Target Object
)或目標(biāo)坐標(biāo)(Target Position
)公浪,如果Keep Vertical
被勾選,則保證該物體僅繞自身縱軸旋轉(zhuǎn)船侧,否則使用Up Vector
中設(shè)置的方向作為上方欠气。
勾選Draw Debug Line
的話,會在場景視圖中顯示一條Debug Line Color
中所指定顏色的直線以方便判斷是否正確镜撩。
Smooth Look At
:
讓Game Object
的正面(Z軸正方向)按一定速度(Speed
)轉(zhuǎn)向指向目標(biāo)物體(Target Object
)或目標(biāo)坐標(biāo)(Target Position
)预柒,如果Keep Vertical
被勾選,則保證該物體僅繞自身縱軸旋轉(zhuǎn)袁梗,否則使用Up Vector
中設(shè)置的方向作為上方宜鸯。
當(dāng)游戲物體正向與目標(biāo)所在方向達(dá)到Finish Tolerance
允許的接近程度時,觸發(fā)Finish Event
中指定的事件围段。
勾選Debug
時顾翼,會在場景視圖中顯示調(diào)試用指向箭頭。
現(xiàn)在的問題是如何獲得這個Target Object
或者Target Position
奈泪。提供一個思路給大家參考:
如果將Player
自身位置作為坐標(biāo)原點的話适贸,這個方向?qū)嶋H就是我們Input Axis所指向的方向。所以Target Position = Player Position + Input Axis涝桅。在Get Axis Vector
中我們已經(jīng)得到了一個放大過的input axis
變量了拜姿,所以這里直接使用這個值。
在Set Velocity
下方添加一個Get Position
和一個Vector3 Add
冯遂。在Get Position
中獲取Player
的位置蕊肥,儲存在player position
中,然后在Vector3 Add
中把input axis
加給player position
蛤肌,現(xiàn)在這個player position
值就是我們的目標(biāo)點位置壁却。
PlayMaker中用Action來進(jìn)行數(shù)學(xué)計算就是這么混亂,習(xí)慣了就好了裸准。
注意展东,這個Get Position
和Vector3 Add
都是每幀運行的。
最后炒俱,將這個player position
值設(shè)置成Smooth Look At
的Target Position
盐肃。
更簡單一點的辦法是使用
Smooth Look At Direction
行為爪膊,直接把input axis
指定給Target Direction
就好了。
攝影機跟隨
通常這樣的操作方式都會采用俯視攝影機跟隨的方式來設(shè)置視角砸王。
最簡單的一個做法其實是把主攝像機當(dāng)做Player的子物體就好了推盛,但這樣做沒有擴(kuò)展性,比如以后Player加上跳躍的話谦铃,相機視角就會跟著跳起來耘成。
于是更常見的操作是實時根據(jù)Player位置去設(shè)置主攝像機的位置,直接給Player Position加上一個偏移量(offset)就好了驹闰。
選擇Main Camera凿跳,添加Fsm(修改名稱為“FSM_Follow”)
State 1
是用來做初始設(shè)置的,State 2
才是真正用來設(shè)置相機跟隨的狀態(tài)疮方。
用專門的初始狀態(tài)來做預(yù)設(shè)定是PlayMaker的常見做法,比如這個例子里面我們需要在游戲場景中尋找一個叫做“Player”的游戲物體茧彤,這個操作只需要在游戲初始化的時候做一次就行了骡显,所以放在專門的State里面,執(zhí)行完畢就轉(zhuǎn)換到其他State曾掂,以后就不用反復(fù)執(zhí)行這種查找操作了惫谤。
Find Game Object
常常被用作在場景中根據(jù)名稱(Object Name
)來尋找特定游戲物體,同時還可以按照特定標(biāo)簽(With Tag
)來過濾珠洗。找到的游戲物體可以保存(Store
)在一個變量中(這個例子里面我新建了一個player
變量)溜歪。
但要記住的是,如果場景中同時有多個同名游戲物體(比如實時生成的克隆物體就都是一樣的名字)许蓖,
Find Game Object
只會返回所找到的第一個游戲物體蝴猪,而不會把所有的物體信息都保留下來。所以一定要確保場景中不會出現(xiàn)同名的查找對象膊爪。
在State 2
中:
- 添加
Get Position
以讀取player
物體的位置信息自阱,儲存在player position
中; - 然后使用
Vector3 Operator
來計算player position
變量和一個新建的camera offset
變量的相加結(jié)果米酬,并儲存在一個新建的變量camera position
中沛豌; - 最后添加
Set Position
把變量camera position
變量指定給當(dāng)前物體(也就是Main Camera
)。
Vector3 Operator
可以對兩個Vector3類型的變量做很多操作:相加赃额、相減加派、獲取夾角、獲取距離等等跳芳,并將結(jié)果儲存于第三個變量芍锦。我們以后可能會經(jīng)常用到這個行為。具體這個例子中筛严,也可以直接用
Vector3 Add
來做這個相加的計算醉旦,但Vector3 Add
不能指定第三個變量來儲存結(jié)果饶米,而是直接改變第一個變量值,所以如果使用Vector3 Add
的話,后面的Set Position
就需要使用player position
這個變量了(現(xiàn)在的player position
變量所代表的位置,已經(jīng)不是Player所處的位置了纱昧,而是偏移之后的位置程奠。
運行測試,在測試狀態(tài)下可以實時修改camera offset值(因為之前已經(jīng)設(shè)置其在Inspector中可見了)输玷,實時調(diào)整合適的相機位置。
一個比較理想的相機位置是Y = 10,Z = -5逃默,然后相機自身的Rotation X = 60。
(紅色界面表示當(dāng)前處于運行模式)
要注意簇搅,運行模式下所做的修改都在退出運行模式后都不會得到保存完域。一個不是特別完美的解決方案是在點擊相應(yīng)組件(Component)的設(shè)置按鈕(小齒輪圖標(biāo)),然后選擇
Copy Component
瘩将,等退出運行模式以后再同樣點擊“設(shè)置”吟税,選擇Paste Component Values
,這樣就可以把運行模式下該組件的參數(shù)信息應(yīng)用到正常模式下了姿现。
范例02:“雙搖桿”式運動控制
分析:
“雙搖桿”是單方向控制的升級版肠仪,單獨將運動物體的面對方向拿出來用第二個搖桿或者鼠標(biāo)指針來予以控制。
搖桿的話备典,還是使用input axis就可以了异旧;鼠標(biāo)的話,大多利用鼠標(biāo)相對于運動物體的位置矢量做指示提佣,讓物體始終朝向這個鼠標(biāo)的方向吮蛹。
鼠標(biāo)是在攝影機平面運動的,要用鼠標(biāo)來指示運動物體的朝向需要將鼠標(biāo)平面坐標(biāo)轉(zhuǎn)換成三維坐標(biāo)拌屏,因此需要使用Raycast匹涮。
如果角色有動畫,“雙搖桿”式控制就要根據(jù)兩個方向之間的角度來切換運動動畫槐壳,比如人往前走往后走以及側(cè)身走的動畫都是不一樣的然低。
Rigidbody + 雙搖桿
我們可以在上一個范例的基礎(chǔ)上將其改造成“雙搖桿”式運動控制。
將Player
保存成一個prefab务唐,更名為“Player_A”雳攘,這時候場景中的Player
也被自動更名為“Player_A”了。
斷開場景中Player_A
與prefab的聯(lián)接(菜單GameObject
> Break Prefab Instance
)枫笛,再將其名稱改回“Player”吨灭。
在FSM_Movement中,為State 1
添加一個Mouse Pick
行為刑巧。
Mouse Pick
可以幫助我們獲取鼠標(biāo)指針下的游戲物體的相關(guān)信息喧兄,我們這里需要獲得的是鼠標(biāo)指針下地面物體上對應(yīng)點的三維空間位置无畔。
所以我們設(shè)置Mouse Pick
中Store Point
為新建變量mouse point
,設(shè)置Layer Mask
為1吠冤,并在新出現(xiàn)的Element 0
參數(shù)中選擇“Add Layer...”以新建一個叫做“Ground”的“層”浑彰,并選擇這個Ground
層為Element 0
參數(shù)的值。
當(dāng)然我們也可以直接在工具欄的Layer設(shè)置中直接選擇
Edit Layers...
拯辙,或者選擇Ground
物體之后在其Layer設(shè)置中選擇Add Layer...
郭变,都可以打開Layer編輯面板。
別忘了涯保,不管用什么辦法打開層編輯面板添加的新層诉濒,都需要將
Ground
物體指定到這個層中才會起作用。初學(xué)者經(jīng)常指定了新層夕春,然后設(shè)置了層遮罩未荒,卻忘記將游戲物體指定到新層中。
做這樣的設(shè)置是為讓Mouse Pick
行為中發(fā)射的ray只探測Ground層中的物體及志,這樣避免探測到我們的主角茄猫、房屋、甚至UI物體困肩,造成混亂。
此外脆侮,這里這樣做是比較簡化的設(shè)計锌畸,默認(rèn)鼠標(biāo)永遠(yuǎn)都會探測到地面物體,永遠(yuǎn)都會有數(shù)值返回給
Store Point
靖避。
假如鼠標(biāo)探測不到任何有效的物體潭枣,會將Store Point
數(shù)值設(shè)置為<<0, 0, 0>>
,出現(xiàn)跳幀現(xiàn)象幻捏。
想偷懶的話盆犁,就把地面設(shè)大一點,或者干脆設(shè)置一個很大的專門的地面物體不顯示篡九,只用來接受探測谐岁。
Mouse Pick
需要被設(shè)置成每幀運行。
獲得了鼠標(biāo)位置點以后榛臼,就可以將mouse point
變量賦給一個Look At
行為的Target Position
參數(shù)伊佃,讓Player永遠(yuǎn)面向這個位置。
使用Smooth Look At
也可以沛善,但鼠標(biāo)的移動和角色的轉(zhuǎn)向之間就有一點延遲效果了航揉,如果需要這種效果可以選擇Smooth Look At
行為。
我將原來的Smooth Look At Direction
前面的小√去掉了金刁,這樣這個行為就不會起作用帅涂,大家也可以將它刪掉议薪。
運行測試,感覺使用Smooth Look At
的效果更順滑一些媳友,覺得轉(zhuǎn)向太慢可以將Speed
值設(shè)置大一些斯议。為了顯示方便,我勾選了Smooth Look At
的Debug
選項庆锦,并做了一個小球當(dāng)做指示物體(再添加一個Set Position
捅位,用來指示小球的位置為mouse point
即可)。
最終完整的Action結(jié)構(gòu)如下圖:
Character Controller + 雙搖桿
Character Controller是Unity3D提供的一個專門用于角色控制的組件:
-
Slope Limit
:角色能夠爬上多大角度的坡 -
Step Offset
:多高(小于設(shè)定值)的平臺會被認(rèn)為是臺階 -
Skin Width
:兩個角色的碰撞體(Capsule Collider)之間能夠相互穿透多大距離 -
Min Move Distance
:可以移動的最小距離(用來避免輕微抖動) -
Center
:角色的Capsule Collider中心高度 -
Radius
:角色的Capsule Collider的截面半徑 -
Height
:角色的Capsule Collider的高度
Character Controller實際上就是一個不可見的Capsule物體搂抒,角色模型則被放置在這個Capsule物體內(nèi)部艇搀,隨之而動。
下面我們把上面的例子改造成由Character Controller
組件來控制的角色求晶。
將上面例子中的Player
做成Player_B.prefab
焰雕,然后斷開場景中Player的Prefab聯(lián)接,名稱改回Player
芳杏。
刪除掉Box Collider
組件和Rigidbody
組件矩屁,添加Character Controller
組件,設(shè)置好Capsule碰撞體的大小和位置(按上圖)爵赵。
然后在FSM_Movement
中吝秕,刪除Set Velocity
行為,換成Controller Simple Move
行為空幻,把input axis
變量指定給Move Vector
參數(shù),然后把speed
變量指定給Speed
參數(shù)秕铛。
Controller Simple Move
給Character Controller指定一個方向Move Vector
约郁,并設(shè)定一個速度Speed
,Character Controller就可以勻速運動了但两。
角色指向部分的設(shè)置不需要改變鬓梅。
(折疊的Action都沒有修改)
運行測試,發(fā)現(xiàn)角色一跳一跳的谨湘,但從場景視圖來看绽快,角色本身的運動是平滑的,問題貌似發(fā)生在攝影機的跟隨交互邏輯中紧阔。
但是谎僻,攝影機的邏輯很清晰啊:獲取Player位置寓辱,添加offset艘绍,然后設(shè)置Camera位置。
真正的問題出在Character Controller
組件的設(shè)置里秫筏。Min Move Distance
= 0.001的默認(rèn)設(shè)置讓角色的真實運動和其Position屬性并不是完全一致的诱鞠,這樣攝影機在運動剛開始的幾幀里面就會比角色快挎挖。修改Min Move Distance
參數(shù)為0就可以保持同步了。
另一個解決方案是在Player內(nèi)添加一個空物體
Camera Point
航夺,然后讓攝影機不指定Player
而指定這個Camera Point
為其跟隨對象蕉朵。
運行測試場景,一切正常阳掐。
在場景中新建一個Cube物體當(dāng)做障礙物始衅,Player可以和障礙物的Collider相互碰撞。這是因為Character Controller
組件自己就可以被當(dāng)成是一個Capsule Collider缭保。只不過以后要做碰撞檢測的時候需要使用專門的Controller Collision行為汛闸。
為了不要頻繁地修改
Player
名字,我把Main Camera
的Fsm中的State 1
中的Find Game Object
修改了一下艺骂,不指定名字诸老,而是指定Tag,意思是讓其尋找場景中有Player
這個Tag的物體钳恕,通常這個物體都只會有一個别伏。這樣一來,只要我將Player的Tag指定為Player忧额,不論它具體名稱是什么厘肮,都能被這個行為找到。
為場景物體或者Prefab添加Tag都是在Inspector中左上角進(jìn)行添加的睦番,如果需要增加新的Tag类茂,點擊
Add Tag...
,跟添加新的Layer是一樣的操作抡砂。
把這個Player保存成Player_C.prefab
。
范例03:“點擊移動”式運動控制
分析:
“點擊移動”是給定一個目的地恬涧,然后讓運動物體自動移動過去注益。如果不考慮障礙物的因素,這個目標(biāo)很容易達(dá)成溯捆,但如果場景中有障礙物丑搔,“點擊移動”就變得很復(fù)雜了。
這是因為如果希望運動物體繞開障礙物提揍,就必須讓其具有一定的智能啤月,在游戲設(shè)計中我們稱之為“尋路系統(tǒng)”。Unity3D內(nèi)置一個比較簡單的“尋路系統(tǒng)”:Navigation劳跃,主要由Nav Mesh和Nav Agent兩個部分組成谎仲。Nav Mesh生成一個可以行走的范圍區(qū)域,Nav Agent為運動物體計算出一條可行的路線刨仑。
要實現(xiàn)“點擊移動”郑诺,需要將Player設(shè)置成一個Nav Agent夹姥,然后鼠標(biāo)點擊實際上是告訴這個Nav Agent你的目的地在哪里。
Nav Agent不是Rigidbody辙诞,不能使用Set Velocity這樣的行為辙售,但Nav Agent自身也提供了很多方便的函數(shù)給我們使用。
要在PlayMaker中運用這套“尋路系統(tǒng)”飞涂,需要加載一套專門的命令庫旦部。
老規(guī)矩先準(zhǔn)備場景。斷開Player的prefab聯(lián)接较店,然后刪掉Character Controller組件和Fsm組件士八,并在場景中用大方塊拼一些障礙物出來。
為Player添加Fsm泽西,建立如下Graph:
在State 1
中添加Get Mouse Button Down
曹铃,設(shè)置當(dāng)鼠標(biāo)左鍵按下時,觸發(fā)事件LMB Down
捧杉。
在State 2
中添加Mouse Pick
陕见,設(shè)置從鼠標(biāo)位置對Ground
層中的物體發(fā)射Ray,將獲取的點位置儲存在mouse point
中味抖,這個mouse point
就是我們設(shè)置的“目的地”评甜。
再添加一個Move Towards
,設(shè)置Target Position
為mouse point
仔涩,設(shè)置Finish Event
為FINISHED
忍坷,就可以實現(xiàn)“點擊鼠標(biāo)左鍵后Player移動到相應(yīng)點的位置”的需求了。
但是熔脂,Player是沿著直線運動的佩研,不會回避障礙物。
Move Towards
是一個不依賴任何物理學(xué)計算純粹改變物體位移屬性的Action霞揉。它會在物體靠近目的地(距離 <Finish Distance
參數(shù)值)時觸發(fā)Finish Event
中所指定的事件以跳轉(zhuǎn)到其他狀態(tài)旬薯。一旦跳轉(zhuǎn)狀態(tài),
Move Towards
就不再起效果了适秩,物體會立刻停止移動绊序。
刪掉這個Move Towards,下面我們來建立一個簡單尋路系統(tǒng)秽荞。
首先給Player添加一個Nav Mesh Agent組件骤公。
-
Agent Type
:設(shè)置Agent類型,主要是控制Agent能跨上多高的臺階扬跋,爬上多陡的坡 -
Base Offset
:Agent離地高度 -
Speed
:運動速度 -
Angular Speed
:轉(zhuǎn)身速度 -
Acceleration
:最快加速度(值越大阶捆,啟動越快) -
Stopping Distance
:接近目標(biāo)距離多近時停止運動 -
Auto Braking
:如果勾選,Agent在接近目標(biāo)時會自動減速 -
Radius
:Agent碰撞體的截面半徑 -
Height
:Agent碰撞體的高度 -
Quality
:回避障礙物的計算精度,這個質(zhì)量設(shè)置越高越耗費CPU資源趁猴,設(shè)置成None
就不會回避障礙物而是直接撞上去了 -
Priority
:計算資源不夠時優(yōu)先度低的Agent會降低回避障礙質(zhì)量 -
Auto Traverse Off Mesh
:如果需要自行處理角色在Off Mesh Link處的行為的話刊咳,不勾選此選項 -
Auto Repath
:讓Agent到達(dá)分路徑末端時會自動重新計算路徑 -
Area Mask
:可以設(shè)置部分區(qū)域不允許該Agent通過
這個組件中可以通過Radius
和Height
參數(shù)設(shè)置Agent的碰撞體大小。與Character Controller不同儡司,Nav Mesh Agent的碰撞體是圓柱體娱挨。
從菜單Window
> Navigation
打開Navigation面板,
選擇地面捕犬,勾選Navigation Static
跷坝,并將其設(shè)置成Walkable
。
選擇所有的障礙物碉碉,勾選Navigation Static
柴钻,并將其設(shè)置成Not Walkable
。
到Bake面板中點擊Bake
按鈕進(jìn)行Nav Mesh的烘焙垢粮。
-
Agent Radius
:這個值越高贴届,障礙物邊緣不可行走的空檔就越大,最好設(shè)置成所有Agent中最小的那個的半徑值 -
Agent Height
:這個值越高蜡吧,半空中有障礙物的區(qū)域就越可能不可走過毫蚓,最好設(shè)置成所有Agent中最高的那個的高度 -
Max Slope
:最大可行走坡度 -
Step Height
:最大可行走臺階高度 -
Drop Height
:如果這個值為正,就在小于這個高度的兩塊Nav Mesh之間創(chuàng)建“掉落”類型的Off Mesh Link -
Jump Distance
:如果這個值為正昔善,就在小于這個距離的兩塊Nav Mesh之間創(chuàng)建“跳躍”類型的Off Mesh Link
按照上述設(shè)置而烘焙成的Nav Mesh如下圖所示:
藍(lán)色區(qū)域就是可以行走的區(qū)域元潘。
要注意,參與創(chuàng)建Nav Mesh的可行走表面和不可行走表面都需要設(shè)置成
Navigation Static
君仆,一旦被設(shè)置成Navigation Static
翩概,該物體就不能再移動了,也不能播放動畫返咱。
在場景中選擇Player
钥庇,繼續(xù)設(shè)置Fsm。
想要Nav Mesh Agent運動咖摹,可以直接給它設(shè)置一個目標(biāo)评姨,它就會自動尋找合適路線走過去。我們在State 2
中的Mouse Pick
后面添加一個Set Agent Destination
楞艾,將Destination
參數(shù)指定為mouse point
變量参咙。
注意龄广,
Set Agent Destination
這個Action并不包含在PlayMaker的初始安裝文件中硫眯,需要自己去官方WIKI下載適合版本的PathFinding.unitypackage
安裝以后才能正常使用。此外择同,如果希望能夠在
5.6
版本中就使用最新2017.1
的Navigation系統(tǒng)两入,可以去Github上相關(guān)頁面去下載核心腳本,解壓后放進(jìn)工程文件夾就可以了敲才。
運行場景裹纳,我們可以看到Player現(xiàn)在可以自己找路了择葡。
最終的Demo場景我添加了一個Manager,讓每次載入場景的時候都會隨機選擇不同的Player.prefab來載入剃氧,這一部分的具體制作過程就不寫了敏储,搞成隨機的主要原因還是我懶得分成4個不同的場景而已。
項目工程文件(不包括PlayMaker插件及其uGUI擴(kuò)展Action包)