當前位置:首頁 >教程首頁 > 华体会hth体育app在线登录 > 遊戲動作設計師班 >分享2D Unity遊戲的動畫製作經驗

分享2D Unity遊戲的動畫製作經驗

發布時間:2018-11-17 19:57:24
  Unity最近宣布推出額外的2D遊戲支持,添加了Box 2D物理和一個精靈管理器。

  但這裏還是有些技巧需要牢記在心。逐幀更改圖像隻是動畫製作的冰山一角,若要讓你的遊戲出色運行,你還得使用轉換和旋轉等功能。

  現在讓我們先從基本技巧開始。

  更改幀

  如果你已經準備好了製作動畫的紋理,你可能會使用SpriteManager腳本的付費版本,或者Unity的新版本。假設你使用的是2D位麵和紋理。這就是一個低效率的方法,但如果你是在製作一個game jam的項目,你可能會想塞入一些可行而好看,但卻不一定有效的元素。這也是一種覆蓋了所有步驟的全麵方法,如果是在精靈管理器中則可能被刪除某些步驟。

  首先,你將需要一個公開的Texture[] 陣列,所以你可以將紋理拖入到Unity編輯器中的對象,以及一個在Start()中初始化到0的整數currentTexturep。下一步你需要一個像這樣運行的NextTexture() 函數:

NextTexture(){
currentTexture++;
if(currentTexture>=textureArray.Length) currentTexture=0;
AnimatedPlane.renderer.material.mainTexture = textureArray[currentTexture];}

  有兩種簡便的方法可以調用這種函數:協同程序遞歸和固定間隔。

  使用固定間隔是最快的方法(但較不精確)。你需要一個整數計數器,在你的Start()函數中初始化到0,以及一個FixedUpdate() 函數(注:每次都會更新,你可以在Unity時間管理器中自己調整)。

  在FixedUpdate()中放置你的條件句(例如if(walking)),並在其中用conter++增加你的計時器,之後設置如下聲明:

if(counter>=animationDelay){
counter=0;
extTexture();
}

  這裏的animationDelay可以是你自己選擇的任意值。這將以持續速度(取決於你在Unity時間管理器中設置的速度)推進幀。

  第二個方法是使用遞歸。但這一方法的劣勢在於不易處理條件句,但你還是能夠獲得所需要的準確延時。如果你想讓特定幀延長或縮短,這一方法就尤其管用。你需要一個IEnumerator TextureChanger() 以及to StartCoroutine(TextureChanger()) in Start().

IEnumerator TextureChanger(){
yield return new WaitForSeconds(timeInterval);
if([conditions]) NextTexture();
}

  這裏timeInterval也是你自己選擇的任意值。有了這些函數,你就可以將任意數量的紋理拖到GameObject,這樣隻要你提供正確的條件,它就會正確運行動畫。

  現在讓我們做一些更有趣的操作。

  平滑移動到一個點

  以下公式是製作Unity 2D動畫的一個訣竅:

where 0 < slidespeed < 1. I recommend 0.1f as a good slidespeed value.

  這個公式允許你把對象完美移動到一個點。在滑動GUI、角色控製、關卡生成、攝像跟隨、褪色/移位等操作中尤其管用。

descension

  這是我即將發布的新遊戲《Rotation Station》中的一個高級版本,是從一個較低點移到一個較高點,最後變成一個小泡。每個貼圖都會根據該公司向下移動,但每個貼圖都有隨機的延時,隨機的初始化旋轉(也使用這一公式旋轉至它所期望的方向)。

  關於角色控製的例子可以參考我最近推出的《Rude Bear Radio》,在這個項目中,該公式運用於製作流暢的鼠標控製方法。

Bearo-Wing

  那麼,讓我們看看如何將其運用於上述例子。

  首先,我們需要知道鼠標位於2D區域。為了找到它,我們要先將這個代碼放置於滑動GameObject的FixedUpdate()函數中:

Vector3 MousePosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, transform.position.z-Camera.main.transform.position.z));

  這裏使用了鼠標的X和Y軸位置,以及從攝像機到滑動GameObject的距離來確定鼠標的2D位置和3D坐標。現在我們要從這個環節的開端來調整該公式。所以,要記住Unity中的2D步驟。

transform.position += new Vector3((MousePosition.x-transform.position.x),
(MousePosition.y-transform.position.y),0)*slidespeed;

  你就隻要這兩行代碼就搞定了!至於GUI這類東西,你可以在之後編寫一個聲明:

if(Mathf.Abs(finalvalue-currentvalue)

  讓我們再看另一個例子,《Rude Bear Radio》中的困難模式Mario台階。

Super-Bario-Bros

  其中的背景使用以下公式由黑變白:

background.renderer.material.color =
(1-factor)*background.renderer.material.color+factor*desiredcolor;

  你從中可以看到它遵從的基本形式,簡寫就是Next = current+(final-current)*factor。代碼會檢查R值是否處於一定的色彩範圍,如果是,它就會更改factor,令其更為迅速地褪色。如果R值非常接近於1,它就會將其所需顏色設置為黑。你還可以檢查下R、G和B,並以一個陣列推進顏色。你可以在我的第二個案例項目《Rude Bear Rising》的背景中看到這種例子。

  目前來看,這些都很簡單,你可以照搬公式做。而下一步操作則需要考慮更多因素。

  三角法和數學的重要性

  三角法對動畫製作來說非常重要。就算有了優秀的幀,也不一定能夠令它們看起來生動美麗,有時候你根本不需要幀就能做事。

  例如,我首次進入Ludum Dare工作室時,我的室友就給我畫了幾張圖。我至今仍然記得其中的每個角色,用什麼方法呢?像木偶一樣將角色綁在棍子上操作。

RudeBear

  這種移動方式非常簡單,轉換時用正弦(sin),旋轉時用餘弦(cos)。

  為了創造這種動畫,你要讓波紋停止並在你鬆手和輸入時繼續,否則這種動作就會極端分散。

  所以你需要一個首要變量(即我所謂的walkbob),隻要對象還在移動,它就會在FixedUpdate中增加Time.deltaTime。之後就製作你的函數:

translation = maxHeight*Mathf.Sin(speed*walkbob);
rotation =  maxRoll*Mathf.Cos(speed*walkbob/2);

  然後將位置和旋轉設為這些值(例如transform.position = new Vector3(transform.position.x,translation,transform.position.y))。

  這可以處理類似那種動作,但是還有一種動畫需要考慮更多因素,這就是我所謂的三角舞,它用於製作可愛角色隨著音樂搖擺起舞,例如下圖:

Rude-Bear-Radio

  首先,你在打算移動遊戲對象時,就要選取一個浮動的initialtime = Time.time,這樣你的對象才能以正確的位置和方向開始,並且不會突然跳入動作。

  下一步,我們就要想想三角函數的概念。

  我們使用簡諧運動,其形式如下:

  Y是指當前值,A是振幅,f是頻率,t是運行時間,phi是指階段。首先,我們很容易確定振幅。它是我們希望對象所具有的最大化高度或旋轉。

  下一個就是運行時間和階段。我們將用(Time.time-initialtime)輕鬆取代t而一次性處搞定這兩者。這會將φ降為0,所以最後我們隻需要得到頻率。我強烈推薦令此頻率與你的音樂頻率吻合(如果你是自己作曲,這一點很容易辦到)。

  如果你還不知道自己音樂的BPM,那就去摸索每個節拍,直到弄懂為止。如果你已經有節奏感,這就很好辦了。如果你沒有,那也不用擔心,我們會利用中心極限定理。持續點觸你的整首歌,每欠點觸都會減少平均值中的錯誤。

  現在你就知道它每分鍾如何打節拍了。你將以60來劃分這個值,找到每秒多少拍。如果你隻想在半小節或一個完整的小節中使用一次動作,那就可以按2或4數值來劃分。這個數值就是頻率,你可以從 Mathf.PI獲得pi。所以現在你要將對象的位置設為該數值。此時你隻是在調整高度:

transform.position = new Vector3(transform.position.x,maxheight*
Mathf.Sin(2*Mathf.PI*frequency*(Time.time-initialtime)),transform.position.z);

  但這還不夠好。首先,我們要讓對象合拍,這樣它就得從其最大振幅開始。我們此時要使用餘弦。但更重要的是,要讓它從一端跳躍到另一端,這樣它就不會像波紋一樣滑上滑下。這時要用cos^2,這樣它才會突然停在0標記,並再次走向正數。因此:

transform.position = new Vector3(transform.position.x,maxheight*Mathf.Pow(Mathf.Cos(
2*Mathf.PI*frequency*(Time.time-initialtime)),2),transform.position.z)

  這裏要注意舞動的高度。最終旋轉要使用正弦,這樣其旋轉和轉化就是異相的。因此:

transform.rotation = Quaternion.EulerAngles(0, maxRotation*
Mathf.Cos(2*Mathf.PI*frequency*Mathf.Sin(Time.time-initialtime)), 0);

  這裏要記住兩件事:如果你使用一個位麵,並希望它麵對攝像機,這些值就不能是0和0,而必須是pi/2和–pi/2。這裏我使用的是EulerAngles而不是Euler,因為Euler使用的是度數,而EulerAngles使用的是弧度。我們要做一些數學運算,我們現在要運用弧度,所以得使用EulerAngles!否則你之扣就得輸入一個換算因數。

  在此你可以看到我新遊戲的一種類似動畫,你可以用同種方法更改比例而不是位置。

RoStlogo

  現在我們要討論最後一種動畫類型:

  紋理補償

  你可以用自己所學到的一切來操作2D紋理補償,以製作美妙的動畫背景。你可以在《Rude Bear Radio》及其主界麵中看到我對《VVVVVV》的拙劣模仿。抓取一個位麵,在其上粘附一個重複紋理,編寫一個FixedUpdate() 函數,並根據下屬性進行調整:

renderer.material.mainTextureOffset
renderer.material.color

  這將導致牆體四處滑動並改變顏色。最後,如果你想讓它們看起來更有趣,還可以運用renderer.material.mainTextureScale。這可以製作一個真正有趣的視覺效果,但它很有幹擾性,不要讓它影響你的主要遊戲玩法。
华体会hth体育网 賞析
  • 2101期學員李思庭作品

    2101期學員李思庭作品

  • 2104期學員林雪茹作品

    2104期學員林雪茹作品

  • 2107期學員趙淩作品

    2107期學員趙淩作品

  • 2107期學員趙燃作品

    2107期學員趙燃作品

  • 2106期學員徐正浩作品

    2106期學員徐正浩作品

  • 2106期學員弓莉作品

    2106期學員弓莉作品

  • 2105期學員白羽新作品

    2105期學員白羽新作品

  • 2107期學員王佳蕊作品

    2107期學員王佳蕊作品

專業問題谘詢

你擔心的問題,火星幫你解答

微信掃碼入群領福利

掃碼領福利最新AI資訊

點擊谘詢
添加老師微信,馬上領取免費課程資源

1. 打開微信掃一掃,掃描左側二維碼

2. 添加老師微信,馬上領取免費課程資源

×

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯係,請保持電話暢通!
確定