// Unity學(xué)習(xí)筆記(零基礎(chǔ)入坑),自用的同時也許也能幫助別人
// 初學(xué)者,沒太多編程基礎(chǔ),所以難免可能會有寫錯的地方,請見諒
//詳細(xì)教程視頻都有,筆記只記重點

官網(wǎng)教程鏈接:http://unity3d.com/cn/learn/tutorials/projects/2d-roguelike-tutorial/project-introduction?playlist=17150
這個中文版的教程講的也很詳細(xì):http://tieba.baidu.com/p/4335701141
我本來是兩個配合著看的,不過兩個版本的腳本寫法不大一樣,后面就以官網(wǎng)教程為主了。
一、創(chuàng)建主角和敵人的動畫
如何創(chuàng)建幀動畫?
直接選中所有幀拖到物體上(或直接拖到 Hierarchy),會自動生成動畫和動畫控制器。
每個Object對應(yīng)一個動畫控制器(Animation Controller),里面包含多個動畫。
分別把閑置動畫、攻擊動畫和受傷動畫的幀拖上去,生成各自的動畫文件。
同類角色控制器的共用
在AnimatorController目錄下,Creative-->Animator Override Controller創(chuàng)建一個控制器的重寫副本(本例為Enemy2),將原版控制器(Enemy1)拖入controller項中。再將Enemy2的閑置和攻擊動畫拖入對應(yīng)項中,完成重寫。

這一步的總流程:
1.創(chuàng)建player,將主角的3種動畫拖到player上
2.將生成的動畫文件和動畫控制器文件放到對應(yīng)目錄下(Assets-Animation-Animations&AnimatorControllers)
3.打開主角動畫控制器,修改閑置動畫(Idle)的速度為0.5
4.player物體拖入prefabs,刪除場景中的
(player加box collider、rigidbody)
5.同上創(chuàng)建enemy1及動畫,并拖入prefabs
(enemy1加box collider、rigidbody)
6.場景中的enemy1直接改成enemy2,拖入enemy2的動畫,但在控制器中刪除這兩個動畫
7.用上文方法,創(chuàng)建控制器enemy1的重寫enemy2,并將剛才創(chuàng)建的enemy2的動畫拖入對應(yīng)項
完成!
2016.07.31
二、創(chuàng)建地面、障礙物和道具
地板、墻、道具,拖入場景由sprite轉(zhuǎn)為Game Objects,配置SortingLayer、Collider、tag、Layer,拖入prefabs轉(zhuǎn)為預(yù)制件。
三、用于生成地圖的地圖管理器
這可以算是一個關(guān)卡生成器。
目標(biāo)是什么?
- 自動生成地板、圍墻(為什么不手動擺?1.省事 2.有隨機變化):位置固定、內(nèi)容隨機
- 自動生成障礙墻、道具、敵人:位置隨機、內(nèi)容隨機、數(shù)量隨機,但都有限制,并且敵人數(shù)量隨關(guān)卡增加
- 順便把出口exit也給生成了:不需要隨機
實現(xiàn)目標(biāo)的思路?
內(nèi)容隨機:從物體組中隨機選取即可(objectArray[Random.Range(0, objectArray.Length)])
位置隨機:將位置轉(zhuǎn)化為一個Vector3的List,從中隨機選取即可
? ? ? ? ? ? ? ? 常用list.Add(); ? list.RemoveAt(); ? list.Count; ? list[]
數(shù)量隨機:在設(shè)定好的最大最小值之間隨機選取即可
需特殊處理的:對于敵人的數(shù)量,以level為變量通過函數(shù)計算即可
? ? ? ? ? ? ? ? ? ? ? 使用list.RemoveAt()來避免,在一個位置上重復(fù)放東西
//這樣寫完感覺其實so easy啊 :目
具體怎么操作?
最終這個腳本包含了5個函數(shù),只有最終的SetScenes是public的,其余都是內(nèi)部使用。
沒有使用Start和Update,所以唯一的運行條件就是SetScenes被調(diào)用(交給GameManager了)。
void InitialiseList()? ? //函數(shù)1,地圖坐標(biāo)列表初始化函數(shù),用于放障礙、道具、敵人
void BoardSetup()? //函數(shù)2,鋪地板、圍墻
Vector3 RandomPosition() //函數(shù)3,自動選取放障礙、道具、敵人的隨機位置,調(diào)用函數(shù)1中的變量
void LayoutObjectAtRandom(GameObject[] tileArray, int minimum, int maxmum) //函數(shù)4,擺放障礙、道具、敵人,調(diào)用函數(shù)3
public void SetupScene(int level) //函數(shù)5,完成關(guān)卡場景的布置,調(diào)用函數(shù)1、2、4






補充材料:
coding中關(guān)于類、對象、屬性、方法的概念:
http://liuyuru.iteye.com/blog/806705
關(guān)于List:
List存放的是單一的數(shù)據(jù)類型的數(shù)據(jù)(ArrayList可以存放不同類型的數(shù)據(jù))
本例創(chuàng)建了一個Vector3的list(gridPosition),(x,y)從(1,1)到(6,6),可從中隨機選取格子放置障礙、道具或敵人。

教程中的坐標(biāo)零點選的是圍墻內(nèi)左下角

2016.08.06 凌晨 沒有編程基礎(chǔ)學(xué)起來會慢一些,但是這種不斷學(xué)東西的感覺很好
四、游戲控制器 —— Game Manager
加上Game Manager之后,就可以測試地圖生成器的效果了。
以level 3為例,Awake里獲取到Board Manager,然后運行下SetupScene就已經(jīng)可以測地圖生成的效果了:(Inspector中要把變量對應(yīng)的prefabs拖進(jìn)去)

效果如下,因為是從(-1,-1)點開始擺的所以偏的

調(diào)下鏡頭位置和背景色

之后要做的,是保證Game Manager是一個單例(singleton),即只會存在一個instance。因為之后Game Manager會被做成prefab。我目前的理解是,全局使用的物體會需要使用這種單例模式,因為在被調(diào)用時有產(chǎn)生多個的可能性。(此處理解不到位,待學(xué)習(xí))

返回unity,把Game Manager拖入prefabs,并刪掉場景中的。
做一個Loader來加載Game Manager的實例。
如果當(dāng)前沒有GameManager類的實例,則創(chuàng)建。

Loader掛在Main Camera上,Game Manager拖入變量gameManager中。
---說明----
1. 全局靜態(tài)變量
public static GameManager instance = null; ?
靜態(tài)變量屬于類本身而不是類的實例。全局靜態(tài)變量可在任何時候被任何腳本調(diào)用。
所以即使在Game Manager未被實例化時,Loader也可以調(diào)用instance!
This means that we can now access the public functions and variables of our game manager from any script in our game.
關(guān)于靜態(tài)變量:
靜態(tài)變量屬于靜態(tài)存儲方式,其存儲空間為內(nèi)存中的靜態(tài)數(shù)據(jù)區(qū)(在 靜態(tài)存儲區(qū)內(nèi)分配存儲單元),該區(qū)域中的數(shù)據(jù)在整個程序的運行期間一直占用這些存儲空間(在程序整個運行期間都不釋放),也可以認(rèn)為是其內(nèi)存地址不變,直 到整個程序運行結(jié)束(相反,而auto自動變量,即動態(tài)局部變量,屬于動態(tài)存儲類別,占動態(tài)存儲空間,函數(shù)調(diào)用結(jié)束后即釋放)。靜態(tài)變量雖在程序的整個執(zhí)行過程中始終存在,但是在它作用域之外不能使用。
http://www.cnblogs.com/dongzhiquan/archive/2009/07/21/1994792.html
2. 單例模式
if (instance == null) ? ? ? ?
? ? instance = this;
else if (instance != this)
? ? Destroy(gameObject);
如果GameManager類的實例instance為空,則把當(dāng)前GameManager類的實例(當(dāng)前物體)賦予instance,如果instance不是當(dāng)前這個實例,就銷毀當(dāng)前這個物體(當(dāng)前這個實例)。
如果現(xiàn)在生成了一個GameManager的實例a,靜態(tài)變量instance則被賦予實例a,這時又生成了一個GameManager的實例b,這時在實例b中,instance就不等于this(this是實例b),于是實例b就會被銷毀。
關(guān)于單例:
http://www.cnblogs.com/gameprogram/archive/2012/10/24/2736856.html
http://www.360doc.com/content/15/0418/20/12109864_464203821.shtml
3.DontDestroyOnLoad
DontDestroyOnLoad means that when we?load a new scene, normally all of the?game objects in the hierarchy will be destroyed.?Because we want to use the GameManager to?keep track of the score between scenes?we don't want it to be destroyed at that point.?And so we're going to use DontDestroyOnLoad?to make sure that it will persist between scenes.
---
為什么需要單例模式?
為什么要用一個Loader來調(diào)用Game Manager?
這些都還不太懂
2016.08.07 @@ 朦朧地理解了全局靜態(tài)變量和單例模式,GOOD!