217 lines
5.6 KiB
C#
217 lines
5.6 KiB
C#
using Spine.Unity;
|
||
using UnityEngine;
|
||
|
||
public enum TurretAnimType
|
||
{
|
||
None = 0,
|
||
skeletonAnimation = 1,
|
||
animation = 2,
|
||
animator = 3
|
||
}
|
||
|
||
|
||
public enum TurretState
|
||
{
|
||
None = 0,
|
||
Idle = 1,
|
||
Attack = 2,
|
||
|
||
LaserStart = 3,
|
||
LaserLoop = 4,
|
||
LaserEnd = 5
|
||
}
|
||
|
||
|
||
public class TurretData : MonoBehaviour
|
||
{
|
||
[Header("基础")]
|
||
public string turretID;
|
||
public SitPosData setPosData;
|
||
public Transform tra_BulletStartPosition;
|
||
public GameObject bulletPrefab_Two;
|
||
public GameObject bulletPrefab;
|
||
|
||
[Header("动画组件")]
|
||
public SkeletonGraphic skeletonAnimation;
|
||
public Animation old_CurrAnimation;
|
||
public Animator new_CurrAnimation;
|
||
public TurretAnimType currTurretType;
|
||
public bool isFrenzy=false;
|
||
[Header("动画名")]
|
||
public string idleAnim;
|
||
public string attackAnim;
|
||
// 新增:狂暴专用攻击动画(已经是二倍速帧动画)
|
||
public string frenzyAttackAnim;
|
||
private bool useFrenzyAnim = false;
|
||
|
||
|
||
public string laserStartAnim;
|
||
public string laserLoopAnim;
|
||
public string laserEndAnim;
|
||
|
||
private TurretState currState;
|
||
|
||
private void Awake()
|
||
{
|
||
if (setPosData != null)
|
||
setPosData.OnStateChange = ChangeState;
|
||
|
||
// 自动判断:如果狂暴攻击动画名不为空,就启用切换动画模式
|
||
useFrenzyAnim = !string.IsNullOrEmpty(frenzyAttackAnim);
|
||
}
|
||
|
||
private void OnEnable()
|
||
{
|
||
PlayState(TurretState.Idle);
|
||
}
|
||
public Vector2 GetBulletStartWorldPos()
|
||
{
|
||
if (tra_BulletStartPosition == null)
|
||
return Vector2.zero;
|
||
|
||
// 如果是 UI RectTransform(UGUI)
|
||
RectTransform rect = tra_BulletStartPosition.GetComponent<RectTransform>();
|
||
if (rect != null)
|
||
{
|
||
// 1. UI 本地坐标 → Canvas 坐标
|
||
Vector2 canvasPos = CoordinateTransformation.AnchoredPos_ToCanvas(
|
||
rect,
|
||
UIManager.Instance.uiRoot.GetComponent<Canvas>()
|
||
);
|
||
|
||
// 2. Canvas 坐标 → 世界坐标
|
||
return CoordinateTransformation.CanvasToWorld(
|
||
canvasPos,
|
||
UIManager.Instance.uiRoot.GetComponent<RectTransform>(),
|
||
Camera.main
|
||
);
|
||
}
|
||
|
||
// 如果不是 UI(比如 3D Transform)
|
||
return tra_BulletStartPosition.position;
|
||
}
|
||
|
||
public void SetFrenzy(bool value)
|
||
{
|
||
isFrenzy = value;
|
||
|
||
if (!useFrenzyAnim) // 没有狂暴动画 → 用速度加倍
|
||
{
|
||
float speed = isFrenzy ? 2f : 1f;
|
||
|
||
if (skeletonAnimation != null)
|
||
skeletonAnimation.timeScale = speed;
|
||
|
||
if (new_CurrAnimation != null)
|
||
new_CurrAnimation.speed = speed;
|
||
|
||
if (old_CurrAnimation != null)
|
||
{
|
||
foreach (AnimationState state in old_CurrAnimation)
|
||
state.speed = speed;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 有狂暴动画 → 不做速度调整,保持 1 倍速
|
||
if (skeletonAnimation != null)
|
||
skeletonAnimation.timeScale = 1f;
|
||
|
||
if (new_CurrAnimation != null)
|
||
new_CurrAnimation.speed = 1f;
|
||
|
||
if (old_CurrAnimation != null)
|
||
{
|
||
foreach (AnimationState state in old_CurrAnimation)
|
||
state.speed = 1f;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
public void ChangeState(TurretState newState)
|
||
{
|
||
if (currState == newState) return;
|
||
|
||
currState = newState;
|
||
PlayState(newState);
|
||
}
|
||
|
||
private void PlayState(TurretState state)
|
||
{
|
||
switch (currTurretType)
|
||
{
|
||
case TurretAnimType.skeletonAnimation:
|
||
PlaySkeleton(state);
|
||
break;
|
||
|
||
case TurretAnimType.animation:
|
||
PlayLegacy(state);
|
||
break;
|
||
|
||
case TurretAnimType.animator:
|
||
PlayAnimator(state);
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void PlaySkeleton(TurretState state)
|
||
{
|
||
if (skeletonAnimation == null) return;
|
||
|
||
string anim = state switch
|
||
{
|
||
TurretState.Idle => idleAnim,
|
||
TurretState.Attack => (isFrenzy && useFrenzyAnim) ? frenzyAttackAnim : attackAnim,
|
||
TurretState.LaserStart => laserStartAnim,
|
||
TurretState.LaserLoop => laserLoopAnim,
|
||
TurretState.LaserEnd => laserEndAnim,
|
||
_ => idleAnim
|
||
};
|
||
|
||
bool loop = state == TurretState.Attack || state == TurretState.LaserLoop;
|
||
skeletonAnimation.AnimationState.SetAnimation(0, anim, loop);
|
||
|
||
if (state == TurretState.LaserStart)
|
||
{
|
||
skeletonAnimation.AnimationState.AddAnimation(0, laserLoopAnim, true, 0f);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
private void PlayLegacy(TurretState state)
|
||
{
|
||
if (old_CurrAnimation == null) return;
|
||
|
||
string anim = state switch
|
||
{
|
||
TurretState.Idle => idleAnim,
|
||
TurretState.Attack => (isFrenzy && useFrenzyAnim) ? frenzyAttackAnim : attackAnim,
|
||
TurretState.LaserStart => laserStartAnim,
|
||
TurretState.LaserLoop => laserLoopAnim,
|
||
TurretState.LaserEnd => laserEndAnim,
|
||
_ => idleAnim
|
||
};
|
||
|
||
old_CurrAnimation.Play(anim);
|
||
}
|
||
|
||
|
||
private void PlayAnimator(TurretState state)
|
||
{
|
||
if (new_CurrAnimation == null) return;
|
||
|
||
if (state == TurretState.Attack && isFrenzy && useFrenzyAnim)
|
||
{
|
||
new_CurrAnimation.SetTrigger("FrenzyAttack");
|
||
}
|
||
else
|
||
{
|
||
new_CurrAnimation.SetInteger("State", (int)state);
|
||
}
|
||
}
|
||
|
||
}
|