說是寫個指南,其實是想吐槽。。。
官方運行庫文檔真的辣雞的不行,它的說明文檔看着寫的挺全的,結果都是過時的了,裏面提的api大部分根本就找不到!
官方文檔:http://zh.esotericsoftware.com/spine-unity
但是我們又不得不用不是,所以就要自己翻它代碼,找真正能調用的api了,這裏推薦還是看一看它的官方文檔,可以至少讓我們對它的架構思路有一定的理解,方便快速分析它的真.api
都是用來幹什麼的~
以下以一個單通道的動畫控制腳本來說一下。(這裏要提個醒,spine它裏面有個多通道的功能,可以讓動畫只作用於網格的某一部分上,比如我們有一個跑步的動畫,依靠通道,我們可以實現在跑步的同時,讓人能夠揮手,或者扭頭,用高級別的通道去覆蓋低級別上的動畫)
using UnityEngine;
using Spine.Unity;
using Spine;
/// <summary>
/// 單通道spine助手
/// </summary>
public class SingleTrackSpineHelper
{
public GameObject gameObject;
public Transform transform;
/// <summary>
/// 當前通道
/// </summary>
public int currentTrack = 0;
// 骨骼動畫對象
private SkeletonAnimation _skeletonAnimation;
// 通道實體
private TrackEntry _trackEntry;
/// <summary>
/// 構造
/// </summary>
public SingleTrackSpineHelper(GameObject gameObject)
{
this.gameObject = gameObject;
this.transform = this.gameObject.transform;
_skeletonAnimation = this.gameObject.GetComponent<SkeletonAnimation>();
}
/// <summary>
/// 停止
/// </summary>
public void Stop()
{
_skeletonAnimation.state.ClearTrack(currentTrack);
}
/// <summary>
/// 根據時間播放
/// </summary>
/// <param name="animationName">動畫名</param>
/// <param name="loop">true=循環,false=單次</param>
/// <param name="fromTime">開始時間(單位秒)</param>
/// <param name="toTime">結束時間(單位秒)</param>
public TrackEntry PlayByTime(string animationName, bool loop = false, float fromTime = -1, float toTime = -1)
{
this.Stop();
_trackEntry = _skeletonAnimation.state.SetAnimation(currentTrack, animationName, loop);
if (fromTime >= 0)
{
_trackEntry.TrackTime = fromTime;
}
if (toTime >= 0)
{
_trackEntry.TrackEnd = toTime;
}
return _trackEntry;
}
/// <summary>
/// 根據幀數播放
/// </summary>
/// <param name="animationName">動畫名</param>
/// <param name="loop">true=循環,false=單次</param>
/// <param name="fromFrame">開始幀</param>
/// <param name="toFrame">結束幀</param>
public TrackEntry PlayByFrame(string animationName, bool loop = false, int fromFrame = -1, int toFrame = -1)
{
float fromTime = -1;
if (fromFrame >= 0)
{
fromTime = (float)fromFrame / SpineConst.FRAME_UNIT;
}
float toTime = -1;
if (toFrame >= 0)
{
toTime = (float)toFrame / SpineConst.FRAME_UNIT;
}
return this.PlayByTime(animationName, loop, fromTime, toTime);
}
/// <summary>
///
/// </summary>
/// <param name="animationName"></param>
/// <param name="loop"></param>
/// <returns></returns>
public TrackEntry Play(string animationName, bool loop = false)
{
return this.PlayByTime(animationName, loop, -1, -1);
}
}
如果我們只是播簡單的動畫的話,封裝的這個小控制腳本就足夠了。
_skeletonAnimation.state
這個是我們獲取當前動畫和播放動畫的主要方法,文檔有說,就不累贅了。
當我們有需求中間打斷一個動畫,讓它重頭開始時,我們第一時間想到的肯定是這樣來:
_skeletonAnimation.state.SetAnimation(currentTrack, animationName, loop);
然鵝,並沒有卵用,單純的這樣調一下,你會發現動畫會從當前的地方往回拉,動畫完全不會重頭進行播放,這根本不是我們想要的結果。
正確的做法應該是先用
_skeletonAnimation.state.ClearTrack(currentTrack);
來停止當前正在運行的通道,然後再重新播放這個動畫,這時你就發現動畫是真的重頭開始了,而不是往回拉了。。。
而當我們只需要播放時間軸上某一段動畫的時候,也根本不是官方所說的方法,而是需要用
_trackEntry.TrackTime
和_trackEntry.TrackEnd
這2個方法,它們控制了當前通道下播放動畫的起止時間!
這些方法其實是我們在項目中經常會需要的方法,然鵝官方卻貼了一大堆根本沒用的api說明。。。
PS:
希望這文章對你有幫助,而不要被 spine 的官方文檔給蒙了。
話說官方真是心大呀,文檔寫成這樣真的沒問題嗎?