2014年11月20日 星期四

【Unity】Sprite圖形切換及動態圖製作

Unity內的Sprite功能可以在3D環境中建構出2D物件,這是Unity在4.3版本中釋出的2D遊戲開發工具,也是Unity第一次針對2D遊戲開發釋出的功能,引言就說到這裡;Sprite功能在寫下樓梯小遊戲的時候受益良多,但也遇到不少問題,所以這次來講講在Unity內的Sprite功能,有關Sprite圖形切換及動態圖製作,歡迎批評指教,另外這次的成品點這裡

先來提Sprite基本的建置,將準備好的角色各方向圖檔匯入Unity中(這類的圖挺好找的,往RPG製作大師素材的方向去找可以找到許多),接著將圖的Texture Type切換成Sprite,Sprite Mode切換成Multiple,按下Sprite Editor後可以叫出編輯視窗,在這裡透過滑鼠框出需要的圖案,另外Trim功能可以將框線貼緊圖的最邊緣,編輯完後按下Apply後可以看到圖形多出了階層,現在可以把將圖形拉進場景中。

sprite Animation

將圖形拉進場景後可以在場景邊集中看到Sprite的2D物件,這時候我們可以透過圖型下Sprite Renderer的Sprite來看看需要的圖形是不是都有了,在這裡的情況是:我需要再按下上下左右方向件時,顯示出對應的方向圖形。
sprite Animation

接著在Assets資料夾下建立名為Resources的資料夾,將圖檔放進去後把以下的腳本(PlayerController.cs)加入到場景的角色上。

using System.Collections;

public class PlayerController : MonoBehaviour {
 
    void Update () {
        Sprite [] playerSprite = Resources.LoadAll("圖檔名稱");////(1)
        SpriteRenderer playerSpriteRenderer = (SpriteRenderer)GetComponent ("SpriteRenderer");////(2)

        if (Input.GetKey (KeyCode.DownArrow)) 
            playerSpriteRenderer.sprite = playerSprite[0];////(3)
        if (Input.GetKey (KeyCode.LeftArrow)) 
            playerSpriteRenderer.sprite = playerSprite[1];
        if (Input.GetKey (KeyCode.RightArrow)) 
            playerSpriteRenderer.sprite = playerSprite[2];
        if (Input.GetKey (KeyCode.UpArrow)) 
            playerSpriteRenderer.sprite = playerSprite[3];
    }
}
(1)透過讀取Resources資料夾下的圖檔名稱,將Sprite下的圖形子集合全部讀進陣列裡。
(2)透過GetComponent抓取角色物件下的SpriteRenderer,接下來只要修改SpriteRenderer下的Sprite就可以改變圖形。
(3)最後只要對應條件下讀進對應的圖檔陣列位置就可以了。

換圖形的地方就到就到這裡,接下來就是動態圖的部分:
首先在選取場景內角色的狀況下,將Window->Animation的編輯視窗打開,之後選取動畫需要的圖形拉進Animation的編輯場景,另外可以調整Sample數值改變播放速度。
sprite Animation

接著透過Create New Clip新增新的動畫片段,同樣的選取需要的圖形拉進Animation的編輯場景,直到需要的動畫片段都有了,打開Window->Animator看是不是動畫片段都在Animator編輯場景內。
sprite Animation

最後加入以下腳本(PlayerAnimation.cs)到控制角色下就完成了。
using UnityEngine;
using System.Collections;

public class PlayerAnimation : MonoBehaviour {
 
    void Update () {
        Animator playerAnimator = (Animator)GetComponent ("Animator");////(1)

        if (Input.GetKey (KeyCode.DownArrow)) 
            playerAnimator.Play ("動畫名稱1");////(2)
        if (Input.GetKey (KeyCode.LeftArrow)) 
            playerAnimator.Play ("動畫名稱2");
        if (Input.GetKey (KeyCode.RightArrow)) 
            playerAnimator.Play ("動畫名稱3");
        if (Input.GetKey (KeyCode.UpArrow)) 
            playerAnimator.Play ("動畫名稱4");
    }
}
(1)抓物件下的Animator。
(2)透過Play播放對應條件的動畫名稱就可以了。

這次就到這裡了,Sprite意外的還挺好用的,至少比早期很克難的用GUI texture好得多。
之前寫下樓梯的時候,角色的左右切換就是透過前半部讀圖檔的方式完成的,看起來效果還不錯。
做動態圖的地方雖然遇到了Animator,但比起建立State連結在設定參數,直接Play動畫還來的快得多,這裡就不多做其他的細節說明了。
最後慣例的感謝素材提供:
王國興亡記-ドラゴン by そーいち
http://makapri.web.fc2.com/top.html

4 則留言:

  1. 您好
    最近也在嘗試練習sprite這方面的動態動作
    只是依照您的方法在Unity5上面出現了一個錯誤
    Assets/PlayerController.cs(8,26): error CS0266: Cannot implicitly convert type `UnityEngine.Object[]' to `UnityEngine.Sprite[]'. An explicit conversion exists (are you missing a cast?)
    不知道是我在哪個步驟有會錯意做錯了或是有少了什麼動作...
    我把Sprite[] playerSprite = Resources.LoadAll("Angel");
    強制轉成Sprite[] playerSprite = (Resources.LoadAll("Angel")) as Sprite[];
    編譯過了 可是當我按下上下左右 卻變成抓不到Object
    NullReferenceException: Object reference not set to an instance of an object
    請問是版本不一樣 需要更動哪裡嗎?!?!
    謝謝您
    您的教學真的非常棒 :"D

    回覆刪除
    回覆
    1. 您好:
      關於第一個錯誤,可能是Unity版本問題或是當初在寫的時候筆誤。
      因為手邊沒有Unity5以下的版本所以也無法確定。
      另外讀取Sprite陣列
      Sprite [] sprites = Resources.LoadAll("檔案名稱");
      在LoadAll後給變數,這是這陣子寫的,Unity5是OK的寫法。

      刪除
  2. Resources.LoadAll是給object用的,所以確實對不上Sprite。
    修改一下
    Sprite [] sprites = Resources.LoadAll("檔案名稱");
    就可以了喔!

    回覆刪除
  3. 咦~ 修改的部份跑不出來?我再試試
    Sprite [ ] sprites = Resources.LoadAll < Sprite > ("檔案名稱");

    回覆刪除

【自製小遊戲】水平思考猜謎(海龜湯)

遊戲連結 海龜湯的玩法是由出題者提出一個難以理解的事件,參與猜題者可以提出任何問題以試圖縮小範圍並找出事件背後真正的原因。但出題者僅能以「是」、「不是」或「沒有關係」來回答問題。 本遊戲蒐集各種論壇、平台的42個題目,提供給想玩海龜湯卻愁找不到題目的你們。 ...