Placeholder Image

字幕列表 影片播放

  • In Unity 4.3 we're launching our first set of 2D features.

    Unity 4.3 我們發佈了第一階段的2D工具

  • To compliment this we have constructed a

    為此,我們用這個工具做了一個2D範例

  • demo project with these tools.

    這個2D範例叫做"鐵橋塔防"

  • Our 2D platformer is nicknamed 'Tower Bridge Defence'

    描述倫敦鐵橋被外星人入侵的故事

  • It depicts London's Tower Bridge in the midst

    範例完全用2D圖片和物理來呈現 讓你了解這些元素如何在Unity裡組合

  • of an alien invasion.

    影片會說明範例裡的背景、前景、角色、特效 鏡頭追跡、動作和腳本程式是如何製作的

  • It's a completely sprite-based, physics driven

    開始之前,先來聊聊基本的Unity 2D工作

  • 2D sample level that we hope will help you

    首先,當要製作2D專案,你應該先設定工作環境為2D

  • understand how 2D games are put together in Unity.

    可以在建立新專案時在下拉選單設定

  • This video will discuss the background and

    或是在開發中到Edit - Project Settings - Editor調整

  • foreground construction, characters, effects,

    這代表預設情況下,輸入的材質會 被視為2D圖片,場景視圖也會預設為2D

  • camera tracking, animation and scripting

    這個新的2D模式會採用完全的 正視圖視角來呈現你的2D遊戲

  • used in the demo.

    同時也會把右上角的3D小圖示都隱藏 讓工作空間更大

  • To begin with, let's discuss the basics

    除此之外,Unity 2D的工作流程 是和現有的3D流程整合在一起的

  • of working in 2D in Unity.

    如果你已經會操作原本的Unity 那Unity 2D會很好上手

  • Firstly, when working in 2D, you should set the

    值得一提的是,你也可以混搭2D和3D共用

  • Editor Behaviour Mode to 2D

    所以如果你想要有3D元素在你的2D遊戲裡 或2D元素在3D遊戲裡都沒有問題

  • for various settings.

    現在來看看範例如何建立一個關卡

  • This can be done when making a new project

    我們一開始勾勒關卡設計雛形 然後到Photoshop裡面去把每個圖層做出來

  • using the drop-down on the project wizard

    然後輸出這些圖層 成為新的Sprite類型導入Unity

  • or during a project by choosing

    為了呈現出背景的視差,我們做了一些 背景元素在Sorting Layer裡

  • Edit - Project Settings - Editor from the top menu.

    這是一個2D工具的新功能

  • This means that by default textures

    當所有背景指定到這一層後 我們可以在圖片著色器的圖層排序它們

  • will be imported as sprites and the

    調好位置之後也可以把圖層鎖定不能編輯

  • Scene View will default to 2D mode.

    這樣的話我們編輯前景元素的時候 就不用擔心會不小心動到背景元素

  • This new mode gives you a completely orthographic

    可以從介面右上方的圖層選單來設定

  • view in which to construct 2D games.

    由於背景只是裝飾用的,所以 並不需要在圖片上放任何元件

  • It also hides the usual 3D gizmo

    將它們放到一個空的物件裡

  • in the top right of the view, giving you more space

    並放入一個叫做叫做 BackgroundParallax的腳本來處裡視差

  • to work in. Aside from these settings the work

    更多的細節可以詳查這個已經註解的腳本

  • flows for 2D have been designed to mirror

    接下來製作角色活動的前景空間

  • existing Unity approaches to 3D game creation.

    我們設計了倫敦鐵橋和降落在中間的飛碟

  • So if you already know a little about Unity

    主角處於一個敵人從天而降並到處亂竄的環境

  • you'll be in a great position to start making

    因此,每一個前景元素都需要 碰撞體(Collider)來讓主角在上面行走

  • 2D games right away.

    大多數環境用方體碰撞就可以 除了外型比較複雜的飛碟

  • It's worth noting at this stage that you can

    Unity提供多邊形碰撞體(Polygon Collider) 可以根據圖片外型自動產生多邊形碰撞體

  • still mix 2D and 3D in Unity,

    甚至可以調整碰撞體的外型

  • so if you want to add 3D elements to your 2D game

    你可以新增、移動或刪除節點 調整到更適合行走的外型

  • or vice versa you can do that with no worries.

    為了排序前景元素我們建立了前景層 設定顯示在背景之前

  • Let's take a look at the demo project itself,

    接下來看看主角

  • and how we built it up one stage at a time.

    我們的主角也是在Photoshop裡面設計的 一個四肢獨立類似卡通主角雷曼的角色

  • We began by sketching out the level design

    另外一個2D工具的新功能

  • for this sample level and then went about

    是一個以圖表化的動畫工具 可以在Photoshop裡繪製每一節點的圖

  • recreating the layout in Photoshop.

    後面我們會介紹如何用這方法 製造我們的天鵝

  • Creating and exporting the layers,

    因為身體部位分開比較好控制動畫 因此我們希望獨立每個身體部位

  • we were able to import these in to Unity

    所以我們將身體部位獨立切開 好讓Unity在輸入時容易拆離它們

  • using the new Sprite type.

    這代表我們可以為圖片單獨製作動作

  • In order to create parallaxing in our background later,

    把這些部位放入建好的角色層 然後改變Z軸深度來改變前後順序

  • we kept some of the background elements separate

    把這些圖片都放入一個有控制腳本 碰撞體、物理設定等等的物件

  • and placed them on to a Background Sorting Layer.

    一旦做到這裡,就可以到動畫視窗給予圖片動作 建立待機、跑、跳、射擊和死亡的動畫

  • Yet another new feature of 2D development in Unity.

    使用動畫視窗裡新的分鏡表功能 就可以簡單製作動作

  • Having assigned all of our backgrounds to this layer,

    我們在父物件建立一個動畫元件 然後針對每一個子物件建立影格

  • we could then use the Order In Layer property

    移動指標到想要的影格後調整角色部位 就會自動把變量錄到影格上

  • of the Sprite Renderer to sort them.

    可隨時切換分鏡表和動畫曲線 使得它更容易調整設計

  • Once we were happy with their positions

    這些動作建立好之後我們可以 幫我們的角色設計控制狀態

  • we could lock the Background Sorting Layer

    讓我們用程式呼叫角色執行各種動作

  • so that when we added foreground elements

    因為不是驅動3D骨架,所以取消打勾Root Motion

  • we didn't need to worry about accidentally

    也可以打勾Animate Physics如果 動畫要和物理行為相互作用

  • dragging background elements around.

    為了在場景走動,主角腳上有圓形碰撞體 和一個包覆整個身體的方形碰撞體

  • This is done using the Layers pull-down in the

    這樣他可以平順地行走和跳下場景 跳起來的時候頭部也可以判定撞到

  • top right of the interface.

    為了控制角色動作,我們寫了 一個腳本透過2D物理引擎來移動

  • Because the background elements are purely decorative

    這代表在遊戲裡面可以指定主角和敵人 讓遊戲動態更豐富的物理行為

  • we did not require any additional components

    我們用PlayerControl腳本來判斷角色的輸入

  • on the sprite game object.

    我們在此指定物理移動速度 同時也把輸入的值送到動畫控制器

  • They were parented to an empty game object

    判定播放哪些動畫以及 順暢的播放分鏡表上圖片的轉變

  • that has a simple script to handle parallaxing

    使用動畫控制建立圖片動態最大的好處是

  • called BackgroundParallax.

    可以調整動畫速度用來搭配物理速度 不需要額外再作任何判定

  • For more information you'll find this script

    FixedUpdate函式會檢查每一步物理運算

  • fully commented in the Scripts folder.

    在這裡我們第一件要做的事情是 把輸入的水平值傳給動畫的速度參數

  • Next up came the creation of the foreground elements

    在我們的狀態設定裡 待機狀態到跑動需要速度參數大於0.1

  • that our characters would actually traverse.

    當值成立時,動畫就會從待機切到跑步

  • We designed London's Tower Bridge with a UFO

    要讓角色移動,讓它有Rigidbody2D元件 就可以為它加力道移動

  • landed in the centre.

    同時我們也根據輸入的水平值是 大於0或小於0來處理角色面朝的方向

  • The character has the run of the environment

    這是因為在Unity裡,按住左鍵會傳回-1 而按住右鍵會傳回+1

  • as enemies spawn from the skies and begin

    根據輸入值呼叫一個簡單的翻轉函數 來翻轉角色的X軸縮放,讓角色面向反方向

  • to navigate around the level.

    為了判定角色是否著地 我們新增了一個Ground圖層

  • As such, each piece of the foreground required

    並指定給全部可行走的前景物件

  • a collider for characters to walk upon.

    然後使用2D裡面的Linecast函數 檢查Ground圖層是否和角色的腳接觸

  • For most of the environment we used 2D

    為了讓製作更容易,我們建立了 一個空白的物件當作檢查地面的標準點

  • box colliders for efficiency,

    在該物件上增加一個小圖示 我們就可以控制角色到地面的距離

  • but the UFO itself has a more complex shape.

    就遊戲角度來看 角色在地面時只能做跳的動作

  • Unity's Polygon Collider allowed us to

    更多關於角色控制的資訊 可以查看範例腳本裡面的說明

  • automate creation of the collider itself

    影片稍後也會討論角色的武器

  • based on the shape of the sprite.

    接下來看看相機如何追蹤角色

  • It even meant that we could tweak the shape of

    跟3D遊戲一樣,在2D遊戲裡 鏡頭運鏡也左右著遊戲體驗

  • the collider later.

    要呈現經典的2D遊戲運鏡 我們參考了2D遊戲經典大作

  • Moving, adding or subtracting points

    任天堂或超任的超級瑪莉歐的鏡頭運作

  • of the collider shape to make it more

    在超級瑪莉歐世界裡鏡頭會水平移動 除了封閉的空間或關卡邊緣

  • appropriate to walk over.

    在這兩類區域裡角色小幅移動 鏡頭不會追蹤

  • To sort these foregrounds we created a

    一旦角色移出區域 鏡頭又會開始追蹤角色

  • Foregrounds Sorting Layer, which was drawn

    超級瑪莉歐的相機 用特定高度來進行垂直判定

  • above the backgrounds in the Tags And Layers manager.

    但我們的遊戲沒有往上的長度 比較像動作平台,所以不需要這類設定

  • Next, let's take a look at our hero.

    因此我們的相機在垂直判定 採用了和水平一樣的方法

  • Our player character was yet again designed

    請看看主相機裡的CameraFollow腳本 了解鏡頭追蹤更完整的寫法和註解

  • in Photoshop, and for this demo

    遊戲中有許多特效 但最重要的是主角殺死外星人的能力

  • we chose to make a character with independent

    主角會發射一個具有 反作用力動畫的火箭筒

  • limbs and features in the style of

    這個動畫由幾個部分組成

  • 2D hits such as Rayman.

    首先檢查輸入,當按下Fire鍵時 產生一個火箭,播放音效並觸發火箭動畫播放

  • Our other option would have been to design

    讓我們進一步分解這些步驟

  • a sprite sheet-based animation and design each

    為了可以播放其他動畫(跑步)時同時播放火箭發射 我們在動畫控制器建立了Shooting的動畫層

  • each frame in Photoshop,

    將Weight屬性設為1,可以 完全覆蓋基本層(Base Layer)所有的動作

  • an approach we use later for the background Swan,

    我們可以從任何狀態中用程式 觸發Shoot參數發射動畫

  • which we'll discuss later in the video.

    來看看負責這工作的Gun腳本

  • Because our character had independent elements

    你可以看到我們寫了驅動事件 觸發Shoot為True

  • that we wish to animate we finalised the design

    觸發後會打開,在下一格重置為關 就可以重複使用,對於射擊動作最好用

  • and then moved his bodily elements in to separate

    除了設定動畫,我們也從腳本中發射火箭

  • spaces on our canvas to allow Unity to isolate them

    播放音效後根據角色的方向 產生火箭並給它一個X軸的正或負速度

  • as separate sprites in the Importer.

    這個Gun腳本被放在主角身上的空物件

  • This meant that we could then arrange all of

    像這樣將腳本放到一個空物件上 可以輕易的定位火箭發射位置

  • our sprites as separate elements to be animated.

    我們將物件放到火箭筒發射口 然後以他自己的座標當作發射點

  • We placed these on to a new Character Sorting Layer

    火箭本身有2D剛體 我們給它一個速度讓它移動

  • that we created, and then used Z values in the

    它也有火焰噴射動畫和粒子系統做的煙霧

  • transform to sort their rendering depth.

    粒子系統也接受新的Sprite圖片

  • All of these sprites are then arranged under an

    所以可以將煙霧的圖片切好後加到材質 並指定到粒子系統的Texture Sheet Animation

  • empty game object, which has all of our

    就有煙霧特效讓粒子系統發射

  • controls scripting, colliders, physics, excetera attached to it.

    當火箭命中敵人或環境時 火箭本身會引起爆炸並被摧毀

  • Once we'd done this we were able to use the newly

    爆炸是我們製作的爆炸動畫物件

  • upgraded Animation window to create

    排序位置在前景的最後面

  • Idle, Run, Jump, Shoot and Death animations

    要建立這類動畫,可以從專案點選圖片 然後在屬性Sprite Mode選擇Multiple

  • by animating each of the character's sprites over time.

    這功能允許我們編輯圖片 手動或是自動裁切圖片大小

  • With the new Dopesheet View in the Animation window

    一旦完成裁切後

  • this is easier than ever.

    只需要點擊Apply Unity會自動產生圖片並作為子物件

  • We simply add animation to the parent object

    這就是火箭製作過程

  • and then create keyframes for any of the child objects.

    稍後我們將在影片中討論 殺死敵人的動畫技法

  • Moving the playhead to where we want

    現在先讓我們回到主角 看看如何處理血條補血和扣血

  • and then moving the various parts of the character

    血條被定義為一個浮點數(Float) 每次碰到敵人就會呼叫TakeDamage函式

  • to automatically keyframe the animation.

    為了避免觸發太快造成死亡 我們用repeatDamagePeriod來間隔觸發時間

  • The ability to switch between Curve and Dopesheet

    為了讓角色顯示受傷 並容易從敵人手中逃脫

  • representation of our animation makes it easier than

    我們建立了受傷的動作 並在物理上彈飛主角

  • ever to adjust timing and design.

    要做到這點,TakeDamage函式 會阻止角色跳躍

  • With these animations created we can

    並從主角與敵人之間找到一個向量位置

  • then design a state machine for our character

    指定一個物理力量往指定方向擊退

  • so that when called upon in code, differing animations

    hurtForce是一個全域變數,可以隨時從介面調整 而不用從腳本裡調整

  • could be played.

    除了擊退主角之外,我們同時 也扣掉角色的血量並更新血條

  • the animator controller for the character is

    為了呈現扣血,我們把血條的寬度縮減 用一個公式計算讓綠色轉變到紅色

  • not driving a 3D biped, so we simply deselect

    透過當下的血量和總量算出一個百分比

  • Apply Root Motion and select Animate Physics

    血條是由兩個圖片組成 一個顯示血量,另一個顯示外框

  • in order to drive our animations in time with

    這也是在Photoshop裡做的 然後輸出兩個單獨的圖片

  • the physics engine.

    導入圖形的時候,設定圖形軸心在左邊 所以當它按比例減少時,就會往左縮

  • In order to traverse the environment our hero has a

    這兩個圖片放在一個空物件底下 給予一個簡單腳本,讓它顯示在角色頭上

  • circle collider at his feet and a box collider

    將血條位置設定與角色相同

  • to cover the rest of his body outline.

    並加上偏移用的全域變數 好在檢視介面進行調整

  • This means he can smoothly walk up and down hills

    當主角血量為0時,設定碰撞體的isTrigger = true 主角就會往下跌到水上

  • and when he jumps his head will hit the ceiling.

    同時將主角排序推到UI層上 主角會移到畫面最上層

  • In order to control the character and it's animations

    UI層是我們製作的層 是用來表示像UI的前面的物件

  • we wrote a script that moves him via 2D physics forces.

    當腳色死亡時,我們有兩個動畫

  • This means that we can apply physics to him

    一個叫Death,會失去帽子和槍 另外一個叫Falling

  • and the enemies during the game for more

    用Exit Time當作動畫的切換條件 一旦Death播完就會切到Falling動畫

  • dynamic game play.

    最後,在播放死亡動畫時 為了阻止玩家移動角色或射擊

  • In our PlayerControl script for the character

    我們會禁用PlayerControl和Gun腳本

  • we check for player input.

    由於Die函式是全域可以從任何地方呼叫 例如玩家掉入水中

  • We use this to apply physics forces

    要在主角接觸水面時重置遊戲,我們 用一個由觸發器和腳本組成的KillTrigger物件

  • for movement and also send the value of the input

    在大多的情況下 Remover腳本移除掉入河中的敵人

  • to the animator, which in turn defines which

    並播放一個水花動畫和音效

  • animation should be playing and smoothly transitions

    但如果是主角被觸發器偵測到時

  • between the different animation clips that

    就會呼叫PlayerHealth腳本裡的Die函式

  • we've created as states.

    並禁用CameraTracking同時將角色移出螢幕 並呼叫co-routiene函數(停止2秒)

  • The great thing about using the animator to

    然後重生在出生點

  • create states from animation clips is

    接下來焦點轉移到角色生存

  • that we can go and tweak speeds of animation

    來看看它是如何生存 和我們給予它甚麼生存工具

  • to match our physics velocities

    遊戲中有兩種幫助玩家的補給箱 一種箱子是炸彈,另一種可以補血

  • without having to reanimate anything

    補給箱由箱子和降落傘兩個部分組成

  • The FixedUpdate function evaluates with

    這兩個元素放入一個空白物件 我們就可以一起觸發動畫

  • each physics step, and the first thing we

    我們定位這兩個圖片 降落傘的軸心位於父物件的中心

  • do with this is to feed the value of Horizontal

    這樣動畫可以左右搖擺 讓降落傘是浮在空中的感覺

  • input in to the Speed parameter of our animator.

    然後增加一個剛體讓它有重力往下掉

  • The transition between Idle and Run

    箱子增加碰撞體用來探測它的著陸時機 和玩家撿起的時機

  • in our simple state machine requires

    著陸之後 播放第二段動畫讓降落傘消失

  • that the Speed parameter is above 0.1.

    跟遊戲其他地方一樣 動畫器控制物件的狀態

  • When it is, the animator blends from Idle

    我們可以看到預設的情況下 它會播放FloatDown動畫

  • in to the Run state.

    然後當Land = True時會切換到著陸狀態

  • We then go on to add forces to the player's

    在腳本裡,我們使用onTriggerEnter函數 透過標記來檢測是否碰到地面

  • 2D physics component, the rigidbody2D,

    我們也將補給箱從父物件中分離 並給它一個剛體

  • in order to move him around.

    它就可以和環境互動 比如降落在一個斜坡上就會斜停在坡上

  • We also handle which direction the character is facing

    接下來看看炸彈

  • based on the value of Horizontal input,

    撿起炸彈箱的動作是箱子上的 BombPickup腳本處理的

  • checking whether it is above or below 0.

    透過角色身上的LayBombs腳本 增減主角擁有的炸彈數量

  • This is because in Unity, holding the left input key

    LayBombs腳本負責檢查是否攜帶著炸彈 並負責產生並放置炸彈

  • returns a value of -1, where right returns positive 1.

    炸彈設有定時裝置,在爆炸之前 透過BombDetonation裡的yield倒數計時

  • Depending on input, we then call a simple flip function,

    爆炸函式執行幾個動作

  • which reverses the X scale of the character,

    它會重置bombLaid參數 允許產生另外一個炸彈箱

  • giving him the appearance of facing the opposite direction.

    它會通知產生器補充新的炸彈箱 並炸死範圍內的敵人

  • To decide whether the player is grounded

    來看看最後一部分怎麼運作的

  • we added a layer in Unity called Ground

    因為炸彈對敵人來說是致命的 不管他們的生命值剩下多少

  • and applied it to all of our walkable foreground surfaces.

    我們用Physics.OverlapCircleAll方法收集 在爆炸範圍內所有標記為敵人的對象

  • We then used the Linecast function in 2D

    然後為每一個敵人執行迴圈

  • to check whether something on the Ground layer

    設定他們的血量為0 從爆炸地點到敵人算出一個向量並施加外力

  • is below the character's feet.

    一旦迴圈跑完,就可以播放視覺效果

  • To customise this more easily we created

    播放一段音效同時摧毀炸彈

  • an empty game object to use as a point

    爆炸視覺效果有兩部分

  • at which to check for the ground.

    主要部份是一個簡單的圓形 短暫的出現後摧毀

  • By adding a gizmo to this empty object

    第二部分是星星狀的粒子系統 重複用相同圖片呈現火箭爆炸

  • we are able to manipulate how far below

    效率上我們保持粒子系統持續在場景中 需要時我們用程式移動到指定位置播放

  • the character we'll check for the ground.

    這樣可以讓粒子系統存在記憶體裡 使遊戲比較有效率

  • From a gameplay perspective this means that

    這麼做主要是因為這個範例 同時只會有一個爆炸在場景中

  • the character can only jump when grounded.

    因為玩家只能一次丟一個炸彈

  • Check out the rest of the comments in the script for more

    這就是為什麼將粒子系統保持在場景中 並重複播放的原因,比起建立後移除有效率

  • information on the control of the player.

    但如果是火箭爆炸,因為可以重複發射 因此需要建立後移除

  • We will discuss the player's weapon

    讓我們看看主角殺死敵人 怎麼計算分數

  • later in this video.

    這分為兩個部分,動畫顯示獲得100分 以及增加UI的分數計算

  • Next, let's take a look at how the camera

    分數動畫由1和0兩個數字組成

  • tracks the player in our demo.

    將它們放到場景中的空白物件

  • In 2D games, much like 3D, the motion of

    給予一個簡單的得分動畫 並用程式讓它們在動畫完成後消失

  • the camera tracking the action can make

    我們放置摧毀腳本在動畫事件尾端

  • or break your game.

    ScoreUI單純是個GUI文字元件 帶有管理玩家分數的腳本

  • For a classic 2D platformer, we looked at the mechanics

    Score是全域變數,代表隨時可以 檢查當敵人被殺死時增加100分

  • of one of the most interesting camera in 2D gaming history,

    說到敵人,讓我們仔細看看他們

  • the camera from Super Mario World on the Super Nintendo

    在我們的遊戲裡,有兩種類型外星敵人

  • or Super Famicom.

    一種是綠皮膚的鼻涕蟲

  • In Super Mario world the camera tracks

    另一種是會搭著飛船保護自己 的智慧型外星怪物

  • horizontally, but uses a dead zone

    這些角色會共用一種腳本

  • or margin in the centre of the viewport

    因為他們行為相似

  • in which the character can move a little

    我們可以檢視它們的全域變數 並設定不同的移動速度和生命

  • without the camera tracking.

    每個敵人都有自己的移動動畫

  • Once the character moved beyond this margin

    鼻涕蟲有一個可以活動的尾巴 飛船內的敵人會前後搖擺移動

  • the camera tracks back toward the player.

    對鼻涕蟲來說,我們匯入圖形 並把尾巴切為獨立圖形

  • The Super Mario World camera used particular heights

    這樣我們就可以單獨縮放它 不會影響到整個圖片

  • to snap to vertically, but we didn't need this

    軸心設定到右邊 我們可以漂亮的伸展收縮尾巴

  • kind of detail for our game as we

    上下移動眼瞼

  • do not have a long level in the X axis

    然後使用Z軸來排序 眼睛就會在眼瞼底下了

  • but more of a stage on which the action takes place.

    就可以製作眨眼動畫

  • For this reason our camera employs

    第二個外星人的動畫要簡單的多 我們只需要前後轉動它

  • similar tracking vertically as it does horizontally.

    關於這些敵人的移動技術 我們透過改變剛體的速率來移動它們

  • Take a look at the CameraFollow script on the

    當它們遇到一個牆壁這樣的障礙物時 會呼叫Physics.OverlapPoint函式來檢測

  • mainCamera game object to see comments

    檢查是否有重疊到像是 牆壁和兩邊的塔被標記的障礙物

  • on how it achieves this effect.

    當函式偵測到時,就會呼叫Flip函式

  • There are several effects in the game,

    函式會翻轉敵人的X軸縮放 讓它轉到不同方向

  • but most important is our heroes ability

    要殺死敵人,當敵人和火箭相撞時 在撞擊時會呼叫Hurt函式

  • to slay the alien onslaught he's faced with.

    這個函式我們從敵人身上扣1點血

  • Our hero shoots a bazooka which has animated recoil.

    並持續呼叫函式保持敵人持續扣血

  • This action is made up of several parts.

    如果血條降到0,就會呼叫死亡函式

  • First we listen for key input and when the Fire key is

    當他們死後,就會執行一些函式

  • pressed we instantiate a rocket,

    會先停用所有的圖形渲染 因為2D角色大多都有動畫

  • play an audio clip and trigger an animation state to play.

    這是為了把動畫物件換成單張死亡圖片

  • Let's break this down even further.

    我們在圖形渲染器將圖片改為deadEnemy

  • in order to play the Shoot animation while other

    然後我們幫Score全域變數增加100

  • animations such as Run are playing we

    然後增加扭轉讓他們死亡時扭曲

  • created a separate layer within our animator

    因此我們要讓這些敵人死後 掉入環境的河中

  • called Shooting.

    我們找到物件上所有碰撞體 並設定IsTrigger = True

  • By setting the Weight property to 1 here

    這樣他們就會穿過所有環境往下掉

  • we can totally override motion in the base layer

    然後播放死亡音效之後展示一個分數動畫

  • on any parts of our character that are animated

    要將已死亡的敵人從場景中移除

  • by clips on the shooting layer.

    我們使用killTregger物件

  • In this layer we switch to the Shoot animation

    和前面所說的一樣

  • from any state, when the Shoot trigger

    當任何角色接觸它時

  • parameter is called from code.

    將會引起一個水花動畫,並移除該物件

  • Let's take a look at the Gun script in charge of this.

    它們撞擊水面並播放 一段附在水花動畫的音效

  • Here you can see that we address the animator

    所以當我們產生水花動畫時 同時也聽到音效

  • and set that trigger to True.

    要完成遊戲關卡 我們也用一些移動背景來裝飾

  • Triggers simply act as a switch and reset themselves to false

    為了讓遊戲環境更顯動態

  • on the next frame so that they can be called again,

    我們添加了一些飛翔的天鵝 以及沿著河岸開的公車和計程車

  • which is perfect for actions such as shooting.

    首先是天鵝,它是在Photoshop裡面畫好後 用Multiple Sprite導入圖片

  • In addition to setting the animation we fire the

    Unity會自動裁切天鵝的每個圖片

  • rockets themselves from this script,

    分為不同的圖導入 並把原圖當作父物件放在底下

  • playing an audio clip and dependent upon

    因為這是個動畫組合,可以將所有的圖片 一起拖到場景中,讓Unity幫我們生成動畫

  • the direction that the player is facing

    瞧,天鵝的動畫已經準備好了

  • we instantiate a rocket and give it a velocity

    然後給天鵝一個剛體 讓我們可以控制速度飛過螢幕

  • that's positive or negative in the X axis.

    和公車和計程車一樣,天鵝已被存為預製物件

  • This script is attached to the Gun empty game object

    公車和計程車作法只需要 在匯入圖形時分開車身和車輪

  • in the hero's hierarchy.

    並製作一個簡單的擺動動畫

  • We place code like this on to an empty game object

    相同指定2D剛體到車子上 就能夠驅動他們在螢幕上跑

  • as it allows us to easily position

    公車、計程車和天鵝這三個物件 我們用一個重複執行的腳本來製造它們

  • where the rockets are created.

    BackgroundPropsSpawner腳本 同時也處理出生位置,出生頻率並給予速度

  • We do this by placing the empty object

    代表我們可以用這個腳本應用在三種對象 預設出生點和屬性

  • at the end of the barrel of the bazooka

    要了解更多的細節,可以查看腳本中的說明

  • and then we use it's own position as the

    最後,要了解更多的背景動態 我們使用了移動的雲朵、流動的河水和煙霧

  • point at which to spawn the rockets.

    我們在空白物件下放兩個背景圖片 並使這些圖片緩慢飛過螢幕

  • The rocket itself has a 2D rigidbody

    因為這是個無限循環 所以動畫永遠不會停

  • and we assign a velocity to that in order

    這就是我們遊戲的製作過程

  • to make it move.

    我們希望這個教學讓你 對如何用Unity開發2D遊戲有一定了解

  • It has a sprite swap flame exhaust

    未來我們也會製作更簡單的教學

  • plus a particle system for smoke.

    也期待你們對於Unity4.3的反應 迫不及待想看看你們的2D產品

  • The particle system also accepts the new sprite type of graphics

    謝謝觀看

  • so by adding a sprite sheet of smoke puffs

  • to a material we can assign it to the

  • texture sheet animation module of the particle system

  • and we get instant animation of our

  • sprites for the particle emission.

  • When our rockets hit an enemy or part of the environment

  • the rocket itself is destroyed and

  • an explosion is spawned.

  • The explosion is simply a sprite game object

  • that animates through a sprite sheet that we have created.

  • Yet again using sorting layers to render this

  • at the lowest layer order of our foreground objects.

  • When adding sprite-based animation like this

  • we setup the sprites themselves by

  • selecting the file in our Project Panel

  • and choosing the Sprite Mode Multiple.

  • This gives us access to the sprite editor

  • which allows us to slice manually or automatically.

  • Once happy with the selection of sprites from our file

  • we simply hit Apply and Unity

  • generates the sprites as children of that file

  • to be used in our project.

  • So that's our rocket in a nutshell.

  • We will discuss the mechanics of killing the enemies

  • later in this video in the section about enemies.

  • Let's return to the player character now and look at

  • how we handle health and taking damage.

  • Health is stored as a float and

  • with each interaction with a tagged enemy

  • we call the TakeDamage function.

  • This is only allowed to occur after the

  • repeatDamagePeriod has passed

  • to avoid the player being killed very quickly.

  • To allow the player to escape enemies more easily

  • and to show the player that they are being hurt

  • we make the act of taking damage

  • repel the character physically.

  • To achieve this the TakeDamage function briefly

  • stops the player from jumping

  • and finds a vector from the enemy to the player

  • and repels him in that direction

  • by adding a physics force.

  • The hurtForce variable is exposed in the Inspector

  • as public so that it can be tweaked

  • to adjust this element of game play without

  • returning to the script.

  • In addition to repelling the player,

  • we of course subtract from the player's health.

  • and update the player's health bar.

  • To signify the decrease in health we subtract

  • from the width of the bar and use a colour lerp

  • to transition it's colour between green and red,

  • both by finding the percentage that the current health is

  • of the full health amount.

  • The health bar simply comprises of two sprites,

  • one for the outline of the bar and the other

  • for the bar itself.

  • This was again designed in Photoshop and then

  • the two separate elements were exported.

  • In the import settings for these sprites

  • we set their pivot to the middle left of the graphic

  • so that when it scales down it shrinks towards the left.

  • These two sprites are placed under an empty

  • parent game object which has a simple script

  • on it which makes it follow the player.

  • We do this by setting the position to the

  • same as the player object's position

  • plus an offset that we've made public to allow

  • for adjustment in the Inspector.

  • When the player has 0 health remaining

  • we allow him to fall through the level by

  • setting his colliders to triggers,

  • and we move him to the very front of rendering

  • by placing his sprite renderers on the UI Sorting layer,

  • one we've made to render in front of everything in the game.

  • We have 2 animations for when the player dies.

  • 1 called Death, where he loses his hat and gun

  • and another called Falling.

  • We naturally transition in to Falling once

  • the Death animation completes by using the Exit Time

  • as our transition condition in the animator.

  • Finally, to stop the player moving the character

  • or shooting during the Death sequence

  • we disable the PlayerControl and Gun scripts.

  • Because the Die function is made as public

  • we can call it from elsewhere, such as if the player

  • falls in to the water.

  • To reset the game once the player does hit the water

  • we have a KillTrigger object, which simply

  • comprises of a trigger collider and a script.

  • For most of the game the purpose of the Remover script

  • is to remove our enemy objects that fall in

  • to the river, and instantiate a splash animation

  • and sound effect.

  • However, when the player is detected by this trigger

  • we call the Die function in the PlayerHealth script

  • and also disable CameraTracking

  • whilst moving the player off screen

  • and calling a co-routiene that pauses for 2 seconds

  • and then reloads the level.

  • But let's not dwell on the death of the player,

  • let's look at his survival and the tools that we give

  • him to do that.

  • Our game features 2 airdropped crates that

  • assist the player, 1 containing a bomb,

  • the other a med kit to boost health.

  • These crate drops are made up of 2 parts.

  • The crate itself and a parachute.

  • These 2 elements are nested beneath an empty parent object

  • to allow us to animate them as a group.

  • We position the 2 sprites so that the parachute's

  • centre is at the centre of the parent.

  • This way the animation can swing left and right

  • as if the entire parachuting crate is floating to the ground.

  • We then simply add a rigidbody to cause

  • gravity to pull the object down

  • and add colliders to the crate so that

  • we can detect when it lands and when

  • the player picks up the crate.

  • Upon landing we transition to a second

  • animation state which scales the parachute down.

  • Like other parts of our game, the animator handles

  • the states of the object.

  • We can see that by default it plays the

  • floatDown animation state

  • but then switches to a landing state

  • when the trigger Land is set to true.

  • In our script we do this using an onTriggerEnter function,

  • which detects the ground via a tag.

  • We also detatch the crate itself from the parent object

  • and give it a rigidbody of it's own

  • so that it can interact with the environment

  • resting realistically on a slope if it lands on one.

  • Let's focus on the bomb first of all.

  • Picking up the bomb crate is handled on the

  • BombPickup script, attached to the crate.

  • We pickup the crate by destroying it and adding to

  • the count of bombs that the player has

  • in the script attached to the player called

  • LayBombs

  • The LayBombs script simply checks if

  • the player is carrying a bomb

  • and then instantiates an instance

  • of the Bomb prefab.

  • The Bomb prefab has a timed fuse

  • which waits by using an yield within the

  • BombDetonation co-routiene

  • before calling the Explode function.

  • The Explode function performs several actions.

  • First it resets the bombLaid variable

  • to allow another bomb to be deployed,

  • it tells the pickup spawner it is allowed to

  • spawn a new crate drop and kills

  • enemies within a defined blast radian.

  • Let's take a look at how this last part works.

  • Because bombs are lethal to enemies regardless of

  • their remaining hit points we use the

  • Physics.OverlapCircleAll to collect all objects

  • tagged Enemy within a certain radius of the bomb.

  • We then run a foreach loop for every enemy found

  • setting their health to 0 finding a vector from where the bomb was

  • to where the enemy is, in order to apply

  • a force in the direction of that vector.

  • Once the foreach loop is complete

  • we play and instantiate visual effects,

  • play an audio clip for the explosion

  • and of course destroy the bomb itself.

  • The visual of the explosion is twofold.

  • The main part is a simple circle that appears

  • briefly and is then destroyed

  • and the second part is a particle system of

  • stars that reuses the same sprites

  • as our rocket explosion.

  • For efficiency we keep this particle

  • system in the scene at all times

  • and when it is required we use code

  • to move the system to the desired position and play it.

  • This keeps the particle system in memory

  • and makes the game more efficient.

  • It's worth noting that we can do this

  • because we know we will only have 1

  • single explosion in the scene at any one time

  • as the player can only throw 1 bomb at a time.

  • This is why keeping our particle system in the

  • scene and replaying it is more

  • efficient than creating instances and then removing them.

  • With the rocket explosion however,

  • we can have many at once so we do

  • need to spawn and remove them.

  • Now let's take a look at what happens when our player

  • kills an enemy and scores points.

  • This is done in 2 parts,

  • a scoring animation that plays showing 100 points earned

  • and the score UI at the top of the screen

  • that increments.

  • The score animation is made up to 2 number sprites,

  • a 1 and a 0.

  • We place this in the scene under an empty parent object

  • and animated them using a simple destroyer script to

  • remove them from the scene when the animation is complete.

  • We call the destroyer function in the script

  • by placing an animation event

  • at the end of the timeline.

  • The ScoreUI itself is a simple GUI text component

  • with a custom font and script that manages

  • the score for the player.

  • The Score variable is public, meaning that we can address it

  • from the Enemy script when they are killed

  • and add 100 points to the value.

  • Speaking of the enemies, let's take a look

  • at them more in depth now.

  • In our game we have 2 types of alien enemy,

  • a green slug-like monster and a smarter

  • alien that brought his ship with him for

  • protection during the invasion.

  • These characters share the same script

  • as the behaviour is very similar

  • and we allow for differing movement speeds

  • and amounts of hit points by setting

  • these as public variables in the Inspector.

  • Each enemy has it's own Walk animation.

  • The slug has a moving tail, whist the

  • ship-based enemy rocks back and forth as it approaches.

  • For the slug we used the sprite importer

  • to define the tail section of the graphic

  • as a separate sprite element,

  • meaning that we could animate it individually

  • and avoid having to scale the entire sprite.

  • By setting the pivot to the right

  • we are able to animate the tail expanding and contracting

  • from that point.

  • For added character we then move the eyelid up and down

  • and we use the Z value to sort the sprites

  • amongst one another, the eye being below the eyelid

  • so that we could animate it over the top.

  • The second enemy's animation was much simpler

  • and just meant that we rotated it back and forth.

  • For the mechanics of moving the enemies

  • we drive them by setting the velocity of the rigidbody.

  • When they encounter an obstacle such as a wall

  • they detect this by using a Physics.OverlapPoint function,

  • which checks for a point in space overlapping a collider.

  • Our walls, the towers at each side of the level,

  • are tagged as obstacles.

  • When this function detects them it calls the Flip function,

  • it reverses the X scale of the enemy

  • sending them moving in a different direction.

  • To kill the enemies, each time a rocket collides

  • with them it's script calls the Hurt function on

  • the particular enemy that it's hit.

  • In this function we subtract 1 from the

  • hit points of the particular enemy.

  • We then keep tabs on the enemy's health

  • inside the fixed update function.

  • If it drops to 0 we call the Death function.

  • When they die we perform a number of functions.

  • Firstly we disable all sprite renderers

  • as our 2D characters are made up of a

  • number of sprite objects that are animated.

  • This is because we simply want to swap out the

  • animated elements for a single sprite

  • of the dead character

  • We do this with the main sprite renderer by

  • setting it to use the sprite assigned to

  • the deadEnemy variable.

  • We then add to the score using the public

  • variable in the Score script

  • and we add some visual flare to the enemy's death

  • by adding torque to spin them as they die.

  • Because we need the enemies to fall through the

  • environment and land in the river when they die

  • we find all colliders on the object

  • and set their IsTrigger parameter to true.

  • This means that they will pass through the

  • environment colliders.

  • We then choose from an array of death audio clips

  • and play one of them back, before creating

  • an instance of the Score animation we showed you earlier.

  • To remove the dead enemy from the scene

  • we rely on the killTrigger object

  • It performs the same function as discussed earlier

  • as any non-player object touching it

  • will cause a splash animation and remove that object.

  • The sound effect of them hitting the water is

  • an audio clip attached to the animated

  • splash which plays on awake

  • so that when we create an instance of the animated

  • object we hear the sound right away.

  • To finish the game level re decorated the

  • background with a number of moving props

  • in order to make our game environment feel more dynamic.

  • We added flying swans, plus buses and taxis that drive

  • along the river bank.

  • First was the swan, which was created from a sprite sheet,

  • drawn in Photoshop and imported using

  • the Multiple Sprite Mode import setting

  • in the Inspector.

  • By choosing this approach Unity automates choosing

  • each frame in the sheet and importing

  • it as a separate sprite under the parent

  • hierarchy of the asset.

  • Because this is a linear set of animation frames

  • we could simply drag all of these sprites in to the

  • scene to let Unity animate them for us.

  • Et voila, our animated swan is ready to add

  • as a background element.

  • The swan was then given a rigidbody2D

  • so that we can use velocity to send it

  • across the screen.

  • As with the bus and the cab, the swan is saved as a prefab.

  • For the bus and taxi prefabs we

  • simply separated the bodies and wheels of

  • the vehicles in the sprite importer

  • and made a simple bobbing animation.

  • Applying a 2d rigidbody to these as well,

  • we were able to drive them across the screen

  • using velocity.

  • For all 3 props, the bus, taxi and the swan

  • we created a script we could reuse

  • which is in charge of spawning them.

  • The BackgroundPropsSpawner script

  • also handles the frequency, a speed to give them

  • and where on screen to spawn them.

  • This meant that we could make 3 creator objects

  • with the same script on.

  • Changing which prefab will be spawned

  • and what properties to give it.

  • Take a look at the comments in the script to learn more.

  • Finally, for more background dynamism,

  • we added rolling clouds, panning river details and fog.

  • We did this by adding 2 instances of the background sprite

  • to a parent object and simply used animation to slowly

  • pan them across the screen.

  • Because this animation loops our animation will

  • continue indefinitely.

  • And that's how we made our game.

  • We hope this overview has given you some idea of

  • how we create 2D games in Unity,

  • and we'll be creating more simply projects and

  • tutorials in the future.

  • We look forward to your feedback on Unity4.3

  • and we can't wait to see the great 2D titles

  • that you'll come up with.

  • Thanks for watching.

In Unity 4.3 we're launching our first set of 2D features.

Unity 4.3 我們發佈了第一階段的2D工具

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋