用Unity开发一款2D横版游戏demo
?
# LanW Game Project
目錄
(一) 介紹
(二) 安裝教程
(三) 開發流程
1. ?新建工程
2. ?設置人物
3. ?控制主角的移動
4. ? 添加切換動作的動畫
5. ? 鏡頭跟蹤
6. ? 收集物體
7. ? 創建ui
8. ? 創建敵人
9. ? 制作敵人ai
10. ? 創建青蛙動畫
11. ? 優化代碼
12. ? 設置音效
13. ? 制作對話框
14. ? 制作死亡邊界
15. ? 制作場景切換
16. ? 制作前中后景視覺差 Parallax
17. ? 創建菜單
18. ? 制作音軌
19. ? 打包游戲
(四)常見問題及解決方法
(五) 致謝
?
?
(一) 介紹
本文主要是介紹了如何使用用unity開發一款簡單的橫版平臺跳躍類游戲demo,該游戲所展現的素材均來自unity商店,開發流程所展示的僅為部分參考代碼,該游戲所有工程文件及代碼在https://gitee.com/lan-dashai/lan-w-game-project/tree/master
軟件環境
Visual stdio 2019?
Unity Hub;
編輯器版本:Unity 2021.3.7f1c1(LTS);
(二) 安裝教程
1. ?首先在網頁搜索網址:https://unity.cn/unity-ggac-2021
2. ?點擊下載unity hub
3. ?安裝編輯器版本
(三) 開發流程
1. ?新建工程
*Asset Store商店搜索好包 并下載 在Package manager中下載并導入
*將背景圖片的Pixels Per Unit 改為16(每個格中含有16像素)并Apply 將背景圖片拖入Level窗口加載并reset其位置
主界面如下
?在level中新建2D obj Tilemap
*將背景圖片隱藏以便觀看 在Window 2D 中選Tile Palette
*在窗口中Create新的 命名為map 在缺省跳到的文件夾中新建文件夾命名maps
*將瓦片素材設置為16 Sprite 自動切割 將Mode改為Mutiple 點擊Sprite Editor 點擊窗口中的GridByCellSize Pixel設置為16*16 并切割
*切割完點擊Apply后將其拖入 Tile Palette ?點擊畫筆繪制地圖(關掉edit)(用橡皮可擦掉 記得選擇當前的Tile map)
*調整好main camera的屬性size設為6
點擊背景圖片 添加新的Sorting Layer 命名為 Background和Frontground 將背景設置為BG
?
?
2. ?設置人物
*將人物圖片改為20, 在level中新建2D Sprite 將人物拖拽到Sprite Render的編輯面板的Sprite中 并reset
?點擊人物的Add Component 添加Rigidbody 2D(剛體 將紙片變成物件)
*繼續為人物添加碰撞體 Box Collider 2D 點擊三個盒子相連的圖標(編輯)將綠色邊框拉至合適位置
?為地圖添加Tilemap Collider 2D 此時運行游戲人物可立于地面上
?
?
?
3. ?控制主角的移動
*為人物添加代碼 Add New Scrips 命名為PlayerController
打開script
創建剛體 public Rigidbody2D Rd; 將剛體拖入到創建的剛體中
創建初速度 public float Speed; 設置為10
創建移動方式 newfloat用來接收input了的GetAxis(horizontal) if語句當它不為0時(即-1或1)Rd.velocity剛體的移動 = newVector2(HorizontalMove * Speed, Rd.velogy.y);
將人物剛體中的Constrains中的Freeze Rotation Z勾上(凍結z軸)否則會發生移動時剛體旋轉
試玩中可調整速度參數 但試玩結束后不會保存 需要手動再設置
寫代碼 修改人物朝向 在移動方式中創建float用來接受input的GetAxisRaw(horizontal)-1 0 1整數 if語句當它不為0時 物體的transform.scale(在unity中) = new Vector3(FaceDirection,1,1);
*(優化代碼)將Update修改為FixedUpdate() 讓程序在低于60幀的電腦上流暢運行 在*Speed 后再 *Time.deltaTime 保存后將游戲中的Speed改為400(不推薦使用此條 很麻煩)
寫代碼 創建跳躍的力 public float JumpForce 在Movement函數中添加if語句如果Input.GetButtonDown("Jump") 則Rigidbody.velocity = (Rigidbody.velocity.x, JumpForce * Time.deltaTime); 并設置unity人物的JumpForce為400 將剛體的Gravity Scale重力稱改為2
?
?
?
4. ? 添加切換動作的動畫
*為人物添加Add Animator組件 再新建Animation文件夾以管理 下面新建Player文件夾 里面新建Animation Controller 命名為Player 將其拖入到組件中的Controller位置中
點擊Window Animation Animation 創建Animation 點擊Create創建 命名為Idle(原地站立)將Asset中idle的圖片全部改為16 全部拖入時間軸
*將采樣率Samples(三個點打開)設置為10 (或者全選節點拖拽至合適長度)
*創建新的Animation 命名為Run 注意文件存放位置 打開Asset中人物圖片的Run 圖片改為16全部拖入時間軸 Samples采樣率改為10 (缺省勾選了Loop Time循環播放)
*在Animator中右鍵Run Idle Make Transition將兩個互相鏈接 在Animator組件的Parameters組件的下拉三角形中選擇Float 添加Float命名為Running
*選中連接線 將Has Exit Time取消勾選(沒有動畫緩沖 馬上切換)Settings中的Transition Duration改為0(不需要轉換時間)在Conditions中點擊加號添加條件 數值改為0.1?
兩條連接線同理操作 Run到Idle的Conditions的Greater改為Less
*寫代碼 新建變量public Animator Animator;在Movement函數中新增Animator.SetFloat("Running", Math.Abs(接受的Horizontal的絕對值)) 保存后回到unity的人物編碼組件 將Animator組件拖入
*創建Animation Jump和Fall 將圖片16拖入 在Animator組件中設置好連線(Run,Idle鏈接Jump,Jump鏈接Fall,Fall鏈接Idle)
*添加Prarmeters Jumping Falling Idle
*設置好連線參數 (Run與Idle 的Jumping是true時到Jump)(Jump的Jumping是false且Falling是true時到Fall)(Fall的Falling是false且Idle是true時到Idle)
*打開PlayController腳本
*編寫代碼 void SwitchAnimation ?if(Animator.GetBool("Jumping")){if剛體的y坐標< 0時 設置Jumping為false,設置Falling為true}
*寫代碼 public LayerMask Ground;以獲取地面 將Tilemap的Layer設置添加新的命名為Ground并選擇 將Player中編碼組件的Ground 設置為Ground
*寫代碼 public Collider2D Collider2D;以獲取人物的碰撞體 續寫SwitchAnimation的elseif(Collider2D.IsTouchingLayers(Ground)){設置Falling為false,Idle為true} *在函數最前定義Bool Animator.SetBool("Idle", false);
(出現閃爍則檢查圖層或elseif)!
*將Box Collider 縮小 為人物新增 Cricle Collider碰撞體 設置到下半身位置
*寫代碼 將Rigidbody和Animator改外private 在start中寫他們的獲取方式 = GetCompenent<Rigidbody 2D>; = GetComponent<Animator>;(<>內名字就是unity組件中的名字)
(在定義的時候前面加[SerializeField]可將其設為可見不可操作)
?
?
5. ? 鏡頭跟蹤
*為Main Camera 添加代碼 命名為CameraControl
添加組件Cinemachine 在組件菜單中添加攝像頭Create 2D Camera 將player拖拽到Follow中跟隨 (Dead Zone調整開始跟隨區域 Screen X/Y調整角色固定位置)
ctrl d 復制背景直到填充屏幕 新建Empty命名為BackGround將三個back整理?
在2DCamera中的Add Extension組件中選擇CinemachineConfiner
為BackGround添加Polygon Collider2D 并將其設置為is Trigger(打勾)點擊編輯將多邊形的頂點拉至屏幕邊角 不需要的按住ctrl點擊可刪 將其添加到2D攝像機的Bounding Shape2D中
?
6. ? 收集物體
*為Cherry創建文件夾 將圖片素材改為16后拖拽導入 添加組件Animator 在Assets的動畫文件夾下創建AnimationController命名為Cherry 將其拖拽導入到Animator中 在組件編輯器中Create新的Cherry動畫 將圖片拽入
*為Cherry添加Box Collider2D 點擊編輯將其調整好 設置為isTrigger(這是一個檢測是否碰撞的裝置 并不要讓它有碰撞效果)
*為Cherry新建Tag標簽 叫做Collection
*打開人物的代碼 新建函數void OnTriggerEnter2D() 里面寫 if語句if(collision.tag == "Collection"){Destory(collision.gameObject);} 如果碰撞物體的標簽是Collection的話就銷毀該碰撞物體
*創建計數器 public int Cherry 在銷毀后面寫Cherry ++;
?
7. ? 創建ui
*在level1中新建ui畫布UI Canvas ?右鍵Canvas 添加UI Text 命名為Cherry
f找到物件位置 將Text移動到合適位置 修改Text內容 并調整合適大小
*在新增UI Text 命名為Numbers 修改Text內容及其屬性
寫代碼獲取ui文本 public Text CherryNumber;并using 保存后將Number拖入
*在OnTriggerEnter中新增代碼 CherryNumber.text = Cherry.ToString();
(固定文本位置)
*點選Cherry文本的設置方位圖(centermiddle圖標)并將位置選為始終在左上角
Number文本同理操作
(為Cherry創建UI Image 并為Gem創建UI及碰撞體和代碼)
?
?
8. ? 創建敵人
*創建Enemy Frog 將青蛙圖片拖入 創建其Idle和Jump動畫 為其添加Rigidbody 2D 及Box collider 2D并調整好碰撞體位置
*寫代碼 新函數private void OnCollisionEnter2D() {}
if語句 當collision.gameObject.tag (不是trigger類型的需要加gameObject) == "Enemy"; 時 Destory(collision.gameObject)
調整代碼 添加新條件 && 當人物正在執行Falling動作時
*寫代碼 添加人物受傷后退 new public bool IsHurt;在Update中if(IsHurt == false)時 運行Movement;
當碰撞體碰到敵人時 && 人物x軸小于敵人x軸(從左邊碰到敵人)則IsHurt = true 人物剛體.Velocity = New Velocity(-10,y)
右邊反之同理
*寫代碼 在SwitchAnimation中新增else if(IsHurt)時 if(剛體的x速度絕對值<0.1f)時 IsHurt = false;(寫在下落代碼之上 否則會一直運行下落)
*寫代碼 在IsHurt中添加動畫代碼條件 并寫SetFloat("Running", 0);以確保受傷動作完畢后回到正常動作
?
9. ? 制作敵人ai
*為Frog添加代碼 私有變量rb 在Start中獲取GetComponent<>
*在heri中為Frog添加子項目作為它的移動區域 為了方便觀察可改變他們的顏色
*寫代碼 創建IsFaceLeft布爾值以觀測 左右移動不超過左右兩個點的x y坐標 子物體設置分家DetachChildren
*寫代碼 創建x y在Start中賦值 運行后將兩個點銷毀
?
?
10. ? 創建青蛙動畫
*為青蛙分別添加Jump fall 動畫 連線并設置
*寫代碼 將y軸移動改為JumpFoece 添加前置if語句 如果rb.IsTouchingLayers(Ground)并開啟跳躍動畫
自動執行跳躍 為animation組件控制器添加事件關鍵幀 將其拖到站立動畫的最后 設置Function為寫好的Movement() 并將代碼中update里的Movement注釋
*寫代碼 添加 SwitchAnimation()
if Jumping則改變跳 落 動畫 else if 碰撞到地面則關閉下落動畫
*添加青蛙死亡的動畫 從Any State連線 添加控制器 Trigger開關 命名為Death
*寫代碼 為青蛙添加public Death函數
在人物動畫中的觸碰青蛙中的if語句中 添加EnemyFrog實體 EnemyFrog Forg = collision.gameObject.GetComponent<EnemyFrog>(); 并用Frog調用Death
*寫代碼 為青蛙添加Destroy函數 Destroy(gameObject); 在Death動畫最后添加關鍵幀 設置為啟用銷毀
?
?
?
?
?
?
11. ? 優化代碼
*根目錄新建C# Enemy 新建變量protected Animator Anim;并獲取 并把Start Update函數也改編為protected virtual void Start()(受保護的虛擬函數)
*將EnemyFrog的:父類改為 Enemy 并將青蛙的變量Animator及其Start中的獲取 注釋
*將青蛙的Start 設為 protected override void Start()(重寫父類方法)同時在里面調用 base.Start()
*將Destory和Death函數注釋并復制到Enemy中 并全部設為public
*修改人物代碼中毀掉青蛙的代碼 將new的青蛙注釋 改外new Enemy 將底下的青蛙.銷毀 改為Enemy.銷毀
?
12. ? 設置音效
*為player添加組件 Audio Source 右上角點擊overrides apply all 將所有新加的組件添加到perfabs預設
*在AudioClip中拖拽添加bgm 將Play on Awake勾選(啟動游戲時播放)將loop勾選(循環播放)
*點擊青蛙heri中的小箭頭進入青蛙組件 為其添加AudioScouce?
*寫代碼 在enemy 中創建爆炸音效變量 protected AudioSource DeathAudio 并getComponent在Death中啟用 DeathAudio.play();
同理 為人物add各種音效 寫人物代碼 public AudioSource ____ 并.play 并在組件中拽入音效?
?
13. ? 制作對話框
*在level1中的Canvas中新建UI Panel面板 命名為EnterDialog
*為其改變顏色 改變位置至固定在下方 width改為600 height125 Y軸改變至100
*為其創建子項目 右鍵UI Text 設置位置 內容 文字大小
在房子的門上創建Trigger碰撞體 (觸碰到門則出現dialog)
*寫代碼 添加房子的代碼 創建變量gameObject Dialog?
*寫代碼 添加函數 OnTriggerEnter2D 和OnTriggerExit2D if語句如果碰撞體的tag是player的話 則Dialog.SetActive(true/false); (設置開關)
(為text制作淺入淺出動畫)
*為heri中的EnterDialog創建動畫 命名EnterDialog
*點擊紅色圓圈錄制 第一幀透明 第20幀顯現 停止錄制并運行
?
?
14. ? 制作死亡邊界
*level1創建新項目DeadLine 并將其放在布局下面 調整好長度 并將其標簽添加并改成DeadLine
*寫代碼 using UnityEngine.SceneManagement;
*在人物TriggerEnter2D中新增if語句 當collision.tag == "DeadLine"; 時
ScenManager.LoadScene(SceneManager.GetActiveScene().name);
*完善代碼 新建函數Restart() 將切換場景剪切到里面
*在if中添加 Invoke("Restart",1);延遲1秒運行Restart切換場景
繼續添加GetComponent<AudioSource>().enabled = false; 關閉音樂
?
15. ? 制作場景切換
*創建代碼EnterHouse ? using SceneManagement
*在update中寫代碼 if語句 當按下e時 scenManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1) 當前場景編號+1
*打開File Build Settings 將場景拖入 可觀察編號?
*將代碼拖拽加入至 enter的dialog中
同理為場景2 寫返回場景1的代碼
?
16. ? 制作前中后景視覺差 Parallax
*新建Area 拷貝背景的多邊形碰撞體至Area中 刪除背景的碰撞體 將攝像機重新設置好
新建代碼Parallax
*寫代碼 添加變量float MoveRate(調整幅度)float StartPoint(確定初始位置)transform Camera(調整位置)
*寫代碼 Start中獲取StartPoint = transform.posion.x
*添加y軸變量 ?
*添加bool變量 lockY
*update添加if 如果lockY 則運行之前的代碼 else y軸 = 初始坐標y + 鏡頭移動*幅度
*將不希望上下移動的物件的lockY勾選
?
17. ? 創建菜單
*新建場景Menu
*添加UI Panel 改為黑色 將Source Image(原圖像)改為null
*再添加 Panel 控制顏色 改Scource為其添加組件Button Text Mesh... 添加按鈕
*調整按鈕大小 text文字 顏色
*寫代碼 Menu 直接創建函數 PlayGame()SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
*添加函數QuitGame()Application.Quit();
*將代碼添加到按鈕的父類中 在按鈕里的On Click組件選擇父類 選擇PlayGame函數 此時運行游戲可點擊按鈕進入
?
?
18. ? 制作音軌
*Assets新建Audio Mixer命名為MainMixer 在Window Audio中找到AudioMixer打開菜單
*為bgm選擇Output 選擇master 將master的Inspector中的Attenuation的volume 右鍵改為可編輯的 expose
調整Menu中的音軌 將最小值設置為-80 最大值0
*寫代碼 在Menu中 新建變量 public AudioMixer AudioMixer 將組件拖入
*寫代碼 新建函數 public void SetVolume(float值) AudioMixer.SetFloat("剛改的可編輯的代碼的名稱",float值);
*為音軌條添加代碼 用SetVolume函數 選擇上面的
*為所有的音效添加master 可一起變換音量
?
19. ? 打包游戲
Build settings中選擇左下角 Player Settings ,設置好自己想要的參數,返回,點擊右下角build將游戲打包。
?
(四)常見問題及解決方法
1.提示unable to access unity services. please log in or request membership to this project
解決方法:①點擊“Window” —— “General” —— “Service”(或者直接快捷鍵 ctrl + 0)②點擊“new link” —— 選擇自己的Project ID —— 點擊“create”。
2.Unity報錯:The variable ... has not been assigned.
解決方法:給物體添加剛體組件。
3.提示UnassignedReferenceException: The variable target of Moving has not been assigned.You probably need to assign the target variable of the Moving script in theinspector.Moving.Update () (at Assets/_Tutorial/Moving.cs:13)
解決方法:把物體拉到tagger里面進行設置。
(五) 致謝
1. ?感謝我的Unity啟蒙老師,麥扣老師,@M_STDIO
2. ?游戲所使用素材均來自Unity商店
3. ?歡迎一起交流學習,有什么問題可以私信我1228193430@qq.com。
?
?
總結
以上是生活随笔為你收集整理的用Unity开发一款2D横版游戏demo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于cocos2dx的横版动作游戏制作(
- 下一篇: 微店新品!微店首款《疯狂野蛮人》横版动作