From 077a76f77e483406c2b8447fb46d51b139b963dc Mon Sep 17 00:00:00 2001 From: Tungdv Date: Tue, 10 Feb 2026 11:12:12 +0700 Subject: [PATCH] fix: test move with brush. --- .../Scripts/Managers/EC_HPWork.cs | 2 +- .../Scripts/Managers/EC_HPWorkMove.cs | 4 +- .../PerfectWorld/Scripts/Managers/aabbcd.cs | 5 +- .../PerfectWorld/Scripts/Move/CECHostMove.cs | 5 +- Assets/PerfectWorld/Scripts/Move/EC_CDR.cs | 339 +++++++++++++++++- Assets/Scripts/CECHostPlayer.cs | 12 +- 6 files changed, 349 insertions(+), 18 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs index 4d26d2289e..5e2d1accaf 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWork.cs @@ -297,7 +297,7 @@ namespace BrewMonster.Scripts FinishWorkAtPriority(iPriority); WorkList workList = m_WorkStack[iPriority]; workList.Add(pWork); - BMLogger.LogError("m_WorkStack " + pWork.GetWorkID()); + //BMLogger.LogError("m_WorkStack " + pWork.GetWorkID()); if (shouldStart) { if (iPriority > m_iCurPriority) diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs index c92da25d82..6164b75f5c 100644 --- a/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs +++ b/Assets/PerfectWorld/Scripts/Managers/EC_HPWorkMove.cs @@ -712,9 +712,9 @@ namespace BrewMonster.Scripts { m_pHost.SetRotationHP(vMoveDir); } - + Debug.LogError("m_pHost pos = " + m_pHost.transform.position + " m_pHost.m_aabbServer.Center = " + EC_Utility.ToVector3(m_pHost.m_aabbServer.Center)); vCurPos = m_pHost.m_MoveCtrl.GroundMove(EC_Utility.ToA3DVECTOR3(vMoveDir), fSpeed, fDeltaTime, m_pHost.m_fVertSpeed); - //Debug.LogError("vCurPos =" + vCurPos); + Debug.LogError("spped =" + Vector3.Distance(EC_Utility.ToVector3(vCurPos), m_pHost.transform.position) / fDeltaTime); m_pHost.SetPos(EC_Utility.ToVector3(vCurPos)); } else diff --git a/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs b/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs index c21f41958d..94cdb1289a 100644 --- a/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs +++ b/Assets/PerfectWorld/Scripts/Managers/aabbcd.cs @@ -29,9 +29,12 @@ namespace BrewMonster.Scripts public uint dwUser1; // User defined data 1 public uint dwUser2; // User defined data 2 + // For test + public A3DVECTOR3 normal; + public void Init(A3DVECTOR3 start, A3DVECTOR3 delta, A3DVECTOR3 ext, bool bRay = false, float epsilon = 0.03125f) { - + BoundAABB = new A3DAABB(); vStart = start; vDelta = delta; vExtents = ext; diff --git a/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs b/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs index 6b4087b09f..5bf4e6aa36 100644 --- a/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs +++ b/Assets/PerfectWorld/Scripts/Move/CECHostMove.cs @@ -82,6 +82,7 @@ namespace BrewMonster ); // Record this position + Debug.LogError("Record this position"); m_vLastSevPos = EC_Utility.ToA3DVECTOR3(m.vPos); Reset(); @@ -307,6 +308,7 @@ namespace BrewMonster //CECInstance pInstance = g_pGame.GetGameRun().GetInstance(idInst); //if (pInstance.GetLimitJump()) //fGravity *= 4.0f; + Vector3 posStart = EC_Utility.ToVector3(m_pHost.m_aabbServer.Center); CDR_INFO cdr = m_pHost.m_CDRInfo; cdr.vCenter = m_pHost.m_aabbServer.Center; cdr.vXOZVelDir = vRealDirH; @@ -314,7 +316,7 @@ namespace BrewMonster cdr.t = fTime; cdr.fGravityAccel = fGravity; cdr.fYVel += fSpeedV; - EC_CDR.OnGroundMove(ref cdr); + EC_CDR.OnGroundMove_test(ref cdr); m_pHost.m_CDRInfo = cdr; //if (g_pGame.GetGameRun().GetWorld().GetAssureMove()) // g_pGame.GetGameRun().GetWorld().GetAssureMove().AssureMove(m_pHost.m_aabbServer.Center, cdr.vCenter); @@ -345,6 +347,7 @@ namespace BrewMonster m_fMoveTime += fTime; m_pHost.m_CDRInfo.vTPNormal = cdr.vTPNormal; + //Debug.LogError("speed = " + (Vector3.Distance(posStart, EC_Utility.ToVector3(vNewPos)) / fTime)); return vNewPos; } diff --git a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs index 9fe75714f7..daf6a71453 100644 --- a/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs +++ b/Assets/PerfectWorld/Scripts/Move/EC_CDR.cs @@ -123,7 +123,6 @@ namespace BrewMonster if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH) { - dir = vDelta; float num = 10f; Vector3[] arrVExt = new Vector3[5] { vExt @@ -132,12 +131,13 @@ namespace BrewMonster new Vector3(vExt.x, vExt.y, vExt.z / num), vExt / num }; - for(int i = 0; i < arrVExt.Length; i++) + dir = vStart + vDelta; + for (int i = 0; i < arrVExt.Length; i++) { - countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask); + countHits = Physics.BoxCastNonAlloc(vStart, arrVExt[i], 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.fFraction = (hits[0].distance) / vDelta.magnitude; pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal); pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH; break; @@ -301,7 +301,7 @@ namespace BrewMonster bool bTryPull = false; int nTry = 0; - LayerMask mask = UsedMask_Ground(); + LayerMask mask = UsedMask_Ground() | BrushMask; env_trace_t trcInfo = new env_trace_t(); trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH; @@ -460,6 +460,328 @@ namespace BrewMonster CDRInfo.vTPNormal = EC_Utility.ToA3DVECTOR3(vTPNormal); } + public static void OnGroundMove_test(ref CDR_INFO CDRInfo) + { + float VEL_EPSILON = 1E-4f; + float DIST_EPSILON = 1e-4f; + float NORMAL_EPSILON = 1e-2f; + float MAX_TRY = 4; + float VEL_MAX_SPEED = 200.0f; + float VEL_REFLECT = 0.3f; + + + CDRInfo.fMoveDist = 0.0f; //clear the moving dist + + bool bFreeFall = (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh); + if (CDRInfo.fYVel < VEL_EPSILON && CDRInfo.fYVel > -VEL_EPSILON && CDRInfo.fSpeed < VEL_EPSILON && CDRInfo.fSpeed > -VEL_EPSILON && !bFreeFall) + { + return; + } + + float fYVel = CDRInfo.fYVel; //save the y velocity; + + //@todo : refine the speed to determine the jumping state. By Kuiwu[14/9/2005] + bool bJump = (fYVel > 0.5f); + //bool bJump = (fYVel > CDRInfo.fGravityAccel * 0.1f); + + A3DVECTOR3 vVelocity = new A3DVECTOR3(CDRInfo.fSpeed* CDRInfo.vXOZVelDir +fYVel * GPDataTypeHelper.g_vAxisY ); + + + if (bFreeFall) + { + vVelocity -= (CDRInfo.fGravityAccel * CDRInfo.t * GPDataTypeHelper.g_vAxisY); + fYVel -= CDRInfo.fGravityAccel * CDRInfo.t; + } + A3DVECTOR3 vVelDir = (vVelocity); + float fVelSpeed = vVelDir.Normalize(); + if (!bFreeFall) + { + AAssist.a_ClampRoof(ref fVelSpeed, VEL_MAX_SPEED); + } + vVelocity = vVelDir * fVelSpeed; + //@note : clip the velocity or dir? By Kuiwu[8/9/2005] + float dtp = DotProduct(vVelDir, CDRInfo.vTPNormal); + if (dtp < 0.0f || !bJump) + { + vVelocity = (vVelDir - CDRInfo.vTPNormal * dtp - CDRInfo.vTPNormal * dtp * 0.01f) * fVelSpeed; + //a_LogOutput(1, "dtp < 0.0f || !bJump vVelocity = (%f, %f, %f) || CDRInfo.vTPNormal = (%f, %f, %f)", vVelocity.x, vVelocity.y, vVelocity.z, CDRInfo.vTPNormal.x, CDRInfo.vTPNormal.y, CDRInfo.vTPNormal.z); + } + + CDRInfo.vAbsVelocity = vVelocity; + + A3DVECTOR3 vStart = (CDRInfo.vCenter); + A3DVECTOR3 vExt = (CDRInfo.vExtent); + float fTime = CDRInfo.t; + //A3DVECTOR3 vDelta(vVelocity * fTime); + A3DVECTOR3 vDelta; + bool bClear = true; + int nTry = 0; + env_trace_t trcInfo = new env_trace_t(); + trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH; + trcInfo.vExt = vExt; + //A3DVECTOR3 vNormal, vFinalPos(vStart); + A3DVECTOR3 vNormal, vFinalPos = new A3DVECTOR3(); + bool bPull = false; + bool bTryPull = false; + + while (nTry < MAX_TRY) + { + vDelta = vVelocity * fTime; + vFinalPos = vStart; + float fDeltaDist = vDelta.Magnitude(); + //a_LogOutput(1, "fDeltaDist = %f || vVelocity = (%f, %f, %f) || fTime = %f", fDeltaDist, vVelocity.x, vVelocity.y, vVelocity.z, fTime); + //if (vDelta.SquaredMagnitude() < DIST_EPSILON ) + if (fDeltaDist < DIST_EPSILON) + { + Debug.LogError("EC_CDR fDeltaDist < DIST_EPSILON"); + break; + } + trcInfo.vStart = vStart; + trcInfo.vDelta = vDelta; + trcInfo.vTerStart = vStart; + trcInfo.vTerStart.y -= vExt.y; //foot + + bClear = !CollideWithEnv(ref trcInfo); + + ++nTry; + if (trcInfo.bStartSolid) + { + //Debug.LogError("EC_CDR trcInfo.bStartSolid = true"); + CDRInfo.fMoveDist = 0.0f; + if (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh) + { + CDRInfo.vTPNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f); + } + //a_LogOutput(1, "bClear = true but trcInfo.bStartSolid = true"); + return; + } + if (bClear) + { + //a_LogOutput(1, "bClear = true"); + vFinalPos = vStart + vDelta; + // Debug.LogError("EC_CDR bClear = true vFinalPos = " + vFinalPos + " fTime = " + fTime + "vVelocity = " + vVelocity + " speed = " + vVelocity.Magnitude()); + break; + } + + //Debug.LogError("EC_CDR trcInfo.fFraction = " + trcInfo.fFraction); + vStart += vDelta * trcInfo.fFraction; + + fTime -= fTime * trcInfo.fFraction; + vNormal = trcInfo.vHitNormal; + if (!bFreeFall && !bTryPull && !bJump) + { + env_trace_t tmpInfo = new env_trace_t(); + tmpInfo.vStart = vStart; + tmpInfo.vDelta = new A3DVECTOR3(0.0f, CDRInfo.fStepHeight, 0.0f); + tmpInfo.vExt = vExt; + //@note : need check terrain?? By Kuiwu[8/10/2005] + tmpInfo.dwCheckFlag = CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_TERRAIN; + tmpInfo.vTerStart = vStart; + tmpInfo.vTerStart.y -= vExt.y; + + bPull = !CollideWithEnv(ref tmpInfo); + if (bPull) + { + vStart.y += CDRInfo.fStepHeight; + //vDelta = vVelocity * fTime; + vDelta = vVelocity; + tmpInfo.vStart = vStart; + tmpInfo.vDelta = vDelta; + tmpInfo.vTerStart = vStart; + tmpInfo.vTerStart.y -= vExt.y; + bool bMove = !CollideWithEnv(ref tmpInfo); + if (!bMove) + { + vDelta *= tmpInfo.fFraction; + } + + if (vDelta.SquaredMagnitude() < vExt.x * vExt.x * 4) + { + vStart.y -= CDRInfo.fStepHeight; + bPull = false; + } + } + bTryPull = true; + + } + + if (!bPull) + { + fVelSpeed = Normalize(vVelocity, ref vVelDir); + fVelSpeed *= (1 - nTry * 0.1f); + dtp = DotProduct(vNormal, vVelDir); + float fRelSpeed = EC_Utility.a_Min(fVelSpeed, 5.0f); + + if ((dtp < 1E-4f) && (dtp >= 0.0f)) + {//@note : special parallel tangent plane case, rarely happen. By Kuiwu[20/10/2005] + vVelocity += vNormal * VEL_REFLECT * fRelSpeed; + } + else + { + vVelocity = (vVelDir - vNormal * dtp) * fVelSpeed - vNormal * dtp * VEL_REFLECT * fRelSpeed; + //vVelocity = (vVelDir - vNormal * dtp - vNormal*dtp * VEL_REFLECT) * fVelSpeed; + } + + + //CDRInfo.fYVel = vVelocity.y; + if (fYVel > VEL_EPSILON) + { + if ((vNormal.y >= CDRInfo.fSlopeThresh || vNormal.y < -NORMAL_EPSILON)) + { + fYVel = 0.0f; + } + } + else if (fYVel < -VEL_EPSILON) + { + if ((vNormal.y >= CDRInfo.fSlopeThresh)) + { + fYVel = 0.0f; + } + } + else + { + //@note : additional handle something??? By Kuiwu[13/9/2005] + } + } + + } + + ////@note : prevent moving to the invalid area. By Kuiwu[20/9/2005] + //if (!IsPosInAvailableMap(vFinalPos)) + //{ + // CDRInfo.fMoveDist = 0.0f; + // return; + //} + + + A3DVECTOR3 vTPNormal = new A3DVECTOR3(); + vTPNormal.Clear(); + + ground_trace_t groundTrc = new ground_trace_t(); + groundTrc.vStart = vFinalPos; + groundTrc.vExt = vExt; + groundTrc.fDeltaY = 0.3f; + + if (bPull) + { + groundTrc.fDeltaY = CDRInfo.fStepHeight + 0.1f; + } + if (bJump) + { + groundTrc.fDeltaY = 0.0f; + } + + if (!RetrieveSupportPlane(ref groundTrc)) + {//@note : do NOT change position. By Kuiwu[14/9/2005] + CDRInfo.fMoveDist = 0.0f; + // if (groundTrc.bSupport) + // { + // CDRInfo.vTPNormal = groundTrc.vHitNormal; + // } + CDRInfo.vTPNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f); + Debug.LogError("EC_CDR RetrieveSupportPlane = false"); + return; + } + if (groundTrc.bSupport) + { + Debug.LogError("EC_CDR groundTrc.bSupport = true groundTrc.vStart = " + groundTrc.vStart + " groundTrc.vEnd = " + groundTrc.vEnd); + Debug.DrawLine(EC_Utility.ToVector3(groundTrc.vStart), EC_Utility.ToVector3(groundTrc.vEnd), Color.green, 10f); + vFinalPos = groundTrc.vEnd; + if (!bJump) + { + vTPNormal = groundTrc.vHitNormal; + } + } + + + if ((vTPNormal.y >= CDRInfo.fSlopeThresh && fYVel < 0.0f) + || (!bJump && fYVel > 0.0f)) + { + fYVel = 0.0f; + } + + CDRInfo.vCenter = vFinalPos; + CDRInfo.fYVel = fYVel; //set back the y velocity + CDRInfo.vTPNormal = vTPNormal; + } + + //@desc : used to retrieve support plane (ground or brush), By Kuiwu[12/9/2005] + public struct ground_trace_t + { + public A3DVECTOR3 vStart; + public A3DVECTOR3 vExt; + public float fDeltaY; //down (-y) + + public A3DVECTOR3 vEnd; + public A3DVECTOR3 vHitNormal; + public bool bSupport; //false if ground missed + }; + + public static bool RetrieveSupportPlane(ref ground_trace_t pTrc) + { + A3DVECTOR3 vTerrainPos = new A3DVECTOR3(), vTerrainNormal = new A3DVECTOR3(); + + GetTerrainInfo(pTrc.vStart, ref vTerrainPos, ref vTerrainNormal); + pTrc.bSupport = false; + // pTrc.vEnd = pTrc.vStart; + // pTrc.vEnd.y -= pTrc.fDeltaY; + BrushTraceInfo trcInfo = new BrushTraceInfo(); + trcInfo.Init(pTrc.vStart, new A3DVECTOR3(0.0f, -pTrc.fDeltaY, 0.0f), pTrc.vExt); + if (AABBCollideWithBrush(ref trcInfo)) + { + + // if (trcInfo.bStartSolid && (!RescueFromSolid(&trcInfo))) + // { + // pTrc.bSupport = true; + // pTrc.vHitNormal = vTerrainNormal; + // pTrc.vEnd = pTrc.vStart; + // return false; + // } + if (trcInfo.bStartSolid) + { + return false; + } + pTrc.vEnd = trcInfo.vStart + trcInfo.vDelta * trcInfo.fFraction; + pTrc.vHitNormal = trcInfo.normal; + + float fUp = pTrc.vExt.y; + if (pTrc.vEnd.y > vTerrainPos.y + fUp) + { + pTrc.vStart = trcInfo.vStart; + pTrc.bSupport = true; + return true; + } + } + //if (vTerrainPos.y > pTrc.vStart.y- pTrc.vExt.y ) + if (vTerrainPos.y > pTrc.vStart.y - pTrc.vExt.y || (vTerrainPos.y <= pTrc.vStart.y - pTrc.vExt.y && vTerrainPos.y >= pTrc.vStart.y - pTrc.vExt.y - pTrc.fDeltaY)) + { + + pTrc.vEnd = vTerrainPos; + //@note : maybe sink in the sleep ground, but this is what I need. By Kuiwu[14/9/2005] + pTrc.vEnd.y += (pTrc.vExt.y + 0.01f); + A3DVECTOR3 vDelta = new A3DVECTOR3(pTrc.vEnd -pTrc.vStart); + trcInfo.Init(pTrc.vStart, vDelta, pTrc.vExt); + pTrc.vHitNormal = vTerrainNormal; + pTrc.bSupport = true; + return !AABBCollideWithBrush(ref trcInfo); + } + + return true; + + } + + public static void GetTerrainInfo(A3DVECTOR3 vPos, ref A3DVECTOR3 vPosOnSurface, ref A3DVECTOR3 vNormal) + { + vPosOnSurface = vPos; + int countHits = 0; + countHits = Physics.RaycastNonAlloc(EC_Utility.ToVector3(vPosOnSurface), Vector3.down, fHitsTerrain, 1000f, TerrainMask | BrushMask); + if (countHits > 0) + { + vPosOnSurface.y = fHitsTerrain[0].point.y; + vNormal = EC_Utility.ToA3DVECTOR3(fHitsTerrain[0].normal); + } + } + // Get normalize static float Normalize(A3DVECTOR3 vIn, ref A3DVECTOR3 vOut) { @@ -659,6 +981,7 @@ namespace BrewMonster Vector3 dir = vDelta; int countHits = 0; float num = 10f; + Quaternion quaternion = EC_Game.GetGameRun().GetWorld().GetPlayerMan().GetHostPlayer().transform.rotation; Vector3[] arrVExt = new Vector3[5] { vExt ,new Vector3(vExt.x / num, vExt.y, vExt.z), @@ -668,16 +991,18 @@ namespace BrewMonster }; for (int i = 0; i < arrVExt.Length; i++) { - countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask); + countHits = Physics.BoxCastNonAlloc(vStart, arrVExt[i], 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; + brushTraceInfo.fFraction = (hits[0].distance) / vDelta.magnitude; + brushTraceInfo.normal = EC_Utility.ToA3DVECTOR3(hits[0].normal); return true; } } } + brushTraceInfo.normal = new A3DVECTOR3(0f); brushTraceInfo.fFraction = 100f; return false; } diff --git a/Assets/Scripts/CECHostPlayer.cs b/Assets/Scripts/CECHostPlayer.cs index f0a4a1d6de..406d345383 100644 --- a/Assets/Scripts/CECHostPlayer.cs +++ b/Assets/Scripts/CECHostPlayer.cs @@ -430,13 +430,13 @@ namespace BrewMonster // ccRadius = controller.radius; ccSkin = controller.skinWidth; EstimateMoveEnv(GetPos()); OnKeyDown(); + m_pWorkMan?.Tick(Time.deltaTime); // track status of Task TickTask(); // Update timers UpdateTimers(Time.deltaTime); - m_pWorkMan?.Tick(Time.deltaTime); // Update GFXs @@ -2762,7 +2762,7 @@ namespace BrewMonster handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos)); handle.Free(); //cmd_host_correct_pos pCmd = GPDataTypeHelper.FromBytes((byte[])Msg.dwParam1); - //Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos); + Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos); SetPos(pCmd.pos); m_vVelocity.Clear(); m_CDRInfo.vAbsVelocity.Clear(); @@ -6233,13 +6233,13 @@ namespace BrewMonster LayerMask layerMaskTerrain = 1 << 6; LayerMask layerMaskBush = 1 << 7; - if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, 1000f, layerMaskTerrain) > 0) + if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, 1000f, layerMaskTerrain) > 0 && hits[0].distance > 0.0009f) { vTerrainPos = hits[0].point; vTerrainNormal = hits[0].normal; } - if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, DeltaY, layerMaskBush) > 0) + if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, DeltaY, layerMaskBush) > 0 && hits[0].distance > 0.0009f) { if (vBuildingPos.y > vTerrainPos.y) { @@ -6270,7 +6270,7 @@ namespace BrewMonster hits = new RaycastHit[5]; int count = Physics.BoxCastNonAlloc(vCenter, vExt, (Vector3.down).normalized, hits, transform.rotation, DeltaY, layerMask); - if (count == 0) + if (count == 0 && hits[0].distance > 0.0009f) { vHitPos = vCenter; vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up); @@ -6282,7 +6282,7 @@ namespace BrewMonster // 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) + if (count == 0 && hits[0].distance > 0.0009f) { vHitPos = vCenter; vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up);