From 6a8274db30da1961b7a21fa5a0e8d5af3c54fc8c Mon Sep 17 00:00:00 2001 From: Tungdv Date: Sat, 10 Jan 2026 16:38:15 +0700 Subject: [PATCH] fix: update logic fly. --- Assets/PerfectWorld/Scripts/Move/EC_CDR.cs | 195 +++++++++++++-------- Assets/Scripts/CECHostPlayer.cs | 1 + Assets/Scripts/EC_Utility.cs | 5 + 3 files changed, 128 insertions(+), 73 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs index 40d44284e4..fc2311fd05 100644 --- a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs +++ b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs @@ -5,7 +5,9 @@ using BrewMonster.Scripts.World; using CSNetwork.GPDataType; using System; using UnityEngine; +using UnityEngine.UI; using static BrewMonster.CECHostMove; +using static System.Net.Mime.MediaTypeNames; using WORD = System.UInt16; namespace BrewMonster @@ -122,12 +124,24 @@ namespace BrewMonster if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH) { dir = vDelta; - countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, 1 << 7); - if (countHits > 0 && Vector3.Distance(hits[0].point, vStart) > 0.0009f) + float num = 10f; + Vector3[] arrVExt = new Vector3[5] { + vExt + ,new Vector3(vExt.x / num, vExt.y, vExt.z), + new Vector3(vExt.x, vExt.y / num, vExt.z), + new Vector3(vExt.x, vExt.y, vExt.z / num), + vExt / num + }; + for(int i = 0; i < arrVExt.Length; i++) { - pEnvTrc.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude; - pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal); - pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH; + countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask); + if (countHits > 0 && hits[0].distance > 0.0009f) + { + pEnvTrc.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude; + pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal); + pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH; + break; + } } } if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_TERRAIN) == CDR_EVN.CDR_TERRAIN) @@ -136,7 +150,7 @@ namespace BrewMonster dir = vTerStart + vDelta; countHits = 0; - countHits = Physics.RaycastNonAlloc(vTerStart, dir.normalized, fHitsTerrain, vDelta.magnitude, 1 << 6); + countHits = Physics.RaycastNonAlloc(vTerStart, dir.normalized, fHitsTerrain, vDelta.magnitude, TerrainMask); if (countHits > 0 && Vector3.Distance(fHitsTerrain[0].point, vTerStart) > 0.0009f) { fFractionTerrain = (hits[0].distance) / vDelta.magnitude; @@ -170,13 +184,13 @@ namespace BrewMonster else { float h0 = 0f; - int countHits0 = Physics.RaycastNonAlloc(vWatStart + Vector3.up * 500f, Vector3.down, fHitsWater, 1000f, 1 << 8); + int countHits0 = Physics.RaycastNonAlloc(vWatStart + Vector3.up * 500f, Vector3.down, fHitsWater, 1000f, WaterMask); if (countHits0 > 0) { h0 = fHitsWater[0].point.y; } float h1 = 0f; - countHits0 = Physics.RaycastNonAlloc((vWatStart + vDelta) + Vector3.up * 500f, Vector3.down, fHitsWater, 1000f, 1 << 8); + countHits0 = Physics.RaycastNonAlloc((vWatStart + vDelta) + Vector3.up * 500f, Vector3.down, fHitsWater, 1000f, WaterMask); if(countHits0 > 0) { h1 = fHitsWater[0].point.y; @@ -632,32 +646,35 @@ namespace BrewMonster } - public static bool AABBCollideWithBrush(ref BrushTraceInfo pInfo) + public static bool AABBCollideWithBrush(ref BrushTraceInfo brushTraceInfo) { - //TO DO: fix later + Vector3 vExt = EC_Utility.ToVector3(brushTraceInfo.vExtents); + Vector3 vStart = EC_Utility.ToVector3(brushTraceInfo.vStart); + Vector3 vDelta = EC_Utility.ToVector3(brushTraceInfo.vDelta); + Vector3 dir = vDelta; + int countHits = 0; + float num = 10f; + Vector3[] arrVExt = new Vector3[5] { + vExt + ,new Vector3(vExt.x / num, vExt.y, vExt.z), + new Vector3(vExt.x, vExt.y / num, vExt.z), + new Vector3(vExt.x, vExt.y, vExt.z / num), + vExt / num + }; + for (int i = 0; i < arrVExt.Length; i++) + { + countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask); + if (countHits > 0) + { + if(hits[0].distance > 0.0009f) + { + brushTraceInfo.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude; + return true; + } + } + } + brushTraceInfo.fFraction = 100f; return false; - //CECWorld pWorld = CECWorld.Instance; //g_pGame.GetGameRun().GetWorld(); - - //CECOrnamentMan pOrnMan = pWorld.GetOrnamentMan(); - //bool bBrush = pOrnMan.TraceWithBrush(ref pInfo); - - //BrushTraceInfo info = pInfo; - //CECMatterMan pMatterMan = pWorld.GetMatterMan(); - //if (pMatterMan.TraceWithBrush(ref info) && info.fFraction < pInfo.fFraction) - //{ - // pInfo = info; - // bBrush = true; - //} - - //info = pInfo; - //CECNPCMan pNPCMan = pWorld.GetNPCMan(); - //if (pNPCMan.TraceWithBrush(ref info) && info.fFraction < pInfo.fFraction) - //{ - // pInfo = info; - // bBrush = true; - //} - - //return bBrush; } public static void OnAirMove(ref ON_AIR_CDR_INFO awmInfo) @@ -677,7 +694,7 @@ namespace BrewMonster static void AirMove(ref ON_AIR_CDR_INFO awmInfo) { float DIST_EPSILON = 1e-4f; - int MAX_TRY = 1; + int MAX_TRY = 4; float VEL_REFLECT = 0.0f; float fTime = awmInfo.t; //@todo : is it necessary to clamp the speed? By Kuiwu[20/9/2005] @@ -710,7 +727,7 @@ namespace BrewMonster trcInfo.bWaterSolid = true; trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_WATER; trcInfo.vExt = vExt; - RaycastHit hit; + while (nTry < MAX_TRY) { if (vDelta.SquaredMagnitude() < DIST_EPSILON) @@ -723,33 +740,22 @@ namespace BrewMonster trcInfo.vTerStart.y -= vExt.y; trcInfo.vWatStart = vStart; trcInfo.vWatStart.y -= vExt.y; - //bClear = !CollideWithEnv(&trcInfo); - bClear = !Physics.BoxCast(EC_Utility.ToVector3(vStart), - EC_Utility.ToVector3(vExt), - EC_Utility.ToVector3(vStart + vVelDir).normalized, - out hit, - Quaternion.identity, - EC_Utility.ToVector3(vDelta).magnitude, - UsedMask_Ground()); + bClear = !CollideWithEnv(ref trcInfo); ++nTry; if (bClear) { vFinalPos = vStart + vDelta; + break; } - else - { - vFinalPos = EC_Utility.ToA3DVECTOR3(hit.point); - vNormal = EC_Utility.ToA3DVECTOR3(hit.normal); - } - //vStart += vDelta * trcInfo.fFraction; - //vFinalPos = vStart; - //fTime -= fTime * trcInfo.fFraction; - //vNormal = trcInfo.vHitNormal; - //fSpeed = A3DVECTOR3.Normalize(vVelocity,out vVelDir); - //fSpeed *= (1 - nTry * 0.1f); - //dtp = A3DVECTOR3.DotProduct(vNormal, vVelDir); - //vVelocity = (vVelDir - vNormal * dtp - vNormal * dtp * VEL_REFLECT) * fSpeed; - //vDelta = vVelocity * fTime; + vStart += vDelta * trcInfo.fFraction; + vFinalPos = vStart; + fTime -= fTime * trcInfo.fFraction; + vNormal = trcInfo.vHitNormal; + fSpeed = Normalize(vVelocity,ref vVelDir); + fSpeed *= (1 - nTry * 0.1f); + dtp = DotProduct(vNormal, vVelDir); + vVelocity = (vVelDir - vNormal * dtp - vNormal * dtp * VEL_REFLECT) * fSpeed; + vDelta = vVelocity * fTime; } @@ -766,26 +772,68 @@ namespace BrewMonster } //see if meet height thresh - Vector3 posVStart = EC_Utility.ToVector3(vFinalPos); float fDeltaY = awmInfo.fHeightThresh + 0.1f; - if (!Physics.Raycast(posVStart, - (posVStart + Vector3.down * fDeltaY).normalized, - out hit, - fDeltaY, - UsedMask_Ground())) + LayerMask mask = TerrainMask | BrushMask; + if (!DoGroundProbe(EC_Utility.ToVector3(vFinalPos), EC_Utility.ToVector3(vExt), fDeltaY, mask, out Vector3 vEnd, out Vector3 groundNormal, out bool bSupport)) { - awmInfo.vCenter = vFinalPos; - awmInfo.vTPNormal = vNormal; return; } - else + + A3DVECTOR3 vTpNormal = new A3DVECTOR3(0.0f); + A3DVECTOR3 vOverTp = vFinalPos; + bool bAdjust = false; + awmInfo.bMeetHeightThresh = true; + + float fHWater = 0f; + int countHits0 = Physics.RaycastNonAlloc(EC_Utility.ToVector3(vFinalPos) + Vector3.up * 500f, Vector3.down, fHitsWater, 1000f, 1 << 8); + if (countHits0 > 0) { - vFinalPos = EC_Utility.ToA3DVECTOR3(hit.point); - vNormal = EC_Utility.ToA3DVECTOR3(hit.normal); - awmInfo.vCenter = vFinalPos; - awmInfo.vTPNormal = vNormal; + fHWater = fHitsWater[0].point.y; } + + if (bSupport) + { + bAdjust = true; + vOverTp = EC_Utility.ToA3DVECTOR3(vEnd); + vTpNormal = EC_Utility.ToA3DVECTOR3(groundNormal); + if (fHWater > vEnd.y) + { + vOverTp.y = fHWater; + vTpNormal = GPDataTypeHelper.g_vAxisY; + } + } + else if (vFinalPos.y < fHWater + awmInfo.fHeightThresh) + { + bAdjust = true; + vOverTp = vFinalPos; + vOverTp.y = fHWater; + vTpNormal = GPDataTypeHelper.g_vAxisY; + } + + if (bAdjust && (vOverTp.y + awmInfo.fHeightThresh > vFinalPos.y)) + { + BrushTraceInfo brushTrc = new BrushTraceInfo(); + vDelta.Clear(); + vDelta.y = vOverTp.y + awmInfo.fHeightThresh - vFinalPos.y; + float fAllow = (float)Math.Abs(awmInfo.vCenter.y - vFinalPos.y) + 0.001f; + fAllow = EC_Utility.a_Max(fAllow, 0.15f); + AAssist.a_ClampRoof(ref vDelta.y, fAllow); + + brushTrc.Init(vFinalPos, vDelta, vExt); + if (AABBCollideWithBrush(ref brushTrc)) + { + vFinalPos += (vDelta * brushTrc.fFraction); + } + else + { + vFinalPos += vDelta; + } + awmInfo.bMeetHeightThresh = (vFinalPos.y - vOverTp.y > awmInfo.fHeightThresh); + } + + awmInfo.vCenter = vFinalPos; + awmInfo.vTPNormal = vTpNormal; } static void WaterMove(ref ON_AIR_CDR_INFO awmInfo) @@ -916,11 +964,12 @@ namespace BrewMonster vDelta.y = vOverTp.y + awmInfo.fHeightThresh - vFinalPos.y; fAllow = EC_Utility.a_Min(fAllow, 0.15f); AAssist.a_ClampRoof(ref vDelta.y, fAllow); - Vector3 dir = EC_Utility.ToVector3(vDelta); - countHits = Physics.BoxCastNonAlloc(v3Start, v3Ext, dir.normalized, hits, Quaternion.identity, dir.magnitude, 1 << 7); - if (countHits > 0) + + BrushTraceInfo brushTrc = new BrushTraceInfo(); + brushTrc.Init(vFinalPos, vDelta, vExt); + if (AABBCollideWithBrush(ref brushTrc)) { - vFinalPos += EC_Utility.ToA3DVECTOR3(hits[0].point); + vFinalPos += (vDelta * brushTrc.fFraction); } else { diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index e037eedc6a..d219a82df1 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -5555,6 +5555,7 @@ namespace BrewMonster { if (Math.Abs(hits[0].distance - 0f) <= float.Epsilon) { + // halfBox with y = 0.05f? I need Y box check too small. count = Physics.BoxCastNonAlloc(vCenter, new Vector3(vExt.x, 0.05f, vExt.z), (Vector3.down).normalized, hits, transform.rotation, DeltaY, layerMask); if(count == 0) diff --git a/Assets/Scripts/EC_Utility.cs b/Assets/Scripts/EC_Utility.cs index 5701675376..19d370eb96 100644 --- a/Assets/Scripts/EC_Utility.cs +++ b/Assets/Scripts/EC_Utility.cs @@ -205,6 +205,11 @@ public static class EC_Utility return (y.CompareTo(x) < 0) ? y : x; } + public static T a_Max(T x, T y) where T : IComparable + { + return (y.CompareTo(x) < 0) ? x : y; + } + public static bool STRING_TO_A3DCOLOR(string str, out Color clr) { // ��� A3DCOLOR_TO_STRING ������ת��