|
using System;
|
using Spine.Unity;
|
using UnityEngine;
|
using UnityEngine.UI;
|
|
public class HorseController : MonoBehaviour
|
{
|
private GameObjectPoolManager.GameObjectPool pool;
|
private int skinID;
|
protected SkeletonGraphic skeletonGraphic;
|
|
protected Spine.AnimationState spineAnimationState;
|
private GameObject instanceGO;
|
|
protected UIHeroController hero;
|
|
private Action onComplete;
|
|
private bool isHeroShowBefore = false;
|
|
public void Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
|
{
|
if (skinID == _skinID)
|
{
|
CreateHero(_heroSkinID);
|
//避免重复创建
|
return;
|
}
|
|
skinID = _skinID;
|
var skinConfig = HorseSkinConfig.Get(skinID);
|
|
this.transform.localScale = Vector3.one * scale;
|
|
onComplete = _onComplete;
|
pool = GameObjectPoolManager.Instance.RequestPool(UILoader.LoadPrefab("UIHorse"));
|
|
if (!transform.gameObject.activeSelf)
|
{
|
transform.SetActive(true);
|
}
|
if (instanceGO == null)
|
{
|
instanceGO = pool.Request();
|
instanceGO.transform.SetParent(transform);
|
//transform 的Pivot Y是0,让instanceGO 居中
|
instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
|
|
//instanceGO.transform.localPosition = Vector3.zero;
|
instanceGO.transform.localScale = Vector3.one;
|
instanceGO.transform.localRotation = Quaternion.identity;
|
}
|
|
skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
|
|
skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
|
if (skeletonGraphic.skeletonDataAsset == null)
|
{
|
|
transform.SetActive(false);
|
if (pool != null)
|
pool.Release(instanceGO);
|
skeletonGraphic = null;
|
Destroy(instanceGO);
|
Debug.LogError("未配置spine");
|
return;
|
}
|
skeletonGraphic.Initialize(true);
|
|
skeletonGraphic.transform.localPosition = new Vector3(skinConfig.Poses[0], skinConfig.Poses[1], 0);
|
isHeroShowBefore = skinConfig.heroFirst == 1;
|
spineAnimationState = skeletonGraphic.AnimationState;
|
spineAnimationState.Data.DefaultMix = 0f;
|
if (motionName == "")
|
motionName = GetFistSpineAnim();
|
PlayAnimation(motionName, true);
|
CreateHero(_heroSkinID);
|
spineAnimationState.Complete -= OnAnimationComplete;
|
spineAnimationState.Complete += OnAnimationComplete;
|
}
|
|
public void CreateHero(int heroSkinID)
|
{
|
if (instanceGO == null)
|
{
|
return;
|
}
|
hero = instanceGO.GetComponentInChildren<UIHeroController>(true);
|
if (hero == null)
|
{
|
return;
|
}
|
if (heroSkinID == 0)
|
{
|
hero.SetActive(false);
|
return;
|
}
|
hero.SetActive(true);
|
hero.Create(heroSkinID);
|
//约定骑乘点骨骼名
|
hero.GetComponent<BoneFollowerGraphic>().boneName = "mountPoint";
|
if (isHeroShowBefore)
|
{
|
hero.transform.SetAsLastSibling();
|
}
|
else
|
{
|
hero.transform.SetAsFirstSibling();
|
}
|
}
|
|
public void HeroPlay(string motionName, bool loop = false, bool replay=true)
|
{
|
hero.PlayAnimation(motionName, loop, replay);
|
}
|
|
|
protected void OnDestroy()
|
{
|
if (spineAnimationState != null)
|
{
|
spineAnimationState.Complete -= OnAnimationComplete;
|
}
|
if (pool != null)
|
pool.Release(instanceGO);
|
skeletonGraphic = null;
|
pool = null;
|
}
|
|
/// <summary>
|
/// 播放 Spine 动画
|
/// </summary>
|
/// <param name="motionName">动作名</param>
|
/// <param name="loop">循环</param>
|
/// <param name="replay">如果相同动作是否再次重播,比如跑步重播就会跳帧不顺滑</param>
|
public virtual void PlayAnimation(string motionName, bool loop = false, bool replay=true)
|
{
|
if (spineAnimationState == null) return;
|
|
if (GetCurrentAnimationName() == motionName && !replay)
|
return;
|
|
// 直接使用 ToString() 而不是调用 GetAnimationName
|
spineAnimationState.SetAnimation(0, motionName.ToString(), loop);
|
}
|
|
// 播放第一个动画(作为默认动画)
|
string GetFistSpineAnim()
|
{
|
var skeletonData = skeletonGraphic.Skeleton.Data;
|
if (skeletonData.Animations.Count > 0)
|
{
|
return skeletonData.Animations.Items[0].Name;
|
}
|
else
|
{
|
Debug.LogError("Spine 数据中没有找到任何动画!武将皮肤:" + skinID);
|
}
|
return "";
|
}
|
|
/// <summary>
|
/// 获取当前正在播放的 Spine 动画名称
|
/// </summary>
|
/// <returns>当前动画名称,如果没有动画则返回空字符串</returns>
|
public string GetCurrentAnimationName()
|
{
|
if (spineAnimationState == null || spineAnimationState.GetCurrent(0) == null)
|
{
|
return string.Empty;
|
}
|
return spineAnimationState.GetCurrent(0).Animation.Name;
|
}
|
|
|
|
/// <summary>
|
/// 动画完成事件处理
|
/// </summary>
|
protected virtual void OnAnimationComplete(Spine.TrackEntry trackEntry)
|
{
|
onComplete?.Invoke();
|
}
|
|
//越大越快
|
public void SetSpeed(float speed)
|
{
|
spineAnimationState.TimeScale = speed;
|
}
|
|
public void SetEnabled(bool isEnable)
|
{
|
if (skeletonGraphic == null)
|
{
|
return;
|
}
|
skeletonGraphic.enabled = isEnable;
|
}
|
}
|