This commit is contained in:
2026-09-05 23:22:30 +08:00
parent 69a699ef44
commit ee8f3cc12a
54 changed files with 268574 additions and 23 deletions
+122 -3
View File
@@ -137,8 +137,14 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
private readonly List<LineRenderer> _zhanShenLasers = new List<LineRenderer>();
/// <summary>预制体形态激光实例列表(世界空间,由 JiGuangControl.JiGuangCreate 按目标数量重建)</summary>
private readonly List<Transform> _laserFx = new List<Transform>();
/// <summary>激光起点特效实例(UI 层:0=挂 turretRotate 下 selfOffsetJGStart 处,1/2=挂 JGFX 左右父对象下,跟随父节点)</summary>
private readonly List<GameObject> _laserStartFx = new List<GameObject>();
/// <summary>激光命中特效实例(与 _laserFx 一一对应,世界空间 Z=-50 层,跟随锁定目标)</summary>
private readonly List<GameObject> _laserHitFx = new List<GameObject>();
/// <summary>预制体形态激光的基准缩放(重建时取自 laserPrefab.transform.localScale)</summary>
private Vector3 _laserFxBaseScale = Vector3.one;
/// <summary>预制体形态激光的角度偏移:激光预制体自带的 Z 轴旋转(重建时缓存,绕世界 Z 叠加在计算朝向上)</summary>
private float _laserFxRotZOffset;
/// <summary>每条激光的起点缓存(索引与 _laserTargets 对齐,每帧复用避免 GC)</summary>
private readonly List<Vector3> _laserStarts = new List<Vector3>();
@@ -459,6 +465,17 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
if (_laserFx[i] != null && _laserFx[i].gameObject.activeSelf)
_laserFx[i].gameObject.SetActive(false);
}
// 起点/命中特效一并隐藏
for (int i = 0; i < _laserStartFx.Count; i++)
{
if (_laserStartFx[i] != null && _laserStartFx[i].activeSelf)
_laserStartFx[i].SetActive(false);
}
for (int i = 0; i < _laserHitFx.Count; i++)
{
if (_laserHitFx[i] != null && _laserHitFx[i].activeSelf)
_laserHitFx[i].SetActive(false);
}
}
/// <summary>
@@ -475,11 +492,15 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
for (int i = 0; i < _laserTargets.Count; i++)
_laserStarts.Add(GetZhanShenLaserStart(i));
// 目标数量变化时全量重建(锁定建立/解除/三发目标增减时触发),并刷新基准缩放
// 目标数量变化时全量重建(锁定建立/解除/三发目标增减时触发),并刷新基准缩放 + 预制体初始旋转偏移
if (_laserFx.Count != _laserTargets.Count)
{
_laserFxBaseScale = zsData.laserPrefab.transform.localScale;
// ⭐ 预制体自带的 Z 轴旋转:在激光预制体上转 Z = 激光平面内旋转(X/Y 不参与,防止甩出平面)
_laserFxRotZOffset = zsData.laserPrefab.transform.localEulerAngles.z;
JiGuangControl.JiGuangCreate(zsData.laserPrefab, _laserStarts, _laserTargets, _laserFx, null, -50f);
// ⭐ 起点/命中特效随激光全量重建(ZhanShenTurretData 上没拖预制体则不生成)
RebuildZhanShenLaserPointFx();
}
// 起点需每帧同步(座位布局/起点球位置变化);隐藏中的重新激活
@@ -492,9 +513,29 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
_laserFx[i].position = _laserStarts[i];
}
// 朝向 + 长度(多起点重载:起终点同层 Z=-50)
JiGuangControl.JiGuangDirection(_laserStarts, _laserTargets, _laserFx, -50f);
// 朝向 + 长度(多起点重载:起终点同层 Z=-50;朝向绕世界 Z 叠加预制体 Z 轴旋转偏移)
JiGuangControl.JiGuangDirection(_laserStarts, _laserTargets, _laserFx, -50f, _laserFxRotZOffset);
JiGuangControl.JiGuangLength(_laserStarts, _laserTargets, _laserFx, _laserFxBaseScale, zsData.laserLengthCorrect, -50f);
// ⭐ 起点特效挂 UI 起点节点下(位置由父节点决定自动跟随,无需刷),这里只负责重新激活;命中特效每帧跟随目标
for (int i = 0; i < _laserStartFx.Count; i++)
{
if (_laserStartFx[i] == null) continue;
if (!_laserStartFx[i].activeSelf)
_laserStartFx[i].SetActive(true);
}
for (int i = 0; i < _laserHitFx.Count; i++)
{
if (_laserHitFx[i] == null) continue;
if (!_laserHitFx[i].activeSelf)
_laserHitFx[i].SetActive(true);
if (i < _laserTargets.Count && _laserTargets[i] != null)
{
Vector3 hitPos = _laserTargets[i].position;
hitPos.z = -50f;
_laserHitFx[i].transform.position = hitPos;
}
}
}
/// <summary>LineRenderer 兜底形态(laserPrefab 为空):按需创建、多余的隐藏。每条激光独立起点</summary>
@@ -569,6 +610,84 @@ public class SitPosData : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
Destroy(_laserFx[i].gameObject);
}
_laserFx.Clear();
// 起点/命中特效一并销毁
ClearZhanShenLaserPointFx();
}
// ==================== 激光起点/命中特效(三发+锁定) ====================
/// <summary>
/// 激光全量重建时同步重建起点/命中特效(数量与激光一一对应)。
/// 起点=UI 层挂起点节点下(0=turretRotate 的 selfOffsetJGStart 处,1/2=JGFX 左右父对象);命中=世界层 Z=-50 跟随锁定目标。
/// ZhanShenTurretData 上对应预制体没拖(为空)时不生成。
/// </summary>
private void RebuildZhanShenLaserPointFx()
{
ClearZhanShenLaserPointFx();
var zsDataEx = currentZhanShenData as ZhanShenTurretData;
if (zsDataEx == null) return;
if (zsDataEx.JGStartFXPrefab == null && zsDataEx.JGHitFXPrefab == null) return;
for (int i = 0; i < _laserTargets.Count; i++)
{
if (_laserTargets[i] == null) continue;
// ⭐ 起点特效(UI 层):挂到该条激光的起点节点下,位置由父节点决定(自动跟随,无需每帧刷)
// 0=主激光 turretRotate 下 selfOffsetJGStart 处(子对象语义,跟随炮台旋转);1/2=JGFX 左右父对象下
if (zsDataEx.JGStartFXPrefab != null)
{
Transform startParent = null;
Vector3 startLocal = Vector3.zero;
if (i == 0 && turretRotate != null)
{
startParent = turretRotate;
startLocal = new Vector3(zsDataEx.selfOffsetJGStart.x, zsDataEx.selfOffsetJGStart.y, 0f);
}
else if (i == 1 && JGFXLeftParent != null)
{
startParent = JGFXLeftParent;
}
else if (i == 2 && JGFXRightParent != null)
{
startParent = JGFXRightParent;
}
if (startParent != null)
{
GameObject startGo = Instantiate(zsDataEx.JGStartFXPrefab, startParent, false);
startGo.transform.localPosition = startLocal;
_laserStartFx.Add(startGo);
}
}
// 命中特效:克隆到该条激光的终点(锁定目标身上,Z 压 -50 与激光同层)
if (zsDataEx.JGHitFXPrefab != null)
{
Vector3 hitPos = _laserTargets[i].position;
hitPos.z = -50f;
_laserHitFx.Add(Instantiate(zsDataEx.JGHitFXPrefab, hitPos, Quaternion.identity));
}
}
}
/// <summary>销毁全部起点/命中特效实例(激光重建/销毁时调用)</summary>
private void ClearZhanShenLaserPointFx()
{
for (int i = 0; i < _laserStartFx.Count; i++)
{
if (_laserStartFx[i] != null)
Destroy(_laserStartFx[i]);
}
_laserStartFx.Clear();
for (int i = 0; i < _laserHitFx.Count; i++)
{
if (_laserHitFx[i] != null)
Destroy(_laserHitFx[i]);
}
_laserHitFx.Clear();
}
// ==================== 战神激光起点(每条激光独立起点) ====================