Unity官方 《Spaceshooter》學習筆記

? ? ? ?在寫學習筆記之前,我先說說為什么會做這么一個游戲DEMO吧,目前是在一家互聯網廣告公司任職3D設計組長一職,主要內容是CG這塊,因為對AR和VR很感興趣,并且暫時選擇了Unity這款游戲引擎做為我的敲門磚,因為CG是我的優勢,所以對Unity這款軟件不陌生,上手很快,唯一比較陌生的是程序代碼這塊,但因為大學的時候學過C和游戲編程,所以倒不止于看到程序就放棄,只是工作一兩年完全沒接觸程序了。因此我決定在上手了Unity軟件后,準備啃下Unity中編程這塊硬骨頭。我選擇了C#這門語言來學習,因為市面上大多數AR和VR教程都是用C#來寫的,這樣學習起來方便一些。

? ? ? ?我先在在網上學習了一些Unity的C#基礎知識,比如GameObject,Transform,枚舉,方法等,對Unity中編程的基礎知識有了一些了解,接著我覺得還得跟著一些教程做練習,理解消化,跟著官方教程是一個很不錯的選擇,接下來就進入我的Spaceshooter筆記。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

一:教程的前5個課時講述的是3D知識,比如相機燈光背景和特效等,表示毫無壓力跳過

二:角色控制、發射子彈

代碼如下:

using UnityEngine;

using System.Collections;

public class spaceshooter : MonoBehaviour {

? ? ? ? ? ? ?public float speed;

? ? ? ? ? ? ?public float rt;

? ? ? ? ? ? ?public float xMin;

? ? ? ? ? ? ?public float xMax;

? ? ? ? ? ? ?public float zMin;

? ? ? ? ? ? public float zMax;

? ? publicGameObjectshot;

? ? publicTransformshotspawn;

? ? publicfloatfirerate;

? ? privatefloatnextfire=0.0f;

voidUpdate(){

? ? ? if(Input.GetButton("Fire1")&&Time.time>nextfire){

? ? ? nextfire=Time.time+firerate;

? ? ?Instantiate(shot,shotspawn.position,shotspawn.rotation);

}

}

? ?void FixedUpdate() ? {

? ? ? ? ? ?float mh = Input.GetAxis ("Horizontal");

? ? ? ? ? ? float mv =? Input.GetAxis ("Vertical");

? ? ? ? ? ? Rigidbody rigidbody =GetComponent();

? ? ? ? ? ? Vector3 movement = new Vector3 (mh, 0.0f, mv);

? ? ? ? ? ? ?rigidbody.velocity = movement*speed;

? ? ? ? ? ? ?transform.rotation= Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x* rt);

? ? ? ? ? ? ? transform.position = new Vector3 (

? ? ? ? ? ? ?Mathf.Clamp (transform.position.x,xMin,xMax),

? ? ? ? ? ? ?0.0F,

? ? ? ? ? ? ?Mathf.Clamp(transform.position.z,zMin,zMax)

? ? ? ? ? ? ?);

? ? }

}

這段代碼主要實現了以下功能

1:這段代碼首先沒有寫在Unity默認的Update函數中,而是寫在了FixedUpdate()函數中,在網上搜了一下Update和FixedUpdate的區別,Update()和FixedUpdate()在游戲中都會在更新的時候自動循環調用。但是Update是在每次渲染新的一幀的時候才會調用,也就是說,這個函數的更新頻率和設備的性能有關以及被渲染的物體(可以認為是三角形的數量)。在性能好的機器上可能fps 30,差的可能小些。這會導致同一個游戲在不同的機器上效果不一致,有的快有的慢。因為Update的執行間隔不一樣了。而FixedUpdate,是在固定的時間間隔執行,不受游戲幀率的影響。所以處理Rigidbody的時候最好用FixedUpdate。

PS:FixedUpdate的時間間隔可以在項目設置中更改,Edit->Project Setting->time找到Fixed timestep。就可以修改了。

2:關于Rigidbody調用的問題,官方案例是4.6版本,可以直接調用rigidbody,但5.0以后的版本中,Unity將C#規范了,要調用rigidbody必須要定義,比如Rigidbody r=GetComponent<Rigidebody>()來定義。

3:通過鍵盤上的"W" "A" "S" "D"或者方向鍵來控制飛船的前后左右的移動,左右是通過Input.GetAxis ("Horizontal")和Input.GetAxis ("Vertical")來實現,它們都是Vector3類型并且值范圍都是在-1到1之間 ,此時定義一個訪問修飾符為public且float類型的speed來控制飛船的速度;

4:用Math.Clamp方法來控制飛船移動邊界,通過查閱官方文檔知道,Math.Clamp返回的是一個float類型value的值,寫法是Math.Clamp(float value,float min,float max)

5:設定飛船的旋轉邊界值,rotation是一個Quaternion類型的值,用Quaternion.Euler來表示物體的旋轉,物體在x和y方向上的旋轉為0 ,在z方向上的旋轉跟物體的速度正負值掛鉤,所以用rigidbody.velovity.x來表示,這樣,按下方向鍵,向左或者向右時,飛船就能夠發生“側翻”效果.

6:Instantiat方法的使用,參照官方文檔,Instancitate是用來實例化物體的,使用方法是Instantiate (Object Original,Vector3 position,Quaternion rotation),Object是要實例化的對象,Vector是要復制到的位置,Quaternion是設置物體的旋轉。

7:Time.time方法用來獲取游戲運行的時間,在本例中用來設置按下鼠標左鍵后間隔多少時間發射下一發子彈。

8:Input.GetButton("FIre1")代碼塊中,Fire1表示鼠標左鍵,Fire0表示鼠標中間,Fire2表示鼠標右鍵,而且Input.GetButton表示持續按下Fire1,同類型的還有Input.GetButtonDown和Input.GetButtonUp也表示按下按鍵,但是只能計算一次按下或者彈起。

二:邊界

voidOnTriggerExit(Colliderother){

Destroy(other.gameObject);

}

調用了Trigger中的一個方法,即離開這個邊界的物體都會被“殺死”,條件就是只要觸碰到了邊界物體的Collider就會調用這個方法,Destroy中的參數是other.gameobjet,表明只會殺死其他的物體,而不會把自身給銷毀掉,跟后面要用到的碰撞方法有區別。

三 創建激光

void Start()?

{

Rigidbodyrigidbody=GetComponent();

rigidbody.velocity=transform.forward*speed;

rigidbody.angularVelocity=Random.insideUnitSphere*tumble;

}

1:這個代碼是用來表示行星的產生方向和起始隨機的旋轉速度,transform.forward用來表示z軸方向上的速度,為(0,0,1)

2:rigidbody.angularVelocity用來表示物體的旋轉角速度,是一個Vector3類型的,而隨機的起始速度則由Random類中的insideUnitSphere來表示,它是一個半徑為1的球,方向是-1到1,并且這個方法只能放在Start函數中只能調用一次,自己在做的時候,放在了Update()函數中,導致這個產生的行星都像發了瘋似的旋轉,因為每一幀都會更新它的角速度,而這個角速度又是隨機產生的。

四 爆炸?

代碼如下

publicGameObjectzidanbaozha;

publicGameObjectfeichuanbaozha;

publicGameObjectzidanbaozhashengyin;

publicGameObjectfeichuanbaozhashengyin;

voidOnTriggerEnter(Colliderother){

//自己的寫法

if(other.tag=="Boundary")//這里的if是不讓邊界盒子跟行星發生碰撞

{

return;//這里的return是返回一個空的值,表示什么也不做,也可以不寫這個return

}

if(other.tag=="Bolt")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

Instantiate(zidanbaozhashengyin,transform.position,Quaternion.identity);

}

if(other.tag=="Player")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(feichuanbaozha,transform.position,Quaternion.identity);

Instantiate(feichuanbaozhashengyin,transform.position,Quaternion.identity);

}

if(other.tag=="xingxing")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

}

//官方教程的寫法

/*if(other.tag=="Boundary")//這里的if是不讓邊界盒子跟行星發生碰撞

{

return;//這里的return是返回一個空的值,表示什么也不做,也可以不寫這個return

}

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

if(other.tag=="Player")

{

Instantiate(feichuanbaozha,transform.position,Quaternion.identity);

}

Destroy(other.gameObject);

Destroy(gameObject);*/

1:這里的代碼是分類子彈的collider碰撞到不同的物體的時候,會有不同的爆炸特效,判斷的一句是gameobject的Tag。我的寫法相比官方的想法可能會更死板,不簡練,但畢竟不是寫代碼的老手,這樣寫代碼方便自己理解,以后代碼量上去了我相信自己還是能夠養成良好的代碼習慣。

2:這里的Quaternion.identity表示物體沒有旋轉。

五 生成波

代碼如下

publicGameObjecthazard;

publicVector3spawnwaves;

publicinthazardcount;

publicfloatwaittime;

publicfloatspawntime;

publicfloatjiangeshijian;

voidStart(){

StartCoroutine(SpawnWaves());

}

IEnumeratorSpawnWaves(){

yieldreturnnewWaitForSeconds(waittime);

while(true)

{

for(inti=0;i

{

floata=Random.Range(-4.76f,4.76f);

hazard.transform.position=newVector3(a,0.0f,14.0f);

hazard.transform.rotation=Quaternion.identity;

Instantiate(hazard,hazard.transform.position,hazard.transform.rotation);

yieldreturnnewWaitForSeconds(spawntime);

}

yieldreturnnewWaitForSeconds(jiangeshijian);

}

}

1:這里的代碼是讓“敵人”也就是行星能夠一波一波地產生,并且在每次游戲開始之前,會過1s后才開始,讓玩家做好游戲準備,并且“敵人”會一波一個產生,每一波之間也會有間隔時間。

2:這里用到了SpawnWaves()方法,其實我覺得有沒有這個方法也是一樣的,因為能夠產生一波一波效果的主要是協同方法中的WaitForSeconds類來控制的,而且SpawnWaves()方法必須要在void Star()方法中手動調用才行。

3:能夠實現一波一波效果的,最關鍵是用到了協同函數,來實現延遲的效果也就是StartCoroutine(method name)方法,查看官方文檔知道,StartCoroutine(方法名)就能啟用Coroutine方法,并且返回值的類型不再是void,而是IEnumerator,并且用關鍵字yield return new WaitForSeconds (float value)來標識WaitForSeconds類,這里的value是標識延遲的時間。(http://docs.unity3d.com/ScriptReference/WaitForSeconds.html)這里插入官方文檔關于如何調用Coroutine,并且使用WaitForSeconds來實現延遲效果有很好的解釋

六 結束游戲

在這一塊中,主要困惑點是在重新加載當前游戲的api,因為官方教程用的是4.2的版本,用Application.loadlevel(Application.loadlevel) 來加載當前場景,當時在5.3版本中完全不能用,在5.3版本中使用SceneManager.LoadScene(scene name or index of the scene),并且在用這個類的時候,還必須引用Scene Management,在官網文檔中其實也沒解釋清楚,在網上搜了好久才知道這個的用法,最終,在5.3中重新加載當前場景,我的代碼是

usingUnityEngine;

usingSystem.Collections;

usingUnityEngine.SceneManagement;

publicclassGameController:MonoBehaviour{

void Update()

{

?if (gameover)

{

? ? ?if(Input.GetKeyDown(Keycode.R))
? ?{

? ? ? SceneManager.LoadScene(0);

? ?}

}

}

}

這樣就當按下R鍵的時候,就會重新加載當前的場景,重新開始游戲

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

推薦閱讀更多精彩內容

  • 這是今天的成果吧,雖然還是沒有全部完成,但是大致的功能已經實現,飛機的移動,限制移動范圍,子彈的發射,消滅敵人,敵...
    Unity學習的路上閱讀 2,858評論 1 2
  • // Unity學習筆記,自己會記錄一些學習中遇到的問題,可以給自己看也可以給需要的人看,希望能幫助掉在同樣坑里的...
    pirateH閱讀 3,065評論 0 4
  • 111. [動畫系統]如何將其他類型的動畫轉換成關鍵幀動畫? 動畫->點緩存->關鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,141評論 3 90
  • 不知道你有沒有喜歡上一個人,就是一眼見過后,就想跟她一起走完這一生的那種,不知道是什么樣的動力讓阿明做到了,不顧一...
    用心愛著你閱讀 245評論 0 0
  • 最近一段時間關于李笑來的負面消息越來越多。 有說李笑來宣傳的區塊鏈投資是龐氏騙局的;有說李笑來沒什么本事的;還有曝...
    且伴空山邀明月閱讀 2,609評論 1 2