fix: update logic swim.
This commit is contained in:
@@ -175,8 +175,8 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_GROUND)
|
||||
Tick_Walk(fDeltaTime);
|
||||
/* else // AIR or WATER
|
||||
Tick_FlySwim(fDeltaTime);*/
|
||||
else // AIR or WATER
|
||||
Tick_FlySwim(fDeltaTime);
|
||||
}
|
||||
|
||||
if (m_iPoseAction == (int)PLAYER_ACTION_TYPE.ACT_STAND)
|
||||
@@ -236,25 +236,37 @@ namespace BrewMonster.Scripts
|
||||
}
|
||||
|
||||
// Tick routine of flying or swimming
|
||||
/* bool Tick_FlySwim(float fDeltaTime)
|
||||
{
|
||||
m_bMoving = false;
|
||||
bool Tick_FlySwim(float fDeltaTime)
|
||||
{
|
||||
m_bMoving = false;
|
||||
|
||||
if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_WATER && !m_bWaterStop)
|
||||
{
|
||||
// Handle floating at water surface after falling into water
|
||||
A3DVECTOR3 vCurPos = m_pHost.GetPos();
|
||||
// ON_AIR_CDR_INFO not available in current C# port; approximate using CDR_INFO where applicable
|
||||
float fSpeed = m_pHost.GetSwimSpeedSev();
|
||||
if (m_pHost.m_iMoveEnv == CECPlayer.Move_environment.MOVEENV_WATER && !m_bWaterStop)
|
||||
{
|
||||
// Handle floating at water surface after falling into water
|
||||
A3DVECTOR3 vCurPos = m_pHost.GetPos();
|
||||
ON_AIR_CDR_INFO cdr = m_pHost.m_AirCDRInfo;
|
||||
float fSpeed = m_pHost.GetSwimSpeedSev();
|
||||
|
||||
// As we don't have water height/extent readily available on host in this port,
|
||||
// retain structure and leave movement here minimal.
|
||||
// If water height APIs are added, restore the original logic.
|
||||
// m_bMoving = true; // enable when full water logic is available
|
||||
}
|
||||
if (m_pHost.m_GndInfo.fWaterHei - vCurPos.y < cdr.vExtent.y + m_pHost.m_MoveConst.fWaterSurf)
|
||||
{
|
||||
m_bMoving = true;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
vCurPos = m_pHost.m_MoveCtrl.AirWaterMove(-GPDataTypeHelper.g_vAxisY, fSpeed, fDeltaTime, false, false);
|
||||
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
|
||||
|
||||
if (m_pHost.m_MoveCtrl.MoveBlocked() >= 3 ||
|
||||
m_pHost.m_GndInfo.fWaterHei - vCurPos.y >= cdr.vExtent.y + m_pHost.m_MoveConst.fWaterSurf)
|
||||
{
|
||||
m_bWaterStop = true;
|
||||
m_pHost.m_MoveCtrl.SendStopMoveCmd(EC_Utility.ToVector3(vCurPos), fSpeed, (int)GPMoveMode.GP_MOVE_WATER | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
else
|
||||
m_pHost.m_MoveCtrl.SendMoveCmd(vCurPos, 2, GPDataTypeHelper.g_vOrigin, -GPDataTypeHelper.g_vAxisY * fSpeed, (int)GPMoveMode.GP_MOVE_WATER | (int)GPMoveMode.GP_MOVE_RUN);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get stop sliding flag
|
||||
public bool GetStopSlideFlag()
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace BrewMonster
|
||||
public static LayerMask WaterMask { get; set; } = 1 << 8;
|
||||
|
||||
public static RaycastHit[] hits = new RaycastHit[5];
|
||||
public static RaycastHit[] fHitsTerrain = new RaycastHit[5];
|
||||
public static RaycastHit[] fHitsWater = new RaycastHit[5];
|
||||
|
||||
const float LOCAL_EPSILON = 1e-5f;
|
||||
const float FLY_MAX_HEIGHT = 800.0f; // ·ÉÐеÄ×î´ó¸ß¶È£¡
|
||||
@@ -113,62 +115,99 @@ namespace BrewMonster
|
||||
Vector3 vExt = EC_Utility.ToVector3(pEnvTrc.vExt);
|
||||
Vector3 vDelta = EC_Utility.ToVector3(pEnvTrc.vDelta);
|
||||
Vector3 vTerStart = EC_Utility.ToVector3(pEnvTrc.vTerStart);
|
||||
Vector3 vWatStart = EC_Utility.ToVector3(pEnvTrc.vWatStart);
|
||||
Vector3 dir = Vector3.zero;
|
||||
int countHits = 0;
|
||||
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH)
|
||||
{
|
||||
dir = vStart + vDelta;
|
||||
if (Physics.BoxCast(vStart, vExt, dir, out RaycastHit hit, Quaternion.identity, vDelta.magnitude, 1 << 7))
|
||||
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)
|
||||
{
|
||||
pEnvTrc.fFraction = (hit.distance - vExt.x) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
pEnvTrc.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal);
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH;
|
||||
}
|
||||
else
|
||||
{
|
||||
pEnvTrc.fFraction = 1f;
|
||||
}
|
||||
}
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_TERRAIN) == CDR_EVN.CDR_TERRAIN)
|
||||
{
|
||||
float fFractionTerrain = 0f;
|
||||
dir = vDelta;
|
||||
if (Physics.Raycast(vTerStart, dir.normalized, out RaycastHit hit, vDelta.magnitude, 1 << 6))
|
||||
float fFractionTerrain = 100f;
|
||||
dir = vTerStart + vDelta;
|
||||
|
||||
countHits = 0;
|
||||
countHits = Physics.RaycastNonAlloc(vTerStart, dir.normalized, fHitsTerrain, vDelta.magnitude, 1 << 6);
|
||||
if (countHits > 0 && Vector3.Distance(fHitsTerrain[0].point, vTerStart) > 0.0009f)
|
||||
{
|
||||
fFractionTerrain = (hit.distance) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hit.normal);
|
||||
fFractionTerrain = (hits[0].distance) / vDelta.magnitude;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal);
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_TERRAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
fFractionTerrain = 1f;
|
||||
}
|
||||
if (fFractionTerrain < pEnvTrc.fFraction)
|
||||
{
|
||||
hits = fHitsTerrain;
|
||||
pEnvTrc.fFraction = fFractionTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_WATER) == CDR_EVN.CDR_WATER)
|
||||
{
|
||||
float fFraction = 0f;
|
||||
A3DVECTOR3 vWatNormal = new A3DVECTOR3();
|
||||
float fFraction = 100f;
|
||||
Vector3 vWatNormal = Vector3.zero;
|
||||
bool bStart = false;
|
||||
//@todo : TBD: use center or foot? By Kuiwu[10/10/2005]
|
||||
//if (CollideWithWater(pEnvTrc.vWatStart, pEnvTrc.vDelta, pEnvTrc.bWaterSolid, ref fFraction, ref vWatNormal, ref bStart)
|
||||
// && fFraction < pEnvTrc.fFraction)
|
||||
//{
|
||||
// pEnvTrc.fFraction = fFraction;
|
||||
// pEnvTrc.vHitNormal = vWatNormal;
|
||||
// pEnvTrc.bStartSolid = bStart;
|
||||
// pEnvTrc.dwClsFlag = CDR_EVN.CDR_WATER;
|
||||
// //# ifdef CDR_DEBUG
|
||||
// // A3DVECTOR3 vHitPos(pEnvTrc.vWatStart +pEnvTrc.vDelta * fFraction);
|
||||
// // sprintf(msg, "collide water, fraction %f pos %f %f %f \n", fFraction, vHitPos.x, vHitPos.y, vHitPos.z);
|
||||
// // OUTPUT_DEBUG_INFO(msg);
|
||||
// //#endif
|
||||
if (pEnvTrc.bWaterSolid && (vDelta.y > LOCAL_EPSILON))
|
||||
{
|
||||
fFraction = 0;
|
||||
}
|
||||
else if (!pEnvTrc.bWaterSolid && (vDelta.y < -LOCAL_EPSILON))
|
||||
{
|
||||
fFraction = 0;
|
||||
}
|
||||
else if (vDelta.y < LOCAL_EPSILON && vDelta.y > -LOCAL_EPSILON)
|
||||
{ //parallel the water plane
|
||||
fFraction = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float h0 = 0f;
|
||||
int countHits0 = Physics.RaycastNonAlloc(vWatStart, Vector3.down, fHitsWater, 1000f, 1 << 8);
|
||||
if (countHits0 > 0)
|
||||
{
|
||||
h0 = fHitsWater[0].point.y;
|
||||
}
|
||||
float h1 = 0f;
|
||||
countHits0 = Physics.RaycastNonAlloc((vWatStart + vDelta), Vector3.down, fHitsWater, 1000f, 1 << 8);
|
||||
if(countHits0 > 0)
|
||||
{
|
||||
h1 = fHitsWater[0].point.y;
|
||||
}
|
||||
float hWater = Mathf.Max(h0, h1);
|
||||
vWatNormal = Vector3.up;
|
||||
float t = (hWater - vWatStart.y) / pEnvTrc.vDelta.y;
|
||||
if (t >= 0.0f && t <= 1.0f)
|
||||
{
|
||||
fFraction = Mathf.Max(0.0f, t - 1E-2f);
|
||||
if (pEnvTrc.bWaterSolid && h0 > vStart.y)
|
||||
{
|
||||
fFraction = 0.0f;
|
||||
bStart = true;
|
||||
}
|
||||
|
||||
//}
|
||||
if (!pEnvTrc.bWaterSolid && h0 < vStart.y)
|
||||
{
|
||||
fFraction = 0.0f;
|
||||
bStart = true;
|
||||
}
|
||||
|
||||
if(fFraction < pEnvTrc.fFraction)
|
||||
{
|
||||
pEnvTrc.fFraction = fFraction;
|
||||
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(vWatNormal);
|
||||
pEnvTrc.bStartSolid = bStart;
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_WATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (pEnvTrc.fFraction < 1.0f + 1E-4f);
|
||||
@@ -751,7 +790,149 @@ namespace BrewMonster
|
||||
|
||||
static void WaterMove(ref ON_AIR_CDR_INFO awmInfo)
|
||||
{
|
||||
float fTime = awmInfo.t;
|
||||
//@todo : is it necessary to clamp the speed? By Kuiwu[20/9/2005]
|
||||
float fSpeed = awmInfo.fSpeed;
|
||||
if (fSpeed * fTime < DIST_EPSILON)
|
||||
{
|
||||
//@todo : set the output param. By Kuiwu[20/9/2005]
|
||||
return;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vStart = awmInfo.vCenter;
|
||||
A3DVECTOR3 vExt = awmInfo.vExtent;
|
||||
A3DVECTOR3 vVelDir = awmInfo.vVelDir;
|
||||
float dtp = 0f;
|
||||
A3DVECTOR3 vVelocity = vVelDir* fSpeed;
|
||||
|
||||
if ((dtp = DotProduct(vVelDir, awmInfo.vTPNormal)) < 0.0f)
|
||||
{
|
||||
vVelocity = (vVelDir - awmInfo.vTPNormal * dtp - awmInfo.vTPNormal * dtp * 0.01f) * fSpeed;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vDelta = (vVelocity* fTime), vNormal, vFinalPos = vStart;
|
||||
int nTry = 0;
|
||||
bool bClear = true;
|
||||
env_trace_t trcInfo = new env_trace_t();
|
||||
trcInfo.bWaterSolid = false;
|
||||
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_WATER;
|
||||
trcInfo.vExt = vExt;
|
||||
|
||||
while (nTry < 1)
|
||||
{
|
||||
if (vDelta.SquaredMagnitude() < DIST_EPSILON)
|
||||
{
|
||||
break;
|
||||
}
|
||||
trcInfo.vStart = vStart;
|
||||
trcInfo.vDelta = vDelta;
|
||||
trcInfo.vTerStart = vStart;
|
||||
trcInfo.vTerStart.y -= vExt.y;
|
||||
trcInfo.vWatStart = vStart;
|
||||
trcInfo.vWatStart.y += awmInfo.fUnderWaterDistThresh; //shoulder
|
||||
|
||||
|
||||
bClear = !CollideWithEnv(ref trcInfo);
|
||||
|
||||
++nTry;
|
||||
if (bClear || (trcInfo.bStartSolid && ((trcInfo.dwClsFlag & CDR_EVN.CDR_WATER) != CDR_EVN.CDR_WATER)))
|
||||
{
|
||||
vFinalPos = vStart + vDelta;
|
||||
break;
|
||||
}
|
||||
vStart += vDelta * trcInfo.fFraction;
|
||||
fTime -= fTime * trcInfo.fFraction;
|
||||
fSpeed = Normalize(vVelocity,ref vVelDir);
|
||||
fSpeed *= (1 - nTry * 0.1f);
|
||||
if ((trcInfo.dwClsFlag & CDR_EVN.CDR_WATER) == CDR_EVN.CDR_WATER)
|
||||
{
|
||||
if (trcInfo.bStartSolid)
|
||||
{//rescue from solid
|
||||
//@note : it may cause some problems. By Kuiwu[11/10/2005]
|
||||
float fHWater = 0f;
|
||||
int countHits0 = Physics.RaycastNonAlloc(EC_Utility.ToVector3(vStart), Vector3.down, fHitsWater, 1000f, 1 << 8);
|
||||
if(countHits0 > 0)
|
||||
{
|
||||
fHWater = fHitsWater[0].point.y;
|
||||
}
|
||||
vStart.y = fHWater;
|
||||
}
|
||||
vVelDir.y = 0.0f;
|
||||
vVelocity = vVelDir * fSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
vNormal = trcInfo.vHitNormal;
|
||||
dtp = DotProduct(vNormal, vVelDir);
|
||||
vVelocity = (vVelDir - vNormal * dtp - vNormal * dtp * VEL_REFLECT) * fSpeed;
|
||||
}
|
||||
vDelta = vVelocity * fTime;
|
||||
vFinalPos = vStart;
|
||||
|
||||
}
|
||||
|
||||
//@note : prevent moving to the invalid area. By Kuiwu[20/9/2005]
|
||||
if (!IsPosInAvailableMap(vFinalPos))
|
||||
{
|
||||
//@todo : set some flag to notify the caller? By Kuiwu[20/9/2005]
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//see if meet height thresh
|
||||
Vector3 v3Start = EC_Utility.ToVector3(vFinalPos);
|
||||
Vector3 v3Ext = EC_Utility.ToVector3(vExt);
|
||||
float fDeltaY = awmInfo.fHeightThresh + 0.1f;
|
||||
|
||||
if (!DoGroundProbe(v3Start, v3Ext, fDeltaY, UsedMask_Ground(), out Vector3 vEnd, out Vector3 groundNormal, out bool bSupport))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vTpNormal = new A3DVECTOR3(0.0f);
|
||||
A3DVECTOR3 vOverTp = vFinalPos;
|
||||
bool bAdjust = false;
|
||||
awmInfo.bMeetHeightThresh = true;
|
||||
|
||||
if (bSupport)
|
||||
{
|
||||
bAdjust = true;
|
||||
vOverTp = EC_Utility.ToA3DVECTOR3(vEnd);
|
||||
vTpNormal = EC_Utility.ToA3DVECTOR3(groundNormal);
|
||||
}
|
||||
|
||||
if (bAdjust && (vOverTp.y + awmInfo.fHeightThresh > vFinalPos.y))
|
||||
{
|
||||
float fHWater = 0f;
|
||||
int countHits = Physics.RaycastNonAlloc(EC_Utility.ToVector3(vFinalPos), Vector3.down, fHitsWater, 1000f, 1 << 8);
|
||||
if (countHits > 0)
|
||||
{
|
||||
fHWater = fHitsWater[0].point.y;
|
||||
}
|
||||
|
||||
float fAllow = fHWater - awmInfo.fUnderWaterDistThresh - vFinalPos.y;
|
||||
if (fAllow > 1E-4f)
|
||||
{
|
||||
vDelta.Clear();
|
||||
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)
|
||||
{
|
||||
vFinalPos += EC_Utility.ToA3DVECTOR3(hits[0].point);
|
||||
}
|
||||
else
|
||||
{
|
||||
vFinalPos += vDelta;
|
||||
}
|
||||
awmInfo.bMeetHeightThresh = (vFinalPos.y - vOverTp.y > awmInfo.fHeightThresh);
|
||||
}
|
||||
}
|
||||
|
||||
awmInfo.vCenter = vFinalPos;
|
||||
awmInfo.vTPNormal = vTpNormal;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -13,7 +13,7 @@ TagManager:
|
||||
- UI
|
||||
- Terrain
|
||||
- Brush
|
||||
-
|
||||
- Water
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
Reference in New Issue
Block a user