|
|
|
|
using Spine;
|
|
|
|
|
using Spine.Unity;
|
|
|
|
|
using Spine.Unity.AttachmentTools;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
public class Motion : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
public enum Type { Idle, Run, RunBack, Attack, AttackUp, AttackDown, AttackEnd, Die, Hit, Idle2, Get, Appear }
|
|
|
|
|
//public enum Emoji { Normal, Shoot }
|
|
|
|
|
|
|
|
|
|
[System.Serializable]
|
|
|
|
|
public class SpineControl
|
|
|
|
|
{
|
|
|
|
|
public Motion.Type type;
|
|
|
|
|
//public Motion.Emoji emoji;
|
|
|
|
|
|
|
|
|
|
[Space(10)]
|
|
|
|
|
[SpineAnimation]
|
|
|
|
|
public string name;
|
|
|
|
|
public int layer = 1;
|
|
|
|
|
public bool loop = false;
|
|
|
|
|
|
|
|
|
|
[Space]
|
|
|
|
|
public float timeScale = 1f;
|
|
|
|
|
[Space]
|
|
|
|
|
public bool useMixDuration = true;
|
|
|
|
|
public float mixDuration = 0.1f;
|
|
|
|
|
//public bool useChainToControl;
|
|
|
|
|
//public int chainToControl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SkeletonAnimation skeletonAnimation;
|
|
|
|
|
Spine.AnimationState spineState;
|
|
|
|
|
Skeleton skeleton;
|
|
|
|
|
[Space(10)]
|
|
|
|
|
public List<SpineControl> controls;
|
|
|
|
|
Dictionary<Type, SpineControl> dicControls = null;
|
|
|
|
|
List<SpineControl> idles = null;
|
|
|
|
|
void Start()
|
|
|
|
|
{
|
|
|
|
|
spineState = skeletonAnimation.state;
|
|
|
|
|
skeleton = skeletonAnimation.Skeleton;
|
|
|
|
|
|
|
|
|
|
if (dicControls == null)
|
|
|
|
|
{
|
|
|
|
|
dicControls = new Dictionary<Type, SpineControl>();
|
|
|
|
|
idles = new List<SpineControl>();
|
|
|
|
|
for (int i = 0; i < controls.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (controls[i].type == Type.Idle)
|
|
|
|
|
idles.Add(controls[i]);
|
|
|
|
|
else
|
|
|
|
|
dicControls.Add(controls[i].type, controls[i]);
|
|
|
|
|
}
|
|
|
|
|
values = new List<SpineControl>(dicControls.Values);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Play(Type.Idle);
|
|
|
|
|
}
|
|
|
|
|
void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
typeBefore = Motion.Type.AttackEnd;
|
|
|
|
|
}
|
|
|
|
|
void OnDisable()
|
|
|
|
|
{
|
|
|
|
|
Play(Type.Idle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Space(10)]
|
|
|
|
|
public bool isATK = false;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 공격 모션 중인지 확인합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool Check_ATK()
|
|
|
|
|
{
|
|
|
|
|
return typeBefore == Type.Attack;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 등장 모션 중인지 확인합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool Check_Appear()
|
|
|
|
|
{
|
|
|
|
|
return typeBefore == Type.Appear;
|
|
|
|
|
}
|
|
|
|
|
public Motion.Type typeBefore = Motion.Type.AttackEnd;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 죽는 모션 중인지 확인합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool Check_Die()
|
|
|
|
|
{
|
|
|
|
|
return typeBefore == Type.Die;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 스파인 애니메이션을 재생합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="type"></param>
|
|
|
|
|
/// <param name="FORCE">true = 강제 재생</param>
|
|
|
|
|
/// <param name="OnEnd">모션 종료시 호출</param>
|
|
|
|
|
/// <param name="OnEvent">모션 이벤트 발생시 호출</param>
|
|
|
|
|
/// <param name="RESET"></param>
|
|
|
|
|
public void Play(Motion.Type type, bool FORCE = false, System.Action OnEnd = null, System.Action<Spine.Event> OnEvent = null, bool RESET = false)
|
|
|
|
|
{
|
|
|
|
|
//if (Check_Die() && !FORCE)//원래 코드, 테스트 진행 후 이상 없으면 삭제
|
|
|
|
|
if (Check_Die())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (FORCE || typeBefore != type)
|
|
|
|
|
{
|
|
|
|
|
if (dicControls == null)
|
|
|
|
|
Start();
|
|
|
|
|
|
|
|
|
|
TrackEntry track = null;
|
|
|
|
|
SpineControl control = null;
|
|
|
|
|
|
|
|
|
|
if (type == Type.Idle)
|
|
|
|
|
control = idles[Random.Range(0, idles.Count)];
|
|
|
|
|
else
|
|
|
|
|
control = dicControls[type];
|
|
|
|
|
|
|
|
|
|
if (control == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case Motion.Type.Attack:
|
|
|
|
|
case Motion.Type.AttackUp:
|
|
|
|
|
case Motion.Type.AttackDown:
|
|
|
|
|
{
|
|
|
|
|
isATK = true;
|
|
|
|
|
|
|
|
|
|
typeBefore = type;
|
|
|
|
|
track = spineState.SetAnimation(control.layer, control.name, control.loop);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type.AttackEnd:
|
|
|
|
|
{
|
|
|
|
|
if (isATK)
|
|
|
|
|
{
|
|
|
|
|
isATK = false;
|
|
|
|
|
|
|
|
|
|
typeBefore = type;
|
|
|
|
|
track = spineState.SetEmptyAnimation(control.layer, 0.2f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Type.Hit:
|
|
|
|
|
{
|
|
|
|
|
typeBefore = type;
|
|
|
|
|
track = spineState.SetAnimation(control.layer, control.name, control.loop);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
typeBefore = type;
|
|
|
|
|
track = spineState.SetAnimation(control.layer, control.name, control.loop);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (track != null)
|
|
|
|
|
{
|
|
|
|
|
if (control != null)
|
|
|
|
|
{
|
|
|
|
|
track.MixDuration = control.useMixDuration ? control.mixDuration : 0;
|
|
|
|
|
track.TimeScale = control.timeScale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OnEnd != null)
|
|
|
|
|
{
|
|
|
|
|
track.Complete += delegate (TrackEntry entry)
|
|
|
|
|
{
|
|
|
|
|
OnEnd();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OnEvent != null)
|
|
|
|
|
{
|
|
|
|
|
track.Event += delegate (TrackEntry trackEntry, Spine.Event e)
|
|
|
|
|
{
|
|
|
|
|
OnEvent(e);
|
|
|
|
|
|
|
|
|
|
if (RESET)
|
|
|
|
|
track.ResetEvent();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public bool isSkill = false;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 애니메이션을 강제 재생 합니다.
|
|
|
|
|
/// 현재는 캐릭터가 스킬을 사용할때만 사용되는 중입니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="control"></param>
|
|
|
|
|
/// <param name="OnEnd"></param>
|
|
|
|
|
/// <param name="OnEvent"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool Play_Force(SpineControl control, System.Action OnEnd = null, System.Action<Spine.Event> OnEvent = null)
|
|
|
|
|
{
|
|
|
|
|
//if (Check_Die())
|
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
|
|
if (spineState == null)
|
|
|
|
|
Start();
|
|
|
|
|
|
|
|
|
|
TrackEntry track = spineState.SetAnimation(control.layer, control.name, control.loop);
|
|
|
|
|
|
|
|
|
|
if (track != null)
|
|
|
|
|
{
|
|
|
|
|
if (control != null)
|
|
|
|
|
{
|
|
|
|
|
track.MixDuration = control.useMixDuration ? control.mixDuration : 0;
|
|
|
|
|
track.TimeScale = control.timeScale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OnEnd != null)
|
|
|
|
|
{
|
|
|
|
|
track.Complete += delegate (TrackEntry entry)
|
|
|
|
|
{
|
|
|
|
|
OnEnd();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OnEvent != null)
|
|
|
|
|
{
|
|
|
|
|
track.Event += delegate (TrackEntry trackEntry, Spine.Event e)
|
|
|
|
|
{
|
|
|
|
|
OnEvent(e);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//public void Play_Force(string name, int layer, bool loop, System.Action OnEnd = null, System.Action<Spine.Event> OnEvent = null)
|
|
|
|
|
//{
|
|
|
|
|
// if (Check_Die())
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
// if (spineState == null)
|
|
|
|
|
// Start();
|
|
|
|
|
|
|
|
|
|
// TrackEntry track = spineState.SetAnimation(layer, name, loop);
|
|
|
|
|
|
|
|
|
|
// if (track != null)
|
|
|
|
|
// {
|
|
|
|
|
// if (OnEnd != null)
|
|
|
|
|
// {
|
|
|
|
|
// track.Complete += delegate (TrackEntry entry)
|
|
|
|
|
// {
|
|
|
|
|
// OnEnd();
|
|
|
|
|
// };
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (OnEvent != null)
|
|
|
|
|
// {
|
|
|
|
|
// track.Event += delegate (TrackEntry trackEntry, Spine.Event e)
|
|
|
|
|
// {
|
|
|
|
|
// OnEvent(e);
|
|
|
|
|
// };
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//표정 변경
|
|
|
|
|
//public List<SpineControl> controls_Emoji;
|
|
|
|
|
//Dictionary<Emoji, SpineControl> dicControls_Emoji = new Dictionary<Emoji, SpineControl>();
|
|
|
|
|
//public void Play_Emoji(Motion.Emoji type)
|
|
|
|
|
//{
|
|
|
|
|
// SpineControl control = dicControls_Emoji[type];
|
|
|
|
|
// spineState.SetAnimation(control.layer, control.name, control.loop);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//public void ClearLayer(int layer)
|
|
|
|
|
//{
|
|
|
|
|
// spineState.SetEmptyAnimation(layer, 0.2f);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
Vector3 scale = Vector3.one;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 캐릭터가 바라볼 방향을 설정합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="x"></param>
|
|
|
|
|
public void LookSet(float x)
|
|
|
|
|
{
|
|
|
|
|
scale.x = x == 0 ? 0 : (x < 0 ? -1 : 1);
|
|
|
|
|
skeletonAnimation.transform.localScale = scale;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 바라보고 있는 방향을 확인합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public Vector3 LookDir()
|
|
|
|
|
{
|
|
|
|
|
return scale.x < 0 ? Vector3.right : Vector3.left;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Space(10)]
|
|
|
|
|
public List<SpineControl> values;
|
|
|
|
|
[Space(10)]
|
|
|
|
|
//public float spdMovePer;
|
|
|
|
|
public float spdDevision = 2f;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 변경된 이동속도 값을 반영합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="spd"></param>
|
|
|
|
|
public void OnMoveSpeedChanged(float spd)
|
|
|
|
|
{
|
|
|
|
|
//spdMovePer = spd;
|
|
|
|
|
//spdMovePer = 1 + (spd - (int)spd) * spdDevision;
|
|
|
|
|
|
|
|
|
|
//values = new List<SpineControl>(dicControls.Values);
|
|
|
|
|
List<SpineControl> list = values.FindAll(a => $"{a.type}".Contains("Run"));
|
|
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
|
|
|
list[i].timeScale = timeScaleRun * spd;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 캐릭터의 모든 이동 애니메이션의 TimeSclae(재생 속도) 를 설정합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="value"></param>
|
|
|
|
|
public float timeScaleRun = 1;
|
|
|
|
|
public void RunMotionTimeScaleChanged(float value)
|
|
|
|
|
{
|
|
|
|
|
if (dicControls == null)
|
|
|
|
|
Start();
|
|
|
|
|
|
|
|
|
|
SpineControl control = values.Find(a => a.type == Type.Run);
|
|
|
|
|
control.timeScale = timeScaleRun = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public float spdAtkPer;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 변경된 공격속도 값을 반영합니다.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="spd"></param>
|
|
|
|
|
public void OnAttackSpeedChanged(float spd)
|
|
|
|
|
{
|
|
|
|
|
spdAtkPer = spd;
|
|
|
|
|
|
|
|
|
|
//values = new List<SpineControl>(dicControls.Values);
|
|
|
|
|
List<SpineControl> list = values.FindAll(a => $"{a.type}".Contains("Attack"));
|
|
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
|
|
|
list[i].timeScale = spdAtkPer;
|
|
|
|
|
}
|
|
|
|
|
}
|