單元1 搭建場景 本教程將會帶大家實現(xiàn)一款經(jīng)典的小游戲——像素鳥,英文名Flappy Bir
單元1 搭建場景
本教程將會帶大家實現(xiàn)一款經(jīng)典的小游戲——像素鳥,英文名Flappy?Bird。這是一款休閑動作游戲,玩家通過點擊屏幕控制小鳥的起飛降落,躲開沿途的障礙物。游戲沒有勝利,玩家通過創(chuàng)建新的最高分而不斷地挑戰(zhàn)自我。
任務(wù)1.1 導(dǎo)入美術(shù)資源包
1. 創(chuàng)建工程
打開Unity的可執(zhí)行程序(本案例使用的是Unity2017.2.0f3),選擇創(chuàng)建2D工程,如圖所示。
?

2. 導(dǎo)入資源包
找到教程提供的資源包,如圖所示。直接拖入到Unity的Project視圖中。
?

3. 設(shè)置圖片格式
如果創(chuàng)建工程選擇了2D模式,那么系統(tǒng)會自動將導(dǎo)入的圖片設(shè)置為Sprite類型,此步驟可忽略不用操作。如果選擇了3D模式,需要手動設(shè)置。在Project視圖中選中所有的圖片,如圖所示。
?

在右側(cè)Inspector視圖中,將Texture Type設(shè)置為Sprite(2D and UI),最后不要忘記單擊下方的“Apply”按鈕,如圖所示。
?

任務(wù)1.2 創(chuàng)建背景
1.?新建場景
按“Ctrl+S”鍵,或者選擇File→Save?Scene命令,將場景命名為Game,保存。此時場景里只保留Camera一個游戲?qū)ο螅鐖D所示。
?

2. 調(diào)整相機
如果創(chuàng)建工程的時候選擇了3D模式,則需要調(diào)整相機的設(shè)置。選中Camera,在Camera組件里設(shè)置Projection為Orthographic,Size設(shè)置為1.75。
在Game視圖中設(shè)置默認(rèn)分辨率為1440*900,如圖所示。
?

3. 添加大地
在image文件夾里找到back圖片,這是我們的地面。直接拖拽到場景中,然后再復(fù)制2個,分別命名為back0、back1、back2。如圖所示。
?

將它們的坐標(biāo)分別設(shè)置為(-0.25,0,0)、(4.8,0,0)、(9.85,0,0),此時的場景應(yīng)該是這樣的。

?
接著,我們需要創(chuàng)建一個空游戲?qū)ο?,命名為Ground,修改坐標(biāo)為(0,0,0),然后將3個back都放到Ground下,成為其子物體,如圖所示。
?

這樣一來,在實現(xiàn)無盡地圖時會比較方便。
4. 添加天空
在image文件夾里找到bg,拖拽到場景中,同樣再復(fù)制2個,命名為bg0、bg1、bg2。將他們的坐標(biāo)分別設(shè)置為(-0.95,0,0)、(2.07,0,0)、(5.09,0,0)。同樣新建一個空物體,命名為Sky,將3個bg對象都放到Sky下,成為其子物體。此時的場景應(yīng)該是這樣的。
?

天空遮住了地面,不用著急。選中3個bg對象,在Inspector的Sprite?Renderer組件里修改Sorting?Layer為-2。最終效果如圖所示。
?

任務(wù)1.3 添加水管
1. 添加兩根水管
從image文件夾中將pipe圖片拖拽到場景中,命名為pipeUp,然后復(fù)制1個,命名為pipeDown,這就是我們的兩個水管。將兩個水管的Sprite?Renderer中sorting?layer修改為-1,讓其介于地面和天空之間,如圖所示。
?

將pipeUp的坐標(biāo)修改為(0,-3,0),pipeDown的坐標(biāo)修改為(0,3,0),效果如圖所示。
?

2. 復(fù)制水管
為了表示這兩個水管是一個整體,讓PipeUp成為pipedown的子物體,如圖所示。
?

將PipeDown復(fù)制出2個,命名為PipeDown1和PipeDown2。最后,設(shè)置PipeDown0的坐標(biāo)為(3,-3,0),PipeDown1的坐標(biāo)為(6,-3,0),PipeDown2的坐標(biāo)為(9,-3,0),最后的效果如圖所示。
?

3. 統(tǒng)一管理
同樣的,為了方便后面生成無數(shù)個管子,我們需要創(chuàng)建一個空游戲?qū)ο螅麨镚ateGroup,修改坐標(biāo)為(0,0,0),將三個PipeDown放到GateGroup下面,成為其子物體,如圖所示。
?

最后,不要忘記按“Ctrl+S”鍵保存場景。
單元2 會飛的小鳥
場景已經(jīng)搭建完成了,接下來該主角登場了。
任務(wù)2.1 創(chuàng)建小鳥
1. 添加小鳥游戲?qū)ο?/span>
將image文件夾里bird拖到場景中,重命名為Bird,可以看到效果如圖。
?

這是因為bird圖片的默認(rèn)格式為Single。
2. 設(shè)置bird圖片格式
在Project視圖選中bird圖片,在Inspector視圖修改Sprite?Mode為Multiple,然后點擊Sprite?Editor按鈕,進(jìn)入Sprite?Editor窗口,對bird圖片進(jìn)行切割,如圖所示。
?

設(shè)置三個方框的Position,分別如下圖所示。
?



?
?
設(shè)置好后,單擊Sprite?Editor窗口中的“Apply”按鈕,應(yīng)用修改并關(guān)閉窗口。
最后,在Inspector視圖下方,單擊“Apply”按鈕,應(yīng)用對圖片格式的修改。此時,Scene場景中的小鳥恢復(fù)了正常,如圖所示。
?

任務(wù)2.2 起飛降落
1. 添加剛體
在Hierarchy視圖中選中Bird,在Inspector視圖中單擊“Add?Component”按鈕添加Rigidbody?2D組件。設(shè)置Gravity?Scale值為0.7,如圖所示。
?

運行游戲,可以看到小鳥受重力影響而降落。
2. 添加SportCtrl.cs
創(chuàng)建SportCtrl.cs腳本,并添加到Bird游戲?qū)ο笊?。打開SportCtrl腳本,添加Rigidbody2D的字段并在Start方法中引用自身,如圖所示。
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?SportCtrl?: MonoBehaviour
{
?
????Rigidbody2D rb;
????void?Start()
????{
????????rb = GetComponent<Rigidbody2D>();
????}
?
????// Update is called once per frame
????void?FixedUpdate()
????{
????????Fly();
?
????}
?
????public?void?Fly()
????{
????????float?xSpeed = 1f;
????????Vector3 v = rb.velocity;
????????float?ySpeed = v.y;
????????if?(Input.GetMouseButton(0))
????????{
????????????ySpeed = 2f;
????????}
????????rb.velocity = new?Vector2(xSpeed, ySpeed);
????}
}
再運行游戲試一試,已經(jīng)可以控制小鳥起飛降落了。
任務(wù)2.3 碰撞
現(xiàn)在小鳥已經(jīng)可以飛了,但是會穿過地面和管子,這一節(jié)將會解決這個問題。
1. 添加小鳥的碰撞體
在Bird游戲?qū)ο笊咸砑覥ircle?Collider?2D,半徑設(shè)置為0.18,如圖所示。
?

2. 添加大地的碰撞體
給Ground下的三個子物體back0、back1、back2添加Box?Collider?2D組件,并設(shè)置成如圖所示的配置。
?

運行游戲,可以看到小鳥已經(jīng)可以碰到地面了,如圖所示。
?

3. 添加管子的碰撞體
選中所有的PipeDown和PipUp,如圖所示。
?

全部都添加上Box?Collider?2D組件即可。
單元3 無盡模式
任務(wù)3.1 相機跟隨
1. 創(chuàng)建CamCtrl.cs腳本
在Main?Camera上添加新腳本CamCtrl.cs,并完成以下代碼。
public?class?CamCtrl?: MonoBehaviour {
?
????public?Transform target;
????Vector3 offset;
// Use this for initialization
void?Start () {
????????offset = ?transform.position-target.position;
????}
// Update is called once per frame
void?LateUpdate () {
????????transform.position = target.position + offset;
}
}
回到編輯器,對Target進(jìn)行賦值,如圖所示。
?

運行游戲,發(fā)現(xiàn)我們的相機已經(jīng)可以跟著小鳥移動了。
2. 限制相機高度
相機有時會穿幫,需要限制高度。修改腳本的LateUpdate方法如下。
void?LateUpdate () {
????????Vector3 pos= target.position + offset;
????????if?(pos.y > 0.9)
????????????pos.y = 0.9f;
????????else?if?(pos.y < -0.9)
????????????pos.y = -0.9f;
????????transform.position = pos;
}
任務(wù)3.2 無限地圖
我們的思路是,將有限的圖片進(jìn)行重復(fù)使用,從而實現(xiàn)無限地圖的效果。當(dāng)最左側(cè)的圖片不可見時,將其移動到最右側(cè)。
1. 創(chuàng)建Endless.cs腳本
添加如下代碼。
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?Endless?: MonoBehaviour {
????public?float?distance;
????void?OnBecameInvisible(){
????????transform.Translate(Vector3.right* distance * 3);
????}
}
2. 實現(xiàn)無限地面
然后將腳本添加到back0、back1、back2,并在編輯器中設(shè)置distance為5.05。如圖所示。
?

運行游戲進(jìn)行測試,注意測試的時候需要關(guān)閉Scene視圖。可以看到地面已經(jīng)可以無限延長了,如圖所示。
?

3. ?實現(xiàn)無限天空
同理,給bg0、bg1、bg2添加Endless腳本,并設(shè)置distance為3.02。
運行游戲測試,可以看到如圖效果。
?

4. 實現(xiàn)無限水管
同理,給pipeDown0、pipeDown1、pipeDown2添加Endless腳本,并設(shè)置distance為3。
運行游戲測試,可以看到水管也有無限個了。
任務(wù)3.3 水管隨機高度
1. 創(chuàng)建RandomHeight.cs腳本
創(chuàng)建RandomHeight.cs腳本,添加如下代碼。
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?RandomHeight?: MonoBehaviour
{
????void?OnBecameVisible()
????{
????????Vector3 pos = transform.position;
????????pos.y = Random.Range(-3f, -1.5f);
????????transform.position = pos;
????}
}
2. 添加腳本
選中所有的pipeDown,全都添加RandomHeight腳本。
運行游戲,測試效果??梢钥吹焦茏右呀?jīng)可以產(chǎn)生隨機高度了。
?

單元4 游戲邏輯
任務(wù)4.1 UI
1. 創(chuàng)建開始界面
在場景中創(chuàng)建畫布Canvas,然后制作開始界面。
首先在Canvas下新建一個空物體,命名為StartWnd。然后在StartWnd下新建一個Image,命名為imgTitle,SourceImage使用main圖片。然后在StartWnd下新建一個Button,命名為btnStart,SourceImage使用start圖片。如圖所示。
?

調(diào)整位置,最后效果如圖所示。
?

2. 創(chuàng)建準(zhǔn)備界面
隱藏StartWnd,在Canvas下新建一個空物體,命名為ReadyWnd。然后在ReadyWnd下新建一個Button,命名為page1,SourceImage使用tap圖片,效果如圖所示。
?

隱藏page1,然后在ReadyWnd下新建一個Image,命名為page2,SourceImage使用ready圖片。如圖所示。
?

調(diào)整位置,效果如圖所示。
?

3. 創(chuàng)建結(jié)束界面
隱藏ReadyWnd,在Canvas下新建一個空物體,命名為EndWnd。然后在EndWnd下新建一個Button,命名為page1,SourceImage使用gameover圖片,效果如圖所示。
?

隱藏page1,然后在EndWnd下新建一個空游戲?qū)ο?,命名為page2。在page2下新建一個Image,命名為bg,SourceImage使用score圖片。在bg下新建兩個Text,一個命名為txtScore,一個命名為txtBest。在page2下新建一個Button,命名為btnRestart,SourceImage使用start圖片,如圖所示。
?

調(diào)整樣式和位置,最后效果如圖所示。
?

4. 創(chuàng)建左上角得分顯示
在Canvas下新建Text,命名為txtScore。調(diào)整參數(shù),最后效果如圖所示。
?

任務(wù)4.2 創(chuàng)建游戲管理器
1. 創(chuàng)建GameRoot.cs腳本單例
創(chuàng)建空游戲?qū)ο?/span>GameRoot,并添加GameRoot.cs腳本。代碼如下。
public?class?GameRoot?: MonoBehaviour
{
????public?static?GameRoot Instance;
????void?Start()
????{
????????Instance = this;
}
}
2. 創(chuàng)建游戲狀態(tài)
public?const?int?GAMESTART = 0;
????public?const?int?GAMEREADY = 1;
????public?const?int?GAMERUN = 2;
????public?const?int?GAMEEND = 3;
public?int?GAMESTATE = GAMESTART;
3. 引用UI窗口和主角
添加引用UI窗口和主角的字段,代碼如下。
public?Transform StartWnd, ReadyWnd, EndWnd, bird;
????public?Text txtScore;
????public?int?score=0;
在外部對這些字段進(jìn)行賦值,如圖所示。
?

4. 創(chuàng)建游戲狀態(tài)變更的方法
///?<summary>
????///?剛進(jìn)入游戲時
????///?</summary>
????public?void?Enter() {
????????StartWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMESTART;
????}
?
????///?<summary>
????///?進(jìn)入準(zhǔn)備狀態(tài)時
????///?</summary>
????public?void?Ready() {
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
????}
????///?<summary>
????///?進(jìn)入娛樂狀態(tài)時
????///?</summary>
????public?void?Run() {
????????ReadyWnd.gameObject.SetActive(false);
????????GAMESTATE = GAMERUN;
????}
????///?<summary>
????///?游戲結(jié)束時
????///?</summary>
????public?void?End()
????{
????????EndWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEEND;
????????
????}
任務(wù)4.3 UI邏輯
1. 添加StartWnd腳本
首先創(chuàng)建StartWnd.cs腳本,代碼如下:
using?UnityEngine;
using?UnityEngine.UI;
?
public?class?StartWnd?: MonoBehaviour
{
????public?Button btnStart;
????// Use this for initialization
????void?Start()
????{
????????btnStart.onClick.AddListener(OnStartClick);
?
????}
?
????void?OnStartClick()
????{
????????GameRoot.Instance.Ready();
????}
}
將腳本添加到StartWnd上,然后對UI字段進(jìn)行賦值。
?

2. 添加ReadyWnd腳本
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
using?UnityEngine.UI;
?
public?class?ReadyWnd?: MonoBehaviour
{
?
????public?Button page1;
????public?Transform page2;
????// Use this for initialization
????void?Start()
????{
????????page1.onClick.AddListener(OnClick);
????}
????void?OnEnable()
????{
????????page1.gameObject.SetActive(true);
????????page2.gameObject.SetActive(false);
????}
?
????public?void?OnClick()
????{
????????//顯示page2
????????page1.gameObject.SetActive(false);
????????page2.gameObject.SetActive(true);
????????//1秒過后調(diào)用
????????StartCoroutine(Run());
????}
?
????IEnumerator Run() {
????????yield?return?new?WaitForSeconds(1);
????????GameRoot.Instance.Run();
????
????}
?
}
將腳本添加到ReadyWnd上,并對外部引用進(jìn)行賦值。如圖所示。
?

3. 添加EndWnd腳本
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
using?UnityEngine.UI;
?
public?class?EndWnd?: MonoBehaviour
{
?
????public?Button page1;
????public?Transform page2;
????public?Button btnRestart;
????public?Text txtScore, txtBest;
????// Use this for initialization
????void?Start()
????{
????????page1.onClick.AddListener(OnPage1Click);
????????btnRestart.onClick.AddListener(OnRestartClick);
????????
????}
????void?OnEnable() {
????????page1.gameObject.SetActive(true);
????????page2.gameObject.SetActive(false);
????}
?
????// Update is called once per frame
????void?Update()
????{
?
????}
?
????void?OnPage1Click()
????{
????????page2.gameObject.SetActive(true);
????????page1.gameObject.SetActive(false);
????????txtBest.text = PlayerPrefs.GetInt("best").ToString();
????????txtScore.text = GameRoot.Instance.score.ToString();
????}
????void?OnRestartClick()
????{
????????gameObject.SetActive(false);
????????GameRoot.Instance.Ready();
????}
?
}
將腳本添加到EndWnd上,并給外部引用賦值,如圖所示。

任務(wù)4.4 得分
1. 添加得分觸發(fā)器
在pipeDown0下創(chuàng)建空游戲?qū)ο?,命名為scoreTrigger。
?

設(shè)置Position為(0,3,0),然后在scoreTrigger上添加Box?Collider?2D組件,設(shè)置如圖所示。
?

效果如圖所示。

?
同理,在pipeDown1和pipeDown2下也創(chuàng)建scoreTrigger。最后效果如圖所示。
?

2. 添加得分方法
在GameRoot中添加以下方法,代碼如下。
public?void?GetPoint()
????{
????????score++;
????????txtScore.text = "Score:"?+ score;
????}
3. 添加得分觸發(fā)方法
在GateGroup上創(chuàng)建ScoreCtrl腳本,代碼如下。
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?ScoreCtrl?: MonoBehaviour {
?
????public?void?OnTriggerEnter2D(Collider2D other) {
????????if?(other.CompareTag("Player")) {
????????????GameRoot.Instance.GetPoint();
????????}
????}
}
為了讓這個方法對所有Trigger有效,在GateGroup上添加RigidBody2D組件,并設(shè)置組件,如圖所示。
?

最后,修改Bird對象的Tag為Player。
任務(wù)4.5 失敗
添加失敗觸發(fā)方法
在SportCtrl腳本里添加碰撞檢測方法,代碼如下。
????void?OnCollisionEnter2D(Collision2D coll)
????{
????????GameRoot.Instance.End();
????}
單元5 邏輯優(yōu)化
任務(wù)5.1 控制優(yōu)化
1. 禁用控制
修改SportCtrl.cs的FixedUpdate方法,代碼如下。
void?FixedUpdate()
????{
????????if?(GameRoot.Instance.GAMESTATE != GameRoot.GAMERUN)
????????????return;
????????Fly();
????}
2. 禁用和啟用重力
在SportCtrl.cs中添加兩個方法:
public?void?EnableGravity() {
????????rb.gravityScale = 0.7f;
????}
????public?void?DisEnableGravity() {
????????rb.gravityScale = 0;
????}
然后添加SportCtrl單例并在游戲開始消除重力:
????public?static?SportCtrl Instance;
????void?Start()
????{
????????Instance = this;
????????rb = GetComponent<Rigidbody2D>();
????????DisEnableGravity();
????}
在GameRoot中調(diào)用:
public?void?Ready()
????{
????????SportCtrl.Instance.DisEnableGravity();
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
????}public?void?Run()
????{
????????SportCtrl.Instance.EnableGravity();
????????ReadyWnd.gameObject.SetActive(false);
????????GAMESTATE = GAMERUN;
????}
3. 禁用和啟用速度
在SportCtrl里添加方法:
???public?void?Init() {
????????rb.velocity = Vector3.zero;
????????rb.angularVelocity = 0;
????}
在GameRoot里調(diào)用:
public?void?Ready()
????{
????????SportCtrl.Instance.Init();
????????SportCtrl.Instance.DisEnableGravity();
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
????}
任務(wù)5.2 場景重置
1. 在GameRoot游戲?qū)ο笊咸砑覯apManager腳本
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?MapManager?: MonoBehaviour {
?
?
????public?List<Transform> maps = new?List<Transform>();
????List<Vector3> pos = new?List<Vector3>();
// Use this for initialization
void?Start () {
????????for?(var?e in maps) {
????????????pos.Add(e.position);
????????}
}
?
????public?void?Init?() {
????????for?(int?i = 0; i < maps.Count; i++)
????????{
????????????maps[i].position = pos[i];
????????}
????}
}
2. 在外部賦值
?

3. 在GameRoot里調(diào)用
public?void?Ready()
{
????????GetComponent<MapManager>(). Init ();
????????SportCtrl.Instance. Init ();
????????SportCtrl.Instance.DisEnableGravity();
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
????}
任務(wù)5.3 保存分?jǐn)?shù)
1. 讀取歷史最高分
在GameRoot中添加最高分變量:
??public?int?best;
在游戲結(jié)束時,判斷是否更新最高分:
public?void?End()
{
if?(GAMESTATE == GAMEEND)
????????????return; ???????
EndWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEEND;
????????int?best=PlayerPrefs.GetInt("best");
????????if?(score > best)
????????{
????????????PlayerPrefs.SetInt("best", score);
????????}
????}
2. 重置分?jǐn)?shù)
在GameRoot里修改方法:
public?void?Ready()
????{
????????score = 0;
????????GetComponent<MapManager>().Init();
????????SportCtrl.Instance. Init ();
????????SportCtrl.Instance.DisEnableGravity();
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
????}
單元6?聲音和動畫
任務(wù)6.1 添加聲音
1. 在GameRoot上添加AudioManager腳本
using?System.Collections;
using?System.Collections.Generic;
using?UnityEngine;
?
public?class?AudioManager?: MonoBehaviour
{
????public?static?AudioManager Instance;
????public?AudioSource fgSource;
????public?AudioSource bgSource;
????public?AudioClip wing;
????public?AudioClip hit;
????public?AudioClip die;
????public?AudioClip point;
????public?AudioClip swooshing;
?
????void?Start() {
????????Instance = this;
????}
????public?void?PlayHit() {
????????fgSource .PlayOneShot(hit);
????}
????public?void?PlayWing()
????{
????????if?(!fgSource.isPlaying)
????????????fgSource.PlayOneShot(wing);
}
????public?void?PlayPoint()
????{
????????bgSource.PlayOneShot(point);
????}
????public?void?PlaySwooshing()
????{
????????fgSource .PlayOneShot(swooshing);
????}
????public?void?PlayDie()
????{
????????fgSource .PlayOneShot(die);
????}
}
在GameRoot下創(chuàng)建兩個空物體fgsource和bgsource,均添加AudioSource組件。
?

2. 在外部對AudioManager進(jìn)行賦值
?

3. 在GameRoot中調(diào)用
public?void?Ready()
????{
????????AudioManager.Instance.PlaySwooshing();
????????score = 0;
????????GetComponent<MapManager>(). Init ();
????????SportCtrl.Instance. Init ();
????????SportCtrl.Instance.DisEnableGravity();
????????bird.position = Vector3.zero;
????????StartWnd.gameObject.SetActive(false);
????????ReadyWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEREADY;
????????bird.rotation = Quaternion.identity;
}
public?void?End()
????{
AudioManager.Instance.PlayHit();
if?(GAMESTATE == GAMEEND)
????????????return; ???????
AudioManager.Instance.PlayDie();
?
EndWnd.gameObject.SetActive(true);
????????GAMESTATE = GAMEEND;
????????int?best=PlayerPrefs.GetInt("best");
????????if?(score > best)
????????{
????????????PlayerPrefs.SetInt("best", score);
????????}
????}
public?void?GetPoint()
????{
????????AudioManager.Instance.PlayPoint();
????????score++;
????????//AudioSvc.Instance.Playpoint();
????????txtScore.text = "Score:"?+ score;
????}
4. 在SportCtrl中進(jìn)行賦值
public?void?Fly()
????{
??????
????????float?xSpeed = 1f;
????????Vector3 v = rb.velocity;
????????float?ySpeed = v.y;
????????if?(Input.GetMouseButton(0))
????????{
????????????ySpeed = 2f;
????????????AudioManager.Instance.PlayWing();
????????}
????????rb.velocity = new?Vector3(xSpeed, ySpeed, 0);
????}
任務(wù)6.2?添加動畫
1.?添加圖片
在SportCtrl腳本中添加圖片列表:
public?SpriteRenderer renderer;
????public?List<Sprite> sprites=new?List<Sprite>();
????int?index=0;
????float?timer=0;
2. 在外部賦值
?

3. 切換圖片
void?SwitchSprite(float?interval) {
????????timer += Time.fixedDeltaTime;
????????if?(timer > interval) {
????????????timer = 0;
????????????index = (index + 1) % sprites.Count;
????????????renderer.sprite = sprites[index];
????????}
????}
????// Update is called once per frame
????void?FixedUpdate()
????{
????????if?(GameRoot.Instance.GAMESTATE != GameRoot.GAMERUN)
????????????return;
????????Fly();
????????SwitchSprite(0.1f);
????}
?