fix: update logic fly.

This commit is contained in:
Tungdv
2026-01-10 16:38:15 +07:00
parent 5f12ace1bd
commit 6a8274db30
3 changed files with 128 additions and 73 deletions
+122 -73
View File
@@ -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
{
+1
View File
@@ -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)
+5
View File
@@ -205,6 +205,11 @@ public static class EC_Utility
return (y.CompareTo(x) < 0) ? y : x;
}
public static T a_Max<T>(T x, T y) where T : IComparable<T>
{
return (y.CompareTo(x) < 0) ? x : y;
}
public static bool STRING_TO_A3DCOLOR(string str, out Color clr)
{
// A3DCOLOR_TO_STRING ת