前面三篇已經將Anima2D主要的功能介紹完畢,這邊就來補充一下製作這類動畫會常常用到的一些程式腳本的做法,例如視差無接縫循環背景..之類的,正好Anima2D裡面也有DEMO這些功能,本篇就簡單的介紹一下。
我們可以打開TRex這個示範用的場景,然後看看有那些可以拿來應用的部分。
鏡頭跟隨
首先是,黏在攝影機上的這支Follow.cs顧名思義,它就是用來跟隨物件的。Target的欄位就是用來指定想跟隨的物件的,Offset用來設定偏移量也就是鏡頭相對於該物件的偏移值。
語法說明:
using UnityEngine; using System.Collections; [ExecuteInEditMode]//讓程式在編輯模式下也能即時運行 public class Follow : MonoBehaviour { public Transform target;//目標欄位 public Vector3 offset;//偏移3維變量 void LateUpdate() { if(target)//當有目標 { transform.position = target.position + offset;//攝影機位置=目標位置+偏移量 } } }
循環背景
這部分結構較複雜,總共有四層包在Jungle底下,而Jungle也使用了上面說的Follow.cs跟隨攝影機(且無偏移Offset皆為0),每個Offset負責控制這一條圖層在畫面上的高低位置(Y的值)和前後(Z的值),Foreground下就包含了要循環的圖片以及掛載了SpriteCycleParallax.cs和SpriteCycle.cs兩個腳本,用來設定位移速度和循環拼貼的圖片jungle_0,有的4張或5張(依照圖片尺寸配合畫面,避免穿幫的長度)。
SpriteCycle中只要設定好SpriteRenderers的張數Size: 4再將對應的圖片放入欄位,程式就會自動幫我們排開和拼貼,Offest設定0.5表示用這串圖的總長的一半當中心點。
SpriteCycleParallax一樣要設定一個相對應的位移對象,因此Target放進入攝影機,Factor相對速度因子也就是鏡頭往前移動時背景圖要往後的速度差(X的值)。
語法說明:
using UnityEngine; using System.Collections; [ExecuteInEditMode]//讓程式在編輯模式下也能即時運行 [RequireComponent(typeof(SpriteCycle))]//掛載這隻程式時順便附加SpriteCycle這隻程式 public class SpriteCycleParallax : MonoBehaviour { public Transform target;//目標變數 public Vector2 factor;//相對速度因子 SpriteCycle spriteCicle;//SpriteCycle這隻程式的變數 void Awake() { spriteCicle = GetComponent<SpriteCycle>();//取得SpriteCycle這隻程式的控制 } void Start() { if(!target)//如果目標不存在 { if(Camera.main)//主攝影機存在 { target = Camera.main.transform;//目標=主攝影機 } } } void Update() { if(target && spriteCicle)//目標和SpriteCycle這隻程式都有取得的情況下 { //SpriteCycle程式中的position = 目標對象的X座標乘上相對速度因子的X spriteCicle.position = target.position.x*factor.x; //當前圖片組的原始座標位置Y = 目標對象的Y座標乘上相對速度因子的Y Vector3 localPosition = transform.localPosition; localPosition.y = target.position.y*factor.y; transform.localPosition = localPosition; } } }
using UnityEngine; using System.Collections; using System.Collections.Generic; [ExecuteInEditMode] public class SpriteCycle : MonoBehaviour { //圖變集合清單變數 public List<SpriteRenderer> spriteRenderers = new List<SpriteRenderer>(); [Range(0,1)] public float offset = 0f;//中心位置 float totalWidth = 1f;//總長度 float mPosition = 0f; public float position//位置設定 { get{ return mPosition;//用該變數返回數值 } set { float scaleX = transform.localScale.x;//取得物件的縮放比例 mPosition = value; if(scaleX > 0f)//比例不為零 { mPosition /= scaleX;//計算縮放比例 } Vector3 l_position = Vector3.zero; totalWidth = 0f; //用迴圈總和全部圖片寬度 for(int i = 0; i < spriteRenderers.Count; ++i) { SpriteRenderer sr = spriteRenderers[i]; if(sr) { if(sr.sprite) { sr.transform.localPosition = l_position; l_position.x += sr.sprite.bounds.size.x; totalWidth += sr.sprite.bounds.size.x; } } } float dx = mPosition % totalWidth; //用迴圈循環圖片 for(int i = 0; i < spriteRenderers.Count; ++i) { SpriteRenderer sr = spriteRenderers[i]; if(sr) { if(sr.sprite) { Vector3 localPos = sr.transform.localPosition + Vector3.right*dx; if(localPos.x <= -sr.sprite.bounds.size.x) { localPos.x += totalWidth; }else if(localPos.x > totalWidth) { localPos.x -= totalWidth; } localPos.x -= offset*totalWidth; sr.transform.localPosition = localPos; } } } } } void Awake() { position = 0f; } void OnValidate() { position = 0f; } }
設定好這些參數後,只要控制人物的移動背景就會開始後退,不過要注意的是四層背景退後的速度是不同的,遠的退後的量會比較少,近的移動量就會比較高。