Files
test/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs
T
2026-02-10 19:28:15 +07:00

516 lines
18 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using static Unity.Cinemachine.CinemachineFreeLookModifier;
namespace BrewMonster
{
public enum GfxHitPos
{
enumHitCenter,
enumHitBottom
}
public enum GfxSkillEventState
{
enumWait,
enumFlying,
enumHit,
enumFinished
}
// TODO: remove singleton later
public class A3DSkillGfxMan
{
public static A3DSkillGfxMan _instance;
public static A3DSkillGfxMan Instance
{
get
{
if (_instance == null)
{
_instance = new A3DSkillGfxMan();
}
return _instance;
}
set
{
_instance = value;
}
}
public bool AddSkillGfxEvent(
A3DSkillGfxComposer pComposer,
long nHostID,
long nTargetID,
string szFlyGfx,
string szHitGfx,
uint dwFlyTimeSpan,
bool bTraceTarget,
GfxMoveMode FlyMode,
int nFlyGfxCount,
uint dwInterval,
GFX_SKILL_PARAM param,
float fFlyGfxScale,
float fHitGfxScale,
uint dwModifier,
bool bOnlyOneHit,
bool bFadeOut,
bool bIsGoblinSkill,
bool bReverse
)
{
bool bRet = true, bCluster;
uint dwDelayTime;
if (nFlyGfxCount == 1)
{
dwDelayTime = dwInterval;
bCluster = false;
}
else
{
dwDelayTime = 0;
bCluster = true;
}
for (int i = 0; i < nFlyGfxCount; i++)
{
string value = bOnlyOneHit && i != nFlyGfxCount - 1 ? "" : szHitGfx;
if (!AddOneSkillGfxEvent(
pComposer,
nHostID,
nTargetID,
szFlyGfx,
FlyMode,
dwDelayTime,
dwFlyTimeSpan,
value,
param,
bTraceTarget,
fFlyGfxScale,
fHitGfxScale,
dwModifier,
bCluster,
bFadeOut,
bIsGoblinSkill,
bReverse
))
bRet = false;
dwDelayTime += dwInterval;
}
return bRet;
}
public bool AddOneSkillGfxEvent(
A3DSkillGfxComposer pComposer,
long nHostID,
long nTargetID,
string szFlyGfx,
GfxMoveMode mode,
uint dwDelayTime,
uint dwFlyTimeSpan,
string szHitGfx,
GFX_SKILL_PARAM param,
bool bTraceTarget,
float fFlyGfxScale,
float fHitGfxScale,
uint dwModifier,
bool bCluster,
bool bFadeOut,
bool bIsGoblinSkill,
bool bReverse)
{
A3DSkillGfxEvent pEvent = SkillGfxMan.InstanceSub.GetEmptyEvent(mode);
pEvent.SetComposer(pComposer);
pEvent.SetHostID(nHostID);
pEvent.SetTargetID(nTargetID);
pEvent.SetFlyTimeSpan(dwFlyTimeSpan);
pEvent.SetDelay(dwDelayTime);
//pEvent.SetReverse(bReverse);
//if (param.value.fVal != float.MinValue) pEvent.SetParam(param);
pEvent.SetTraceTarget(bTraceTarget);
pEvent.SetModifier(dwModifier);
//pEvent.SetIsCluster(bCluster);
pEvent.SetFadeOut(bFadeOut);
pEvent.SetGoblinSkill(bIsGoblinSkill);
ECMODEL_GFX_PROPERTY Prop = new ECMODEL_GFX_PROPERTY();
if (GetPropertyById(nHostID, ref Prop))
{
pEvent.SetGfxUseLod(Prop.bGfxUseLod);
pEvent.SetDisableCamShake(Prop.bGfxDisableCamShake);
pEvent.SetHostModelCreatedByGfx(Prop.bHostECMCreatedByGfx);
}
/* if (szFlyGfx != 0)
{
A3DGFXEx pGfx = pEvent.LoadFlyGfx(m_pDevice, szFlyGfx.ToString());
if (pGfx != null)
{
pGfx.SetScale(fFlyGfxScale);
pGfx.SetDisableCamShake(pEvent.GetDisableCamShake());
pGfx.SetCreatedByGFXECM(pEvent.GetHostModelCreatedByGfx());
pGfx.SetUseLOD(pEvent.GetGfxUseLod());
pGfx.SetId(pEvent.GetHostID());
pEvent.SetFlyGfx(pGfx);
}
}*/
if (string.IsNullOrEmpty(szHitGfx))
{
/*game pGfx = pEvent.LoadHitGfx(m_pDevice, szHitGfx.ToString());
if (pGfx != null)
{
pGfx.SetScale(fHitGfxScale);
pEvent.SetHitGfx(pGfx);
}*/
}
#if !_SKILLGFXCOMPOSER
pEvent.Tick(0);
#endif
pComposer.SpawnGFX(nTargetID);
PushEvent(pEvent);
return true;
}
public virtual bool GetPropertyById(long nId, ref ECMODEL_GFX_PROPERTY pProperty) => false;
void PushEvent(A3DSkillGfxEvent pEvent) { SkillGfxMan.InstanceSub.m_EventLst.AddLast((CECSkillGfxEvent)pEvent); }
}
public class A3DSkillGfxEvent
{
protected A3DSkillGfxComposer m_pComposer;
//protected CGfxMoveBase m_pMoveMethod;
//protected A3DGFXEx m_pFlyGfx; // 飞行特效 / Fly effect
//protected A3DGFXEx m_pHitGfx; // 命中特效 / Hit effect
protected uint m_dwFlyTimeSpan; // 飞行时间 / Flight time
protected uint m_dwCurSpan;
protected uint m_dwDelayTime;
protected bool m_bTraceTarget;
protected bool m_bFadeOut;
protected long m_nHostID;
protected long m_nTargetID;
protected uint m_dwModifier;
protected bool m_bIsGoblinSkill;
protected Vector3 m_vHostPos;
protected Vector3 m_vTargetPos;
protected Vector3 m_vTargetDir;
protected Vector3 m_vTargetUp;
protected bool m_bHostExist;
protected bool m_bTargetExist;
protected bool m_bHitGfxInfinite;
protected bool m_bTargetDirAndUpExist;
protected bool m_bGfxUseLod;
protected bool m_bGfxDisableCamShake;
protected bool m_bHostECMCreatedByGfx;
protected GfxSkillEventState m_enumState;
public A3DSkillGfxEvent(GfxMoveMode mode)
{
m_pComposer = null;
/* m_pFlyGfx = null;
m_pHitGfx = null;*/
m_nHostID = 0;
m_nTargetID = 0;
m_dwModifier = 0;
m_dwFlyTimeSpan = 0;
m_dwCurSpan = 0;
m_enumState = GfxSkillEventState.enumWait;
m_bHitGfxInfinite = false;
m_bIsGoblinSkill = false;
m_bTargetDirAndUpExist = false;
m_bGfxUseLod = true;
m_bGfxDisableCamShake = false;
m_bHostECMCreatedByGfx = false;
//m_pMoveMethod = CGfxMoveBase.CreateMoveMethod(mode);
}
~A3DSkillGfxEvent()
{
//ReleaseGfx();
// Note: m_pMoveMethod will be garbage collected
}
// Inline functions
/* protected void ReleaseFlyGfx()
{
if (m_pFlyGfx != null)
{
if (m_bFadeOut)
AfxGetGFXExMan().QueueFadeOutGfx(m_pFlyGfx, 1000);
else
{
m_pFlyGfx.Release();
// In C#, we don't need to manually delete
}
m_pFlyGfx = null;
}
}*/
/* protected void ReleaseHitGfx()
{
if (m_pHitGfx != null)
{
AfxGetGFXExMan().CacheReleasedGfx(m_pHitGfx);
m_pHitGfx = null;
}
}*/
/* protected void ReleaseGfx()
{
ReleaseFlyGfx();
ReleaseHitGfx();
}*/
// Virtual functions
protected virtual void HitTarget(Vector3 vTarget)
{
m_enumState = GfxSkillEventState.enumHit;
//ReleaseFlyGfx();
if (false /*m_pHitGfx != null*/)
{
//m_bHitGfxInfinite = m_pHitGfx.IsInfinite();
Matrix4x4 matTran;
// now try to make the hit gfx face to the attacker
if (m_bHostExist)
{
Vector3 vDir = vTarget - m_vHostPos;
vDir.y = 0;
if (vDir.magnitude < 1e-3f)
vDir = new Vector3(0, 0, 1.0f);
else
vDir.Normalize();
matTran = _build_matrix(vDir, vTarget);
}
else
{
matTran = Matrix4x4.identity;
matTran.SetColumn(3, new Vector4(vTarget.x, vTarget.y, vTarget.z, 1));
}
/* m_pHitGfx.SetParentTM(matTran);
m_pHitGfx.Start(true);
m_pHitGfx.TickAnimation(0);*/
}
}
// Public inline functions
public void SetGfxUseLod(bool b) { m_bGfxUseLod = b; }
public bool GetGfxUseLod() { return m_bGfxUseLod; }
public void SetDisableCamShake(bool b) { m_bGfxDisableCamShake = b; }
public bool GetDisableCamShake() { return m_bGfxDisableCamShake; }
public void SetHostModelCreatedByGfx(bool b) { m_bHostECMCreatedByGfx = b; }
public bool GetHostModelCreatedByGfx() { return m_bHostECMCreatedByGfx; }
public void SetComposer(A3DSkillGfxComposer pComposer) { m_pComposer = pComposer; }
//public CGfxMoveBase GetMoveMethod() { return m_pMoveMethod; }
//public GfxMoveMode GetMode() { return m_pMoveMethod.GetMode(); }
//public GfxHitPos GetHitPos() { return m_pMoveMethod.GetHitPos(); }
/* public A3DGFXEx GetFlyGfx() { return m_pFlyGfx; }
public A3DGFXEx GetHitGfx() { return m_pHitGfx; }*/
public void SetFlyTimeSpan(uint dwSpan) { m_dwFlyTimeSpan = dwSpan; }
public void SetDelay(uint dwDelay) { m_dwDelayTime = dwDelay; }
//public void SetReverse(bool bReverse) { m_pMoveMethod.SetReverse(bReverse); }
//public void SetParam(GFX_SKILL_PARAM param) { m_pMoveMethod.SetParam(param); }
//public void SetIsCluster(bool bCluster) { m_pMoveMethod.SetIsCluster(bCluster); }
public void SetTraceTarget(bool bTrace) { m_bTraceTarget = bTrace; }
public void SetFadeOut(bool bFadeOut) { m_bFadeOut = bFadeOut; }
public bool IsFinished() { return m_enumState == GfxSkillEventState.enumFinished; }
public long GetHostID() { return m_nHostID; }
public void SetHostID(long nID) { m_nHostID = nID; }
public long GetTargetID() { return m_nTargetID; }
public void SetTargetID(long nID) { m_nTargetID = nID; }
public void SetHostPos(Vector3 vPos) { m_vHostPos = vPos; }
public void SetTargetPos(Vector3 vPos) { m_vTargetPos = vPos; }
public void SetHostExist(bool bExist) { m_bHostExist = bExist; }
public void SetTargetExist(bool bExist) { m_bTargetExist = bExist; }
public void SetModifier(uint dwModifier) { m_dwModifier = dwModifier; }
public void SetGoblinSkill(bool bGoblinSkill) { m_bIsGoblinSkill = bGoblinSkill; }
public bool GetGoblinSkill() { return m_bIsGoblinSkill; }
public void Resume()
{
//ReleaseGfx();
m_enumState = GfxSkillEventState.enumWait;
m_dwCurSpan = 0;
}
// Virtual functions
/* public virtual A3DGFXEx LoadFlyGfx(A3DDevice pDev, string szPath)
{
return AfxGetGFXExMan().LoadGfx(pDev, szPath);
}
public virtual A3DGFXEx LoadHitGfx(A3DDevice pDev, string szPath)
{
return AfxGetGFXExMan().LoadGfx(pDev, szPath);
}
public virtual void SetFlyGfx(A3DGFXEx pFlyGfx)
{
m_pFlyGfx = pFlyGfx;
}
public virtual void SetHitGfx(A3DGFXEx pHitGfx)
{
m_pHitGfx = pHitGfx;
}*/
public virtual void Tick(uint dwDeltaTime)
{
m_dwCurSpan += dwDeltaTime;
if (m_enumState == GfxSkillEventState.enumFinished) return; // 结束 / Finished
else if (m_enumState == GfxSkillEventState.enumHit) // 命中 / Hit
{
/* if (m_pHitGfx == null || m_pHitGfx.GetState() == ST_STOP)
m_enumState = GfxSkillEventState.enumFinished;
else
{
if (!m_bTargetExist || (m_bHitGfxInfinite && m_pHitGfx.GetTimeElapse() > 5000)) // HIT_GFX_MAX_TIMESPAN = 5000
m_enumState = GfxSkillEventState.enumFinished;
else
{
if (m_bTraceTarget)
{
Matrix4x4 matTran = Matrix4x4.identity;
Vector3 targetCenter = GetTargetCenter();
matTran.SetColumn(3, new Vector4(targetCenter.x, targetCenter.y, targetCenter.z, 1));
//m_pHitGfx.SetParentTM(matTran);
}
//m_pHitGfx.TickAnimation(dwDeltaTime);
}
}*/
}
else if (m_dwCurSpan > m_dwFlyTimeSpan) // 飞行超时 / Flight timeout
{
if (!m_bTargetExist)
m_enumState = GfxSkillEventState.enumFinished;
/* else
HitTarget(GetTargetCenter());*/
}
else if (!m_bTargetExist)
m_enumState = GfxSkillEventState.enumFinished;
else if (m_enumState == GfxSkillEventState.enumWait)
{
if (m_dwCurSpan < m_dwDelayTime) return;
if (!m_bHostExist)
m_enumState = GfxSkillEventState.enumFinished;
else
{
m_enumState = GfxSkillEventState.enumFlying;
/* m_pMoveMethod.SetMaxFlyTime(m_dwFlyTimeSpan);
m_pMoveMethod.StartMove(m_vHostPos, m_vTargetPos);*/
/* if (m_pFlyGfx != null)
{
Vector3 vDir, vUp;
if (m_pMoveMethod.GetMode() == GfxMoveMode.enumOnTarget && m_pMoveMethod.IsReverse() && GetTargetDirAndUp(out vDir, out vUp))
m_pFlyGfx.SetParentTM(a3d_TransformMatrix(vDir, vUp, m_pMoveMethod.GetPos()));
else
m_pFlyGfx.SetParentTM(_build_matrix(m_pMoveMethod.GetMoveDir(), m_pMoveMethod.GetPos()));
m_pFlyGfx.Start(true);
m_pMoveMethod.UpdateGfxParam(m_pFlyGfx, m_vHostPos, m_vTargetPos);
m_pFlyGfx.TickAnimation(0);
}*/
}
}
else
{
/* if (m_pMoveMethod.TickMove(dwDeltaTime, m_vHostPos, m_vTargetPos)) // 目标被命中 / Target hit
HitTarget(GetTargetCenter());*/
/*else if (m_pFlyGfx != null)
{
Vector3 vDir, vUp;
if (m_pMoveMethod.GetMode() == GfxMoveMode.enumOnTarget && m_pMoveMethod.IsReverse() && GetTargetDirAndUp(out vDir, out vUp))
m_pFlyGfx.SetParentTM(a3d_TransformMatrix(vDir, vUp, m_pMoveMethod.GetPos()));
else
m_pFlyGfx.SetParentTM(_build_matrix(m_pMoveMethod.GetMoveDir(), m_pMoveMethod.GetPos()));
m_pMoveMethod.UpdateGfxParam(m_pFlyGfx, m_vHostPos, m_vTargetPos);
m_pFlyGfx.TickAnimation(dwDeltaTime);
}*/
}
}
/* public virtual void Render()
{
if (m_pFlyGfx != null) AfxGetGFXExMan().RegisterGfx(m_pFlyGfx);
if (m_pHitGfx != null) AfxGetGFXExMan().RegisterGfx(m_pHitGfx);
}
*/
public virtual Vector3 GetTargetCenter()
{
// Abstract method - must be implemented by derived class
throw new NotImplementedException("GetTargetCenter must be implemented by derived class");
}
public virtual bool GetTargetDirAndUp(out Vector3 vDir, out Vector3 vUp)
{
vDir = Vector3.zero;
vUp = Vector3.zero;
return false;
}
// Helper methods that need to be implemented elsewhere or provided by utility class
/* protected A3DGFXExMan AfxGetGFXExMan()
{
// This should return the GFX manager instance
throw new NotImplementedException("AfxGetGFXExMan needs to be implemented");
}
*/
protected Matrix4x4 _build_matrix(Vector3 dir, Vector3 pos)
{
// This should build a transformation matrix from direction and position
throw new NotImplementedException("_build_matrix needs to be implemented");
}
protected Matrix4x4 a3d_TransformMatrix(Vector3 dir, Vector3 up, Vector3 pos)
{
// This should build a transformation matrix from direction, up vector and position
throw new NotImplementedException("a3d_TransformMatrix needs to be implemented");
}
}
public struct ECMODEL_GFX_PROPERTY
{
public bool bGfxUseLod;
public bool bGfxDisableCamShake;
public bool bHostECMCreatedByGfx;
};
}