c1_unity/Assets/Scripts/Component/Helper/CharacterSpineHelper.cs

280 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BF
{
[System.Serializable]
public struct CharacterSpineObjectInfo
{
public uint hashName;
public UnityEngine.GameObject gameObject;
}
[ExecuteInEditMode]
[DisallowMultipleComponent]
public class CharacterSpineHelper : MonoBehaviour
{
public GameObject SpineObject;
public List<CharacterSpineObjectInfo> ObjectList = new List<CharacterSpineObjectInfo>();
public float PositionX { get; private set; }
public float PositionY { get; private set; }
public float PositionZ { get; private set; }
private Spine.Unity.SkeletonGraphic skeletonGraphic;
private Spine.AnimationState animationState;
void Awake()
{
skeletonGraphic = SpineObject.GetComponent<Spine.Unity.SkeletonGraphic>();
animationState = skeletonGraphic.AnimationState;
}
public void Reload()
{
animationState = skeletonGraphic.AnimationState;
}
public void PlayAnimation(string animName, bool loop, bool forceRefresh)
{
#if UNITY_EDITOR
float duration = GetAnimationDuration(animName);
if(BFLog.LogAssert(duration > 0, this.gameObject.name + " not have " + animName))
{
return;
}
#endif
animationState.SetAnimation(0, animName, loop);
if (forceRefresh)
{
skeletonGraphic.Update(0);
}
}
public void SetAnimationSpeed(float timeScale)
{
skeletonGraphic.timeScale = timeScale;
}
public void SetLoop(bool isLoop)
{
skeletonGraphic.startingLoop = isLoop;
}
public GameObject GetSpineObject()
{
return SpineObject;
}
public Spine.Unity.SkeletonGraphic GetSkeletonGraphic()
{
return skeletonGraphic;
}
public int GetListCount()
{
return ObjectList.Count;
}
public GameObject GetGameObjectByIndex(int index)
{
if (index >= 0 && index < ObjectList.Count)
{
return ObjectList[index].gameObject;
}
else if (index < 0)
{
return this.gameObject;
}
return null;
}
public uint GetHashNameByIndex(int index)
{
if (index >= 0 && index < ObjectList.Count)
{
return ObjectList[index].hashName;
}
return 0;
}
public int GetInstanceID(int index)
{
if (index >= 0 && index < ObjectList.Count)
{
return ObjectList[index].gameObject.GetInstanceID();
}
return gameObject.GetInstanceID();
}
// Lua层可以使用PositionXPositionYPositionZ减少直接传递localPosition的开销
public void CacheLocalPosition(int index)
{
if (index >= 0 && index < ObjectList.Count)
{
var localPosition = ObjectList[index].gameObject.transform.localPosition;
PositionX = localPosition.x;
PositionY = localPosition.y;
PositionZ = localPosition.z;
}
else if (index < 0)
{
PositionX = this.transform.localPosition.x;
PositionY = this.transform.localPosition.y;
PositionZ = this.transform.localPosition.z;
}
}
public void SetLocalPosition(int index, float x, float y, float z)
{
if (index >= 0 && index < ObjectList.Count)
{
ObjectList[index].gameObject.transform.localPosition = new Vector3(x, y, z);
}
else if (index < 0)
{
this.transform.localPosition = new Vector3(x, y, z);
}
}
// Lua层可以使用PositionXPositionYPositionZ减少直接传递position的开销
public void CachePosition(int index)
{
if (index >= 0 && index < ObjectList.Count)
{
var position = ObjectList[index].gameObject.transform.position;
PositionX = position.x;
PositionY = position.y;
PositionZ = position.z;
}
else if (index < 0)
{
PositionX = this.transform.position.x;
PositionY = this.transform.position.y;
PositionZ = this.transform.position.z;
}
}
public void CacheBonePosition(string name)
{
var skeleton = skeletonGraphic.Skeleton;
var bone = skeleton.FindBone(name);
if (bone != null)
{
Vector3 unityWorldPosition = skeletonGraphic.transform.TransformPoint(new Vector3(bone.WorldX, bone.WorldY, 0.0f));
PositionX = unityWorldPosition.x;
PositionY = unityWorldPosition.y;
PositionZ = unityWorldPosition.z;
}
else
{
PositionX = 0.0f;
PositionY = 0.0f;
PositionZ = 0.0f;
}
}
public void SetPosition(int index, float x, float y, float z)
{
if (index >= 0 && index < ObjectList.Count)
{
ObjectList[index].gameObject.transform.position = new Vector3(x, y, z);
}
else if (index < 0)
{
this.transform.position = new Vector3(x, y, z);
}
}
public void SetLocalEulerAngles(int index, float x, float y, float z)
{
if (index >= 0 && index < ObjectList.Count)
{
ObjectList[index].gameObject.transform.localEulerAngles = new Vector3(x, y, z);
}
else if (index < 0)
{
this.transform.localEulerAngles = new Vector3(x, y, z);
}
}
public void setEulerAngles(int index, float x, float y, float z)
{
if (index >= 0 && index < ObjectList.Count)
{
ObjectList[index].gameObject.transform.eulerAngles = new Vector3(x, y, z);
}
else if (index < 0)
{
this.transform.eulerAngles = new Vector3(x, y, z);
}
}
public void SetLocalScale(int index, float x, float y, float z)
{
if (index >= 0 && index < ObjectList.Count)
{
ObjectList[index].gameObject.transform.localScale = new Vector3(x, y, z);
}
else if (index < 0)
{
this.transform.localScale = new Vector3(x, y, z);
}
}
public void SetLocalScaleX(int index, float x)
{
if (index >= 0 && index < ObjectList.Count)
{
var transform = ObjectList[index].gameObject.transform;
transform.localScale = new Vector3(x, transform.localScale.y, transform.localScale.z);
}
else if (index < 0)
{
transform.localScale = new Vector3(x, transform.localScale.y, transform.localScale.z);
}
}
public void SetMainSpineLocalPosition(float x, float y, float z)
{
SpineObject.transform.localPosition = new Vector3(x, y, z);
}
public float GetAnimationDuration(string name)
{
Spine.Animation animation = skeletonGraphic.skeletonDataAsset.GetAnimationStateData().SkeletonData.FindAnimation(name);
if (animation == null){
return 0.0f;
}
return animation.Duration;
}
public float GetAnimationKeyFrameTime(string name)
{
float time = 0.0f;
var animation = skeletonGraphic.skeletonDataAsset.GetAnimationStateData().SkeletonData.FindAnimation(name);
foreach (var timeline in animation.Timelines)
{
var eventTimeline = timeline as Spine.EventTimeline;
if (eventTimeline != null && eventTimeline.Events.Length > 0)
{
time = eventTimeline.Events[0].Time;
}
}
return time;
}
public void SetDefaultMix(float mixDuration)
{
skeletonGraphic.skeletonDataAsset.GetAnimationStateData().DefaultMix = mixDuration;
}
public void PlayAnimationAndPause(string animName, float percent)
{
skeletonGraphic.timeScale = 1;
animationState.SetAnimation(0, animName, false);
var duration = GetAnimationDuration(animName);
skeletonGraphic.Update(percent * duration);
skeletonGraphic.timeScale = 0;
}
}
}