// Unity學習筆記(零基礎入坑),自用的同時也許也能幫助別人
// 初學者,沒太多編程基礎,所以難免可能會有寫錯的地方,請見諒
//詳細教程視頻都有,筆記只記重點
這個中文版的教程講的也很詳細:http://tieba.baidu.com/p/4335701141
我本來是兩個配合著看的,不過兩個版本的腳本寫法不大一樣,后面就以官網教程為主了。
一、創建主角和敵人的動畫
如何創建幀動畫?
直接選中所有幀拖到物體上(或直接拖到 Hierarchy),會自動生成動畫和動畫控制器。
每個Object對應一個動畫控制器(Animation Controller),里面包含多個動畫。
分別把閑置動畫、攻擊動畫和受傷動畫的幀拖上去,生成各自的動畫文件。
同類角色控制器的共用
在AnimatorController目錄下,Creative-->Animator Override Controller創建一個控制器的重寫副本(本例為Enemy2),將原版控制器(Enemy1)拖入controller項中。再將Enemy2的閑置和攻擊動畫拖入對應項中,完成重寫。
這一步的總流程:
1.創建player,將主角的3種動畫拖到player上
2.將生成的動畫文件和動畫控制器文件放到對應目錄下(Assets-Animation-Animations&AnimatorControllers)
3.打開主角動畫控制器,修改閑置動畫(Idle)的速度為0.5
4.player物體拖入prefabs,刪除場景中的
(player加box collider、rigidbody)
5.同上創建enemy1及動畫,并拖入prefabs
(enemy1加box collider、rigidbody)
6.場景中的enemy1直接改成enemy2,拖入enemy2的動畫,但在控制器中刪除這兩個動畫
7.用上文方法,創建控制器enemy1的重寫enemy2,并將剛才創建的enemy2的動畫拖入對應項
完成!
2016.07.31
二、創建地面、障礙物和道具
地板、墻、道具,拖入場景由sprite轉為Game Objects,配置SortingLayer、Collider、tag、Layer,拖入prefabs轉為預制件。
三、用于生成地圖的地圖管理器
這可以算是一個關卡生成器。
目標是什么?
- 自動生成地板、圍墻(為什么不手動擺?1.省事 2.有隨機變化):位置固定、內容隨機
- 自動生成障礙墻、道具、敵人:位置隨機、內容隨機、數量隨機,但都有限制,并且敵人數量隨關卡增加
- 順便把出口exit也給生成了:不需要隨機
實現目標的思路?
內容隨機:從物體組中隨機選取即可(objectArray[Random.Range(0, objectArray.Length)])
位置隨機:將位置轉化為一個Vector3的List,從中隨機選取即可
? ? ? ? ? ? ? ? 常用list.Add(); ? list.RemoveAt(); ? list.Count; ? list[]
數量隨機:在設定好的最大最小值之間隨機選取即可
需特殊處理的:對于敵人的數量,以level為變量通過函數計算即可
? ? ? ? ? ? ? ? ? ? ? 使用list.RemoveAt()來避免,在一個位置上重復放東西
//這樣寫完感覺其實so easy啊 :目
具體怎么操作?
最終這個腳本包含了5個函數,只有最終的SetScenes是public的,其余都是內部使用。
沒有使用Start和Update,所以唯一的運行條件就是SetScenes被調用(交給GameManager了)。
void InitialiseList()? ? //函數1,地圖坐標列表初始化函數,用于放障礙、道具、敵人
void BoardSetup()? //函數2,鋪地板、圍墻
Vector3 RandomPosition() //函數3,自動選取放障礙、道具、敵人的隨機位置,調用函數1中的變量
void LayoutObjectAtRandom(GameObject[] tileArray, int minimum, int maxmum) //函數4,擺放障礙、道具、敵人,調用函數3
public void SetupScene(int level) //函數5,完成關卡場景的布置,調用函數1、2、4
補充材料:
coding中關于類、對象、屬性、方法的概念:
http://liuyuru.iteye.com/blog/806705
關于List:
List存放的是單一的數據類型的數據(ArrayList可以存放不同類型的數據)
本例創建了一個Vector3的list(gridPosition),(x,y)從(1,1)到(6,6),可從中隨機選取格子放置障礙、道具或敵人。
教程中的坐標零點選的是圍墻內左下角
2016.08.06 凌晨 沒有編程基礎學起來會慢一些,但是這種不斷學東西的感覺很好
四、游戲控制器 —— Game Manager
加上Game Manager之后,就可以測試地圖生成器的效果了。
以level 3為例,Awake里獲取到Board Manager,然后運行下SetupScene就已經可以測地圖生成的效果了:(Inspector中要把變量對應的prefabs拖進去)
效果如下,因為是從(-1,-1)點開始擺的所以偏的
調下鏡頭位置和背景色
之后要做的,是保證Game Manager是一個單例(singleton),即只會存在一個instance。因為之后Game Manager會被做成prefab。我目前的理解是,全局使用的物體會需要使用這種單例模式,因為在被調用時有產生多個的可能性。(此處理解不到位,待學習)
返回unity,把Game Manager拖入prefabs,并刪掉場景中的。
做一個Loader來加載Game Manager的實例。
如果當前沒有GameManager類的實例,則創建。
Loader掛在Main Camera上,Game Manager拖入變量gameManager中。
---說明----
1. 全局靜態變量
public static GameManager instance = null; ?
靜態變量屬于類本身而不是類的實例。全局靜態變量可在任何時候被任何腳本調用。
所以即使在Game Manager未被實例化時,Loader也可以調用instance!
This means that we can now access the public functions and variables of our game manager from any script in our game.
關于靜態變量:
靜態變量屬于靜態存儲方式,其存儲空間為內存中的靜態數據區(在 靜態存儲區內分配存儲單元),該區域中的數據在整個程序的運行期間一直占用這些存儲空間(在程序整個運行期間都不釋放),也可以認為是其內存地址不變,直 到整個程序運行結束(相反,而auto自動變量,即動態局部變量,屬于動態存儲類別,占動態存儲空間,函數調用結束后即釋放)。靜態變量雖在程序的整個執行過程中始終存在,但是在它作用域之外不能使用。
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為空,則把當前GameManager類的實例(當前物體)賦予instance,如果instance不是當前這個實例,就銷毀當前這個物體(當前這個實例)。
如果現在生成了一個GameManager的實例a,靜態變量instance則被賦予實例a,這時又生成了一個GameManager的實例b,這時在實例b中,instance就不等于this(this是實例b),于是實例b就會被銷毀。
關于單例:
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來調用Game Manager?
這些都還不太懂
2016.08.07 @@ 朦朧地理解了全局靜態變量和單例模式,GOOD!