You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
14 KiB
389 lines
14 KiB
using System.Collections.Generic;
|
|
|
|
using CoreGame;
|
|
using GAS.Runtime;
|
|
using UnityEngine;
|
|
using xFrame;
|
|
|
|
namespace CoreGame.Render
|
|
{
|
|
public struct TexiaoShowParam
|
|
{
|
|
public int effectId; // 静态配置
|
|
public int element;
|
|
public Vector2 offset;
|
|
public Quaternion rotation;
|
|
public Vector3 scale;
|
|
|
|
public override string ToString()
|
|
{
|
|
var tbRenderEffect = RenderEffectDescMgr.Instance.GetConfig(effectId);
|
|
return "effectId: " + effectId + " name: " + tbRenderEffect?.name;
|
|
}
|
|
}
|
|
|
|
public class TxShowProcessParam : ISptPool
|
|
{
|
|
public int effectId;
|
|
public Vector2 offset;
|
|
public Quaternion rotation;
|
|
public Vector3 scale;
|
|
public Vector2 ghostPos; // 若eid的实体已回收,使用此位置播放
|
|
public bool isAttach;
|
|
public bool useHitPos;
|
|
public ReuseGoData reuseGoData;
|
|
public int eid;
|
|
|
|
public void Awake(ref TexiaoShowParam param)
|
|
{
|
|
effectId = param.effectId;
|
|
offset = param.offset;
|
|
rotation = param.rotation;
|
|
scale = param.scale;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
effectId = 0;
|
|
offset = Vector2.zero;
|
|
rotation = Quaternion.identity;
|
|
scale = Vector3.one;
|
|
ghostPos = Vector2.zero;
|
|
isAttach = false;
|
|
useHitPos = false;
|
|
reuseGoData = null;
|
|
eid = 0;
|
|
}
|
|
}
|
|
|
|
[Combat]
|
|
public class EffectShowProxy : ProxyBase
|
|
{
|
|
private readonly Dictionary<int, TxShowProcessParam> effectListDict = new();
|
|
private readonly List<SpriteRenderer> m_CacheRenderers = new();
|
|
private readonly List<Material> m_CacheMaterials = new();
|
|
private int m_IsMatPushed = 0;
|
|
public float effectScale = 1.0f;
|
|
|
|
protected override void Initialize(GameObject obj, CombatEntity ent)
|
|
{
|
|
}
|
|
|
|
public void ShowCastEffect(int effectId, List<int> seqList = null)
|
|
{
|
|
TexiaoShowParam param = default;
|
|
param.effectId = effectId;
|
|
param.scale = Vector3.one;
|
|
param.rotation = Quaternion.identity;
|
|
param.offset = Vector2.zero;
|
|
GA_ShowCastEffect(ref param, null, seqList);
|
|
}
|
|
|
|
public void ShowCastEffect(ref TexiaoShowParam param, in GameplayCueParameters cueData,
|
|
List<int> seqList = null)
|
|
{
|
|
if (cueData.sourceGaSpec != null)
|
|
{
|
|
GA_ShowCastEffect(ref param, cueData.sourceGaSpec.ctx, seqList);
|
|
return;
|
|
}
|
|
|
|
GE_ShowCastEffect(ref param, cueData.sourceGeSpec, seqList);
|
|
}
|
|
|
|
public void GE_ShowCastEffect(ref TexiaoShowParam param, GameplayEffectSpec spec, List<int> seqList = null)
|
|
{
|
|
Vector2 targetDir = Vector2.right;
|
|
if (spec.Source != null && spec.Source.owner.IsValid())
|
|
{
|
|
targetDir = spec.Owner.owner.transformProxy.position - spec.Source.owner.transformProxy.position;
|
|
}
|
|
var isShowSelf = IsShowSelf(ref param, seqList, out var path, out var isAttach, targetDir);
|
|
if (isShowSelf == false)
|
|
{
|
|
XLog.LogWarning($"GESpec {spec.GameplayEffect.GameplayEffectName} -> {param}: 只能显示Owner特效");
|
|
return;
|
|
}
|
|
}
|
|
|
|
public void GA_ShowCastEffect(ref TexiaoShowParam param, GameAbilityContext ctx, List<int> seqList = null)
|
|
{
|
|
var targetDir = Vector2.zero;
|
|
if (ctx != null)
|
|
{
|
|
var tbRenderEffect = RenderEffectDescMgr.Instance.GetConfig(param.effectId);
|
|
if (tbRenderEffect.isLookAtTarget == VFXLookType.PointSelect && ctx.castPos.Count > 0)
|
|
{
|
|
targetDir = ctx.castPos[0].ToVector2() - ctx.ownerEnt.transformProxy.position;
|
|
}
|
|
else if (tbRenderEffect.isLookAtTarget == VFXLookType.CatchTarget && ctx.geCatchTargets.Count > 0)
|
|
{
|
|
for (int i = 0; i < ctx.geCatchTargets.Count; i++)
|
|
{
|
|
if (ctx.geCatchTargets[i].IsValid() && ctx.geCatchTargets[i].hasTransformProxy)
|
|
{
|
|
targetDir = ctx.geCatchTargets[i].transformProxy.position -
|
|
ctx.ownerEnt.transformProxy.position;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsShowSelf(ref param, seqList, out var path, out var isAttach, targetDir)) return;
|
|
|
|
if (ctx == null || ctx.geCatchTargets.Count == 0)
|
|
{
|
|
BattleLogger.LogInfo("ShowCastEffect: geCatchTargets is empty");
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < ctx.geCatchTargets.Count; i++)
|
|
{
|
|
var useHitData = false;
|
|
if (isAttach == false)
|
|
useHitData = NormalParma(ref param, ctx.geCatchTargets[i].creationIndex, ctx);
|
|
|
|
ShowSingleTargetEffect(ctx.geCatchTargets[i], path, useHitData, isAttach, ref param, seqList);
|
|
}
|
|
}
|
|
|
|
private bool IsShowSelf(ref TexiaoShowParam param, List<int> seqList, out string path, out bool isAttach,
|
|
Vector2 targetDir)
|
|
{
|
|
seqList?.Clear();
|
|
var tbRenderEffect = RenderEffectDescMgr.Instance.GetConfig(param.effectId);
|
|
if (tbRenderEffect == null)
|
|
{
|
|
BattleLogger.LogInfo($"ShowCastEffect: effectId {param.effectId} is not exist");
|
|
path = null;
|
|
isAttach = false;
|
|
return true;
|
|
}
|
|
|
|
if (tbRenderEffect.isScale != 0) // 需要乘上实体的缩放
|
|
param.scale *= effectScale;
|
|
|
|
path = tbRenderEffect.prefab;
|
|
if (param.element == (int)ElementType.Fire && !string.IsNullOrEmpty(tbRenderEffect.firePrefab))
|
|
path = tbRenderEffect.firePrefab;
|
|
else if (param.element == (int)ElementType.Toxic && !string.IsNullOrEmpty(tbRenderEffect.toxicPrefab))
|
|
path = tbRenderEffect.toxicPrefab;
|
|
else if (param.element == (int)ElementType.Thunder && !string.IsNullOrEmpty(tbRenderEffect.thunderPrefab))
|
|
path = tbRenderEffect.thunderPrefab;
|
|
|
|
isAttach = tbRenderEffect.effectSpawn == EffectSpawn.Target;
|
|
var isTargetSelf = tbRenderEffect.effectTarget == EffectTarget.Owner;
|
|
|
|
if (isTargetSelf)
|
|
{
|
|
if (tbRenderEffect.isLookAtTarget != VFXLookType.None &&
|
|
tbRenderEffect.isLookAtTarget != VFXLookType.Default)
|
|
{
|
|
var rotation = Quaternion.LookRotation(Vector3.forward, targetDir.normalized);
|
|
param.rotation = rotation;
|
|
}
|
|
|
|
ShowSingleTargetEffect(ent, path, false, isAttach, ref param, seqList);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool NormalParma(ref TexiaoShowParam param, int targetEid, GameAbilityContext ctx)
|
|
{
|
|
if (ctx == null)
|
|
return false;
|
|
|
|
if (ctx.hitDatas.TryGetValue(targetEid, out var hitData))
|
|
{
|
|
param.offset = hitData.hitPos;
|
|
param.rotation = Quaternion.LookRotation(Vector3.forward, hitData.hitDir);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void ShowSingleTargetEffect(CombatEntity entity, string path, bool useHitData, bool isAttach,
|
|
ref TexiaoShowParam param, List<int> seqList = null)
|
|
{
|
|
if (entity == null || entity.isEnabled == false)
|
|
{
|
|
BattleLogger.LogInfo($"{entity} is null or not enabled");
|
|
return;
|
|
}
|
|
var txShowProcessParam = SptPool<TxShowProcessParam>.Malloc();
|
|
txShowProcessParam.Awake(ref param);
|
|
txShowProcessParam.isAttach = isAttach;
|
|
txShowProcessParam.eid = entity.creationIndex;
|
|
txShowProcessParam.useHitPos = useHitData;
|
|
txShowProcessParam.ghostPos = entity.transformProxy.position;
|
|
var pool = GoPoolDic.GetPool(path);
|
|
var reuseGoData = pool.GetNewGo(ShowSingleTargetEffect, txShowProcessParam);
|
|
txShowProcessParam.reuseGoData = reuseGoData;
|
|
var seq = reuseGoData.GetSeq();
|
|
if (seqList != null)
|
|
{
|
|
seqList.Add(seq);
|
|
}
|
|
else
|
|
{
|
|
Contexts.Combat.renderTimerEntity?.renderTimer?.AddTimer(1.3f, seq, DestroyEffect);
|
|
}
|
|
|
|
effectListDict.Add(seq, txShowProcessParam);
|
|
}
|
|
|
|
private static void ShowSingleTargetEffect(ReuseGoData reuseGoData)
|
|
{
|
|
if (reuseGoData == null)
|
|
return;
|
|
|
|
var param = (TxShowProcessParam)reuseGoData.param;
|
|
reuseGoData.param = null; // 只能被池管理
|
|
var effectObj = reuseGoData.go;
|
|
var entity = Contexts.Combat.GetEntity(param.eid);
|
|
|
|
// 此函数为回调函数,go一定有
|
|
if (param.isAttach && entity.IsValid())
|
|
{
|
|
var tbRenderEffect = RenderEffectDescMgr.Instance.GetConfig(param.effectId);
|
|
Transform bindPoint = entity.transformProxy.value;
|
|
if (entity.bindPointProxy?.TryGetBindPointOrDefault(tbRenderEffect.effectPoint,
|
|
out var point) == true)
|
|
{
|
|
bindPoint = point;
|
|
}
|
|
if (bindPoint == null)
|
|
{
|
|
XLog.LogDebug($"ShowSingleTargetEffect: bindPoint {tbRenderEffect.effectPoint} is invalid, effectId: {param.effectId}");
|
|
return;
|
|
}
|
|
effectObj.transform.SetParent(bindPoint);
|
|
effectObj.transform.SetLocalTransform(param.offset, param.rotation, param.scale);
|
|
}
|
|
else if (param.useHitPos)
|
|
{
|
|
effectObj.transform.SetTransform(param.offset, param.rotation, param.scale);
|
|
}
|
|
else
|
|
{
|
|
// todo : 有问题,但应该不会出问题,需要矩阵转换
|
|
// 不要拿transform,可能没同步
|
|
var position = entity.IsValid() ? entity.transformProxy.position : param.ghostPos;
|
|
effectObj.transform.SetTransform(
|
|
new Vector3(position.x, position.y) + new Vector3(param.offset.x, param.offset.y), param.rotation,
|
|
param.scale);
|
|
}
|
|
|
|
effectObj.SetActiveWrap(true);
|
|
}
|
|
|
|
public void ActivateEffect(List<int> seqs)
|
|
{
|
|
for (int i = 0; i < seqs.Count; i++)
|
|
{
|
|
if (effectListDict.TryGetValue(seqs[i], out var tp))
|
|
{
|
|
// 不能用warp
|
|
if (!tp.reuseGoData.go) continue;
|
|
tp.reuseGoData.go.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DeactivateEffect(List<int> seqs)
|
|
{
|
|
for (int i = 0; i < seqs.Count; i++)
|
|
{
|
|
if (effectListDict.TryGetValue(seqs[i], out var tp))
|
|
{
|
|
if (!tp.reuseGoData.go) continue;
|
|
tp.reuseGoData.go.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DestroyEffect(List<int> seqs)
|
|
{
|
|
for (var i = 0; i < seqs.Count; i++)
|
|
{
|
|
var seq = seqs[i];
|
|
if (effectListDict.TryGetValue(seq, out var tp))
|
|
{
|
|
GoPoolDic.GetPool(tp.reuseGoData.path).ReleaseGo(tp.reuseGoData);
|
|
SptPool<TxShowProcessParam>.Free(ref tp);
|
|
effectListDict.Remove(seq);
|
|
}
|
|
else
|
|
{
|
|
BattleLogger.LogInfo($"{ent} : DestroyEffect: seq {seq} is not exist");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DestroyEffect(object sq)
|
|
{
|
|
var seq = (int)sq;
|
|
if (effectListDict.TryGetValue(seq, out var tp))
|
|
{
|
|
GoPoolDic.GetPool(tp.reuseGoData.path).ReleaseGo(tp.reuseGoData);
|
|
SptPool<TxShowProcessParam>.Free(ref tp);
|
|
effectListDict.Remove(seq);
|
|
}
|
|
}
|
|
|
|
#region Mat
|
|
|
|
// 只能一次修改
|
|
public void PushMat(Material mat)
|
|
{
|
|
if (m_IsMatPushed < 0)
|
|
m_IsMatPushed++;
|
|
|
|
if (m_IsMatPushed > 0)
|
|
return;
|
|
|
|
m_IsMatPushed++;
|
|
go.GetComponentsInChildren(m_CacheRenderers);
|
|
for (var i = m_CacheRenderers.Count - 1; i >= 0; i--)
|
|
{
|
|
if (m_CacheRenderers[i].GetComponentInParent<NotChangeMatByCue>() != null)
|
|
{
|
|
m_CacheRenderers.RemoveAt(i);
|
|
continue;
|
|
}
|
|
|
|
m_CacheMaterials.Add(m_CacheRenderers[i].sharedMaterial);
|
|
m_CacheRenderers[i].sharedMaterial = mat;
|
|
}
|
|
}
|
|
|
|
public List<SpriteRenderer> OpMats()
|
|
{
|
|
return m_CacheRenderers;
|
|
}
|
|
|
|
public void PopMat()
|
|
{
|
|
m_IsMatPushed--;
|
|
|
|
for (var i = 0; i < m_CacheRenderers.Count; i++)
|
|
{
|
|
if (m_CacheRenderers[i])
|
|
{
|
|
m_CacheRenderers[i].sharedMaterial = m_CacheMaterials[i];
|
|
}
|
|
}
|
|
m_CacheRenderers.Clear();
|
|
}
|
|
|
|
#endregion
|
|
|
|
protected override void OnReset()
|
|
{
|
|
effectScale = 1;
|
|
}
|
|
}
|
|
}
|