Unity官方教程:Roll A Ball(PM版)

這篇文章默認大家已經(jīng)對Unity3D和PlayMaker有一定的了解,所以沒有把所有操作步驟都寫的非常詳細,不太看得明白的同學可以先行閱讀:

視頻教程已經(jīng)上傳YouTube:[教程]使用PlayMaker重制Unity官方“滾動小球”教程
視頻文件及素材資源下載地址在:百度網(wǎng)盤


Unity3D官方教程是非常非常優(yōu)秀的新手入門學習資源,將其PlayMaker化是一個挺有趣的體驗。

本教程是Unity官方教程第一篇,原教程地址:Roll-a-ball tutorial


準備場景

scene_setup_01.png

Roll-a-ball的場景很簡單,一塊2×1×2的藍色Plane做地面(命名為Ground),四個0.5×1×20.5的Cube做墻壁(放在Walls空物體之中),墻壁物體距離坐標原點10單位長度,一個1×1×1的Sphere作為玩家操控的小球(命名為Player)。

scene_setup_camera_01.png
scene_setup_light_01.png

設(shè)置Main Camera的位置和旋轉(zhuǎn),修改Directional Light的位置與旋轉(zhuǎn),得到合適的攝影機位置以及光照效果。

scene_setup_02.png

添加小球運動

給Player添加一個Rigidbody組件。

player_01.png

Rigidbody將游戲物體變成一個“主動剛體”,使其可以受到力的作用而改變其位置和旋轉(zhuǎn),并且會根據(jù)其碰撞體(Collider)組件的設(shè)置而與其他物體相互作用。

Unity中的剛體動力學是這樣劃分的:

  • 沒有添加Collider組件的游戲物體不參與動力學計算;
  • 只有Collider組件且沒有勾選Is Trigger選項的游戲物體被認為是“被動剛體”,不會被動力學改變其運動狀態(tài),也就是說不會被撞開;
  • 勾選了Is Trigger選項的Collider不會起到阻擋其他Collider的作用,也就是不會發(fā)生碰撞現(xiàn)象,但依然能夠感知到其與其他Collider之間發(fā)生的交互作用,比如有其他Collider進入、停留或離開該Collider范圍時,該Collider是能夠感知到的;
  • 有Collider組件也有Rigidbody組件的游戲物體被認為是“主動剛體”,主動剛體會受到動力學作用而改變運動狀態(tài),我們可以給主動剛體施加作用力或設(shè)置運動速度,也可以用其他剛體去撞擊主動剛體;
  • 勾選了Use Gravity(使用重力)選項的Rigidbody會持續(xù)受到重力作用而向-Y方向運動,除非被其他剛體阻擋;
  • 勾選了Is Kinematic(運動學)選項的Rigidbody將忽略外力作用,也就是說重力和剛體撞擊都不會使其產(chǎn)生運動,但我們直接設(shè)置其速度(velocity)來讓其運動起來,算是一種特殊的“主動剛體”吧。

為Player添加Fsm,在State 1中添加Get Axis Vector以獲得輸入向量,添加Add Force為Player施加作用力。

player_fsm_01.png

與控制角色運動不同,控制小球運動我們不僅希望改變其位置,還希望小球能夠“滾動”起來,這時候使用“施加作用力”的方式就比“設(shè)定運動速度”的方式要合適一些。并且,通過“施加作用力”來控制物體(尤其是球形物體)并不能非常精確的控制對象的運動(因為有慣性作用),所以用在這里反而能給游戲添加一些難度和樂趣。

這里我指定了兩個變量,一個speed變量用來設(shè)置小球的運動速度,一個input axis變量用來儲存輸入向量值。speed變量勾選了Inspector選項,使其可以在Inspector中可見。

player_fsm_02.png

添加可拾取的小方塊(Pickup)

在場景中新建一個Cube(改名為Pickup),修改其位移屬性為<<0, 1, 0>>,修改其旋轉(zhuǎn)屬性為<<45, 45, 45>>,修改其縮放屬性為<<0.5, 0.5, 0.5>>,添加一個黃色材質(zhì)給Pickup。

為Pickup添加一個Fsm,在State 1添加一個Rotate:

pickup_fsm_01.png

勾選了Every Frame選項之后,Rotate行為可以按照Vector參數(shù)中所設(shè)定的旋轉(zhuǎn)速度,持續(xù)旋轉(zhuǎn)指定游戲物體。為了獲得平滑的旋轉(zhuǎn)效果,可以勾選Per Second選項和Fixed Update選項,讓其按照“每秒多少度”的方式來進行旋轉(zhuǎn)。

這里我沒有直接輸入旋轉(zhuǎn)速度,而是通過新建一個名稱為rotate speed的變量來控制,rotate speed變量的初始值設(shè)置為<<15, 30, 45>>,并在Inspector中可見。

將設(shè)置好的Pickup物體轉(zhuǎn)換成prefab,然后在場景中復制擺放。新建一個名為Pickups的空物體來放置所有的Pickup物體,以保持場景整潔。

place_pickups_01.png

小球“拾取”黃色方塊

Roll A Ball小游戲的基本交互邏輯是:玩家控制小球在場景中“拾取”所有的黃色小方塊。為了達成這個目的,我們需要進行“碰撞”判定:當小球的碰撞體與黃色方塊的碰撞體相交時,黃色方塊消失。

由于小球和黃色方塊上都具有Collider組件,所以這個判定工作可以被放在小球上,也可以被放在黃色小方塊上。在這個范例中我們選擇將判定工作放在小球上,是因為這個判定是每幀執(zhí)行的,如果放在小方塊上,則所有的小方塊都會每幀執(zhí)行判定操作,顯然執(zhí)行效率不如將判定放在小球這一個物體上。

為Player添加一個Trigger Event,設(shè)定其當有其他Trigger進入小球的碰撞體范圍時,將這個Trigger物體儲存在一個叫做pickup object的變量中,并觸發(fā)hit a pickup事件。

為了避免別的trigger物體的干擾,我們設(shè)定這個Trigger Event行為僅針對那些被Tag為Pickup的Trigger物體起效果。因此,我們需要添加一個名為Pickup的Tag,并將所有的Trigger物體標記上這個Tag。

當hit a pickup事件被觸發(fā)時,Player的Fsm狀態(tài)從State 1跳轉(zhuǎn)為State 2。

payer_fsm_02.png

在State 2中,我們添加一個Activate Game Object,設(shè)置pickup object變量中所儲存的游戲物體(也就是進入了Player碰撞體的Trigger物體)的Activate屬性進行取消操作。

Activate實際上就是游戲物體Inspector面板中名稱前面的小勾選框,如果取消勾選,這個游戲物體就“隱藏”了,或者說“失效”了,雖然依然存在于游戲場景中,卻不會起到任何作用。

payer_fsm_03.png

同時,我們還需要將Pickup物體(黃色小方塊)的碰撞體設(shè)置為Trigger類型(勾選Box Collider組件中的Is Trigger選項),并設(shè)置其為Kinematic(勾選Rigidbody組件中的Is Kinematic選項)。

將小方塊設(shè)置為Trigger類型是因為我們不希望小球和方塊發(fā)生實際碰撞,只希望檢測到雙方相互觸碰而已;將小方塊設(shè)置為Kinematic是因為我們不希望小球在添加了Rigidbody之后受到重力作用而改變其“浮空自動旋轉(zhuǎn)”的運動狀態(tài)設(shè)置。

注意,如果是在場景中對Pickup物體進行的修改,需要點擊Apply按鈕將其修改應(yīng)用到其他所有Pickup物體上,或者直接對prefab物體進行修改。

pickup_inspector_01.png

運行測試,我們現(xiàn)在可以用小球“吃掉”所有的黃色小方塊了。


添加UI

我們希望每“吃掉”一個小方塊,就能夠得到1分,“吃完”所有的小方塊,就可以贏得游戲!

在場景中添加兩個UI Text物體:Score Text和Win Text:

UI_01.png
UI_02.png

可以看到,系統(tǒng)自動創(chuàng)建了一個Canvas,并將UI Text物體放置在Canvas中。同時,系統(tǒng)還創(chuàng)建了一個EventSystem,這兩個自動創(chuàng)建的節(jié)點都不要隨便刪掉。

修改兩個UI Text物體的參數(shù),獲得如下UI顯示:

UI_03.png
UI_04.png
UI_05.png

注意,這時候我們在Inspector中輸入的UI文字內(nèi)容只是一個預設(shè)值,我們后面會用PlayMaker控制其中文字內(nèi)容的。


在Fsm中控制UI顯示內(nèi)容

這時候需要對Player的Fsm進行一些較大的修改了。

payer_fsm_04.png

首先,State 2中需要加入“計分”的功能,并判斷是否所有的Pickup物體都被“吃掉”了。如果是,則跳轉(zhuǎn)到State 4(游戲獲勝狀態(tài)),如果否,則跳轉(zhuǎn)回State 1繼續(xù)游戲。同時,State 2中還需要進行UI文字內(nèi)容更新操作,使其顯示最新的分數(shù)。

其次,需要制作游戲獲勝狀態(tài)State 4,這里需要顯示W(wǎng)in Text。

最后,需要在State 1之前添加一個State 3,在State 3中做一些必要的預設(shè)工作。

State 3

在State 3中:

  1. 用Set Int Value設(shè)置一個score變量,并將其數(shù)值初始化為0;
  2. 用Set Game Object設(shè)置一個score text變量,并指定Score Text物體給score text變量;
  3. 用Set Game Object設(shè)置一個win text變量,并指定Win Text物體給win text變量;
  4. 用Convert Int To String將score變量值轉(zhuǎn)換成一個字符串變量score string,以便指定為UI文字的內(nèi)容;
  5. 用U Gui Text Set Text將score text物體的Text參數(shù)值設(shè)置為“ ”(也就是無內(nèi)容,如果什么字都不打PlayMaker會報錯,所以打個空格就好了);
  6. 用U Gui Text Set Text將win text物體的Text參數(shù)值也設(shè)置為“ ”。

注意:U Gui Text Set Text行為需要自行安裝uGui行為包。

payer_fsm_05.png

在State 2中:

  1. 添加Int Add讓score數(shù)值加1,代表得到1分;
  2. 添加Int Compare比較新的score數(shù)值和一個total pickups變量(手動設(shè)置為12)中的數(shù)值誰大誰小,如果score >= total pickups,則觸發(fā)win事件(跳轉(zhuǎn)到State 4);
  3. 添加Convert Int To String將score變量值轉(zhuǎn)換成一個字符串變量score string,設(shè)置Format參數(shù)使其顯示為“Score: 1”這樣的格式;
  4. 添加U Gui Text Set Text將score string指定給score text物體的Text參數(shù)值,更新score text的顯示內(nèi)容。

注意,Int Compare放在Convert Int To String前面,當“吃到”最后一個小方塊的時候,score text不會更新為Score: 12,因為已經(jīng)直接跳轉(zhuǎn)到State 4了。如果希望在State 4的時候能看到Score: 12這樣的分數(shù)顯示,則需要將Int Compare放在U Gui Text Set Text的后面。

payer_fsm_07.png

在State 4中:

  1. 添加U Gui Text Set Text將win text的文字直接設(shè)置成“You Win!”。

這里其實偷了個巧,懶得去做顯示隱藏Win Text物體的操作,就直接用“ ”來假裝Win Text未出現(xiàn)。

最終的UI顯示效果如下:

final_01.png

到此為止,就完成了Unity官方Roll A Ball教程的PlayMaker化!


一些小改進

發(fā)布游戲之前,添加了一些小改進:

  1. 給小球添加了貼圖,可以清晰看到小球的旋轉(zhuǎn);
  2. 添加了一個RESTART按鈕讓玩家可以重新開始游戲;
  3. 烘焙了光照貼圖;
  4. 添加了一點點后期效果:抗鋸齒、邊緣暗化;
  5. 添加了背景音樂和“吃掉”小方塊時的音效。

WebGL版游戲演示:Roll A Ball


其他的設(shè)計思路

Roll A Ball小游戲非常簡單,但我們可以在這個基礎(chǔ)上開開腦洞,設(shè)計一些其他玩法,比如:

  • 添加復雜的墻壁,修改小方塊布局,以得到不同的關(guān)卡設(shè)計;
  • 設(shè)置墻壁不可觸碰,碰到墻壁則重置游戲;
  • 規(guī)定時限,時限內(nèi)沒有吃到所有的小方塊則任務(wù)失敗;
  • 添加陷阱,比如地面有個洞;
  • 添加機關(guān)、道具,比如傳送門;
  • 為小球添加跳躍行為;
  • 添加坡度,將目前的平面關(guān)卡設(shè)計轉(zhuǎn)換為立體關(guān)卡設(shè)計;
  • ……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內(nèi)容