Files
5.24BuYu/Assets/MyGame/Scripts/Turret/TurretData.cs
T
2026-06-15 18:37:06 +08:00

368 lines
11 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 Spine.Unity;
using System.Collections.Generic;
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("UI面板属性")]
[Tooltip("炮台编号,对应 TurretResourcesData.turretNumber")]
public int turretNumber;
[Tooltip("1=普通炮台 2=战神 3=翅膀")]
public int turretType = 1;
[Tooltip("UI 展示名称")]
public string displayName;
[Tooltip("品质 1=普通 2=稀有 3=史诗 4=传说")]
[Range(1, 5)]
public int quality = 1;
[Tooltip("解锁所需等级(0=默认拥有)")]
public int unlockLevel;
[Tooltip("UI 列表/详情用的缩略图")]
public Sprite uiIconSprite;
[TextArea(2, 4)]
[Tooltip("描述文字")]
public string description;
// ---- 运行时状态(由服务器/UI面板读写) ----
[System.NonSerialized] public bool isUnlocked;
[System.NonSerialized] public bool isEquipped;
[System.NonSerialized] public int ownStarLevel;
[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;
/// <summary>
/// 从资源表查询 TurretResourcesData。表里没有则返回 null,调用方应使用 TurretData 自身的 Inspector 默认值。
/// </summary>
public TurretResourcesData GetResourcesData()
{
return TurretResourcesData.GetTurretData(turretNumber);
}
/// <summary>安全获取攻击音效 ID:表里有就用,没有则返回 0(静音)。</summary>
public int GetAttackAudioID()
{
var res = GetResourcesData();
return res != null ? res.attackAudioID : 0;
}
/// <summary>安全获取子弹 ID 列表:表里有就用,没有则返回空列表。</summary>
public List<int> GetBulletIDs()
{
var res = GetResourcesData();
return res?.bulletID ?? new List<int>();
}
/// <summary>安全获取动画类型:表里有就用,没有则用 Inspector 配置的 currTurretType。</summary>
public TurretAnimType GetAnimationType()
{
var res = GetResourcesData();
return res != null ? (TurretAnimType)res.animationType : currTurretType;
}
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 Vector2 GetBulletStartWorldPos()
{
if (tra_BulletStartPosition == null)
return Vector2.zero;
// 如果是 UI(UGUI)
RectTransform rect = tra_BulletStartPosition.GetComponent<RectTransform>();
if (rect != null)
{
Canvas canvas = UIManager.Instance.uiRoot.GetComponent<Canvas>();
Camera cam = Camera.main;
// 方式1:通过屏幕坐标直接转世界坐标(推荐)
Vector3 screenPos = RectTransformUtility.WorldToScreenPoint(
canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera,
rect.position
);
// 需要计算 Z 轴距离(物体到相机的距离),这里假设子弹打在 Z=0 平面
float distance = Mathf.Abs(cam.transform.position.z - 0f);
Vector3 worldPos = cam.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, distance));
worldPos.z = 0f;
return worldPos;
}
// 非 UI(3D 物体)
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);
// }
//}
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
};
// 如果动画名为空 → 停止当前动画(暂停),不再播放任何动画
if (string.IsNullOrEmpty(anim))
{
skeletonAnimation.AnimationState.ClearTrack(0);
skeletonAnimation.AnimationState.SetEmptyAnimation(0, 0f);
return;
}
bool loop = state == TurretState.Attack || state == TurretState.LaserLoop;
skeletonAnimation.AnimationState.SetAnimation(0, anim, loop);
if (state == TurretState.LaserStart && !string.IsNullOrEmpty(laserLoopAnim))
{
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
};
if (string.IsNullOrEmpty(anim))
{
old_CurrAnimation.Stop();
return;
}
old_CurrAnimation.Play(anim);
}
private void PlayAnimator(TurretState state)
{
if (new_CurrAnimation == null) return;
// 如果缺少对应动画,暂停 animator(速度为0)或者设置一个空状态
if (state == TurretState.Attack && isFrenzy && useFrenzyAnim && !string.IsNullOrEmpty(frenzyAttackAnim))
{
new_CurrAnimation.SetTrigger("FrenzyAttack");
}
else if (!string.IsNullOrEmpty(attackAnim) || state == TurretState.Idle && !string.IsNullOrEmpty(idleAnim))
{
new_CurrAnimation.SetInteger("State", (int)state);
}
else
{
// 没有可用动画时暂停 animator,避免残留动作
new_CurrAnimation.speed = 0f;
}
}
}