Unity學(xué)習(xí)筆記 - Roguelike Tutorial(中)

// Unity學(xué)習(xí)筆記(零基礎(chǔ)入坑),自用的同時(shí)也許也能幫助別人

// 初學(xué)者,沒太多編程基礎(chǔ),所以難免可能會有寫錯(cuò)的地方,請見諒

//詳細(xì)教程視頻都有,筆記只記重點(diǎn)

傳送門: ?Unity學(xué)習(xí)筆記 - Roguelike Tutorial(上)

五、讓游戲元素動(dòng)起來


1. 創(chuàng)建了一個(gè)基類

為玩家和敵人提供運(yùn)動(dòng)功能,玩家和敵人的腳本會繼承這個(gè)基類。

public abstract class MovingObject : MonoBehaviour {}

關(guān)于abstract:

The Abstract keyword enables us?to create classes and class members?that are incomplete and must be implemented?in the derived class.

https://msdn.microsoft.com/en-gb/library/sf985hc5.aspx

2.變量

public float moveTime = 0.1f;? ? //移動(dòng) 1 point 的時(shí)間

public LayerMask blockingLayer;? //檢測碰撞的層

private BoxCollider2D boxCollider;

private Rigidbody2D rb2D;

private float inverseMoveTime;


3. 函數(shù)1 - Start函數(shù)


獲取到會用到的變量

4. 函數(shù)2 - 平滑運(yùn)動(dòng)函數(shù) SmoothMovement


使玩家和敵人呈現(xiàn)連續(xù)、平滑的運(yùn)動(dòng)。

輸入目的地的Vector3即可實(shí)現(xiàn)當(dāng)前物體向目的地的連續(xù)、平滑的直線運(yùn)動(dòng)

邏輯:和終點(diǎn)有距離——>向終點(diǎn)方向移動(dòng)一“步”(inverseMoveTime * Time.deltaTime)并刷新距離——>停一幀——> 和終點(diǎn)有距離 ……

Magnitude是向量的長度,sqrMagnitude是長度的平方:

一個(gè)向量V的長度計(jì)算方法是Mathf.Sqrt(Vector3.Dot(v, v))。然而,sqrt計(jì)算是相當(dāng)復(fù)雜的,需要更長的時(shí)間比正常執(zhí)行算術(shù)操作。計(jì)算長度平方來代替直接計(jì)算長度速度更快,除掉開根號計(jì)算是基本相同的。如果你只是使用大小比較的距離,那么你同樣可以比較平方長度大小來比較距離,得到相同的結(jié)果。

http://wiki.ceeger.com/script:unityengine:classes:vector3:vector3.sqrmagnitude

public static?Vector3?MoveTowards(Vector3?current,?Vector3?target, ?float maxDistanceDelta);

MoveToward的作用是將當(dāng)前值current移向目標(biāo)target。(對Vector3是沿兩點(diǎn)間直線)

maxDistanceDelta就是每次移動(dòng)的最大長度。

返回值是當(dāng)current值加上maxDistanceDelta的值,如果這個(gè)值超過了target,返回的就是target的值。

文/fan2b(簡書作者)

原文鏈接:http://www.lxweimin.com/p/6287f18260f5


5. 函數(shù)3 - Move


輸入移動(dòng)方向,返回是否有障礙及障礙物體

沒有障礙則觸發(fā)“平滑運(yùn)動(dòng)函數(shù)” SmoothMovement (有障礙的問題會在后兩個(gè)函數(shù)中處理)

out”在這里被用來讓函數(shù)返回多個(gè)值,即不止返回一個(gè)bool值,還會返回一個(gè)raycastHit2D類型的值(hit)。

The out keyword causes arguments to be parsed by reference. In this case we're using it to return more than one value from our Move function.

boxCollider.enabled = false;

We're going to disable the attached box collider2D to make sure that when we are casting our ray that we're not going to hit our own collider.

hit = Physics2D.Linecast(start, end, blockingLayer);

Physics2D.Linecast會返回一個(gè)RaycastHit2D,即射線檢測到的第一個(gè)物體。


6. 函數(shù)4 - AttemptMove 獲取障礙物


接收Move函數(shù)返回的障礙物,

獲取到障礙物的component并作為參數(shù)傳入函數(shù)5 OnCantMove,并運(yùn)行OnCantMove。

泛類型 <T>

public T GenericMethod <T>?(T param)

在函數(shù)被實(shí)際調(diào)用時(shí),T會被具體的類型替代。

http://unity3d.com/cn/learn/tutorials/topics/scripting/generics

*之所以使用泛類型是因?yàn)椋诶^承類player、和繼承類enemy中障礙的類型是不同的(墻、player)。

泛型類型約束——關(guān)鍵字 where

protected virtual void AttemptMove(intxDir,intyDir) ? ?where T:Component

{ ... }

限定泛類型的范圍

四種限制類型:

Class, Struct, new (), interfaces

https://msdn.microsoft.com/zh-cn/library/bb384067.aspx


7. 函數(shù)5 - OnCantMove

abstract函數(shù),在基類中未定義具體功能,在繼承類中會被重寫,以實(shí)現(xiàn)在不同繼承類中的不同功能。

2016.08.10 這篇腳本?對一個(gè)零編程基礎(chǔ)的“玩家”真心夠復(fù)雜,而我的技巧就是適度地?不 求 甚 解!


六、墻的邏輯


C# Wall,撞一下會碎,撞多了會消失。

墻被撞的時(shí)候,調(diào)用函數(shù)DamageWall就可以了。

返回unity,要把這個(gè)腳本掛在8塊墻上,每塊墻的dmgSprite變量處要放入對應(yīng)的被撞碎的墻的圖片。

七、Player動(dòng)畫控制器設(shè)置


打開Player的Animator Controller。

1. 參數(shù)列表里,新建兩個(gè)trigger,一個(gè)用來觸發(fā)攻擊,一個(gè)用來觸發(fā)受傷。

2. 在PlayerIdle和PlayerAttack之間建立雙向Transitions

PlayerIdle --> PlayerAttack: Has Exit Time不勾選,即觸發(fā)后立即切換動(dòng)畫

PlayerIdle <-- PlayerAttack: Has Exit Time勾選,即當(dāng)前動(dòng)畫結(jié)束后切換動(dòng)畫,Exit Time =1,即完全播完后切換

Transition Duration都改為0,因?yàn)?D的基于sprite的動(dòng)畫切換無法實(shí)現(xiàn)過渡,3D才需要。

3. 觸發(fā)條件設(shè)定:PlayerIdle --> PlayerAttack的Condition選上建好的Trigger

4. PlayerIdle和PlayerDamage同理

動(dòng)畫轉(zhuǎn)換測試:

點(diǎn)擊左下參數(shù)列表里的Trigger即可觸發(fā)相應(yīng)動(dòng)畫:

2016.08.11?


八、Player的腳本 —— 控制player的移動(dòng)


先在GameManager中補(bǔ)充了一些要用到的東西:

幾個(gè)變量
一個(gè)函數(shù)

新建腳本Player

繼承與變量

1. 函數(shù) - Start


重寫基類函數(shù):

protected override void Function ()

? ? { ? ?重寫內(nèi)容……

? ? ?base.Function();

? ? 重寫內(nèi)容……?}

2. 函數(shù) - CheckIfGameOver


3. 函數(shù) - 重寫 AttemptMove


4. 自啟動(dòng)函數(shù) - Update


上圖有個(gè)錯(cuò)誤Horizontal

##兩次栽在Input.GetAxis的這個(gè)“Horizontal”上了,是“Horizontal”不是“Horizonal”啊!

調(diào)用AttemptMove,同時(shí)設(shè)定泛類型T-->Wall,并傳入獲取到的輸入?yún)?shù)。

*泛類型在函數(shù)被執(zhí)行時(shí),需將泛類型具體化。

AttemptMove運(yùn)行時(shí)會調(diào)用基類中的Move函數(shù)和OnCantMove函數(shù),而Move函數(shù)又會調(diào)用SmoothMovement函數(shù)。

Input.GetAxisRaw:

Since input is not smoothed, keyboard input will always be either -1, 0 or 1. This is useful if you want to do all smoothing of keyboard input processing yourself.


5. 函數(shù) - 重寫OnCantMove


6. 函數(shù) - Restart


7. 自啟動(dòng)函數(shù) - OnTriggerEnter2D


8. 自啟動(dòng)函數(shù) - OnDisable


當(dāng)前物體disable的時(shí)候,將分?jǐn)?shù)值傳給GameManager

9. 函數(shù) - LoseFood


當(dāng)前腳本中未被調(diào)用,留在enemy腳本中產(chǎn)生攻擊時(shí)調(diào)用。

最后,Player腳本掛到player上,Blocking Layer選好。

2016.08.12 ?Fighting


九、Enemy的腳本 —— enemy的移動(dòng)和攻擊


1. 繼承MovingObject,重寫Start函數(shù)

獲取自身動(dòng)畫和player的transform。

2. 重寫AttemptMove函數(shù)

增加是否移動(dòng)的判斷,enemy動(dòng)一幀停一幀,不會連續(xù)動(dòng)。

3. 新增函數(shù) MoveEnemy —— 智能判斷趨向player的移動(dòng)方向

這個(gè)函數(shù)的作用是判斷往哪個(gè)方向移動(dòng),先選X or Y,再選 正 or 負(fù)。

MoveEnemy是這個(gè)腳本的核心,它調(diào)用AttemptMove,而AttemptMove則調(diào)用其他基類中的函數(shù)。但enemy腳本中并不包含Update,MoveEnemy會被GameManager調(diào)用。這大概是因?yàn)楫?dāng)前是否讓enemy移動(dòng)的判斷要寫在GameManager里,并且場景中會有多個(gè)enemy。

public void MoveEnemy()

This is going to be called by the GameManager when it issues the order to move to each of our enemies in our Enemies list.


Mathf.Abs()是取絕對值。

這里也凸顯了float.Epsilon作為一個(gè)無限接近于0的數(shù)值的作用。

條件表達(dá)式:

基本格式 ? ? ? ?表達(dá)式1? 表達(dá)式2:表達(dá)式3

1為真則返回2的值,1為假則返回3的值。

http://blog.csdn.net/liyzh_inspur/article/details/3080769

4. 重寫OnCantMove

動(dòng)畫那句應(yīng)該是弄好animator ?controller之后加

最后要返回編輯器把腳本掛在兩個(gè)enemy上,把playerDamage參數(shù)設(shè)定上,還有blockingLayer。

2016.08.13?


十、Enemy動(dòng)畫控制和行動(dòng)觸發(fā)


1. enemy動(dòng)畫控制器

跟player動(dòng)畫控制器的操作基本相同

Enemy1Idle ---> Enemy1Attack :No Has Exit Time,Condition +Trigger "enemyAttack"

Enemy1Idle <--- Enemy1Attack :Has Exit Time, Exit Time = 1

Transition Duration都改為0

2. GameManager中調(diào)度enemy的移動(dòng)


變量:

Awake新加List

每次開始新level,GameManager重新加載,Awake運(yùn)行,清空上一關(guān)的敵人:

加敵人到列表的函數(shù),在enemy腳本中調(diào)用:

協(xié)程,調(diào)用enemy腳本中的移動(dòng)函數(shù):

*為什么如果沒有敵人,要多停一下,player再動(dòng)?不知道。

Update 調(diào)用協(xié)程MoveEnemies,MoveEnemies調(diào)用enemy上的MoveEnemy完成移動(dòng):

2016.08.14

PS: 今天測試的時(shí)候發(fā)現(xiàn),動(dòng)畫Trigger名字的大小寫又搞錯(cuò)了,然后OutWall沒有加Collider

2016.08.15

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

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