2026-02-09 10:44:38 +08:00
|
|
|
|
using Spine.Unity;
|
|
|
|
|
|
using UnityEngine;
|
2026-05-02 23:52:48 +08:00
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
}
|
2026-02-09 10:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
public class TurretData : MonoBehaviour
|
|
|
|
|
|
{
|
2026-05-02 23:52:48 +08:00
|
|
|
|
[Header("基础")]
|
2026-02-09 10:44:38 +08:00
|
|
|
|
public string turretID;
|
|
|
|
|
|
public SitPosData setPosData;
|
2026-03-31 17:00:05 +08:00
|
|
|
|
public Transform tra_BulletStartPosition;
|
2026-05-04 17:21:52 +08:00
|
|
|
|
public GameObject bulletPrefab_Two;
|
|
|
|
|
|
public GameObject bulletPrefab;
|
2026-05-02 23:52:48 +08:00
|
|
|
|
|
|
|
|
|
|
[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 laserStartAnim;
|
|
|
|
|
|
public string laserLoopAnim;
|
|
|
|
|
|
public string laserEndAnim;
|
|
|
|
|
|
|
|
|
|
|
|
private TurretState currState;
|
|
|
|
|
|
|
|
|
|
|
|
private void Awake()
|
2026-02-09 10:44:38 +08:00
|
|
|
|
{
|
2026-05-02 23:52:48 +08:00
|
|
|
|
if (setPosData != null)
|
|
|
|
|
|
setPosData.OnStateChange = ChangeState;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
2026-02-09 10:44:38 +08:00
|
|
|
|
{
|
2026-05-02 23:52:48 +08:00
|
|
|
|
// 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 (skeletonAnimation != null)
|
|
|
|
|
|
skeletonAnimation.timeScale = isFrenzy ? 2f : 1f;
|
|
|
|
|
|
|
|
|
|
|
|
if (new_CurrAnimation != null)
|
|
|
|
|
|
new_CurrAnimation.speed = isFrenzy ? 2f : 1f;
|
|
|
|
|
|
|
|
|
|
|
|
if (old_CurrAnimation != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (AnimationState state in old_CurrAnimation)
|
|
|
|
|
|
state.speed = isFrenzy ? 2f : 1f;
|
2026-02-09 10:44:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-02 23:52:48 +08:00
|
|
|
|
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 => 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);
|
|
|
|
|
|
|
|
|
|
|
|
// 激光开始 → 自动进入 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 => 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;
|
|
|
|
|
|
|
|
|
|
|
|
new_CurrAnimation.SetInteger("State", (int)state);
|
|
|
|
|
|
}
|
2026-02-09 10:44:38 +08:00
|
|
|
|
}
|