(8e2e6e4da) Physics error prevention: - Use the ApplyForce/ApplyImpulse method overrides that clamp the resulting velocity to a value (in this case NetConfig.MaxPhysicsBodyVelocity, 64 m/s). Without this, explosions and attacks for example could apply arbitrarily large forces to bodies, causing physics errors in Ragdoll.CheckValidity. - Make sure angular velocity still has a sane value after applying an impulse to a specific point of a collider.
This commit is contained in:
@@ -1094,7 +1094,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (flowForce.LengthSquared() > 0.001f)
|
if (flowForce.LengthSquared() > 0.001f)
|
||||||
{
|
{
|
||||||
Collider.ApplyForce(flowForce);
|
Collider.ApplyForce(flowForce, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentHull == null ||
|
if (currentHull == null ||
|
||||||
@@ -1132,7 +1132,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (flowForce.LengthSquared() > 0.001f)
|
if (flowForce.LengthSquared() > 0.001f)
|
||||||
{
|
{
|
||||||
limb.body.ApplyForce(flowForce);
|
limb.body.ApplyForce(flowForce, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
surfaceY = limbHull.Surface;
|
surfaceY = limbHull.Surface;
|
||||||
|
|||||||
@@ -2187,7 +2187,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (limbHit == null) return new AttackResult();
|
if (limbHit == null) return new AttackResult();
|
||||||
|
|
||||||
limbHit.body?.ApplyLinearImpulse(attack.TargetImpulseWorld + attack.TargetForceWorld * deltaTime);
|
limbHit.body?.ApplyLinearImpulse(attack.TargetImpulseWorld + attack.TargetForceWorld * deltaTime, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
#if SERVER
|
#if SERVER
|
||||||
if (attacker is Character attackingCharacter && attackingCharacter.AIController == null)
|
if (attacker is Character attackingCharacter && attackingCharacter.AIController == null)
|
||||||
{
|
{
|
||||||
@@ -2273,7 +2273,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Vector2 diff = dir;
|
Vector2 diff = dir;
|
||||||
if (diff == Vector2.Zero) diff = Rand.Vector(1.0f);
|
if (diff == Vector2.Zero) diff = Rand.Vector(1.0f);
|
||||||
hitLimb.body.ApplyLinearImpulse(Vector2.Normalize(diff) * attackImpulse, hitLimb.SimPosition + ConvertUnits.ToSimUnits(diff));
|
hitLimb.body.ApplyLinearImpulse(Vector2.Normalize(diff) * attackImpulse, hitLimb.SimPosition + ConvertUnits.ToSimUnits(diff),
|
||||||
|
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
Vector2 simPos = hitLimb.SimPosition + ConvertUnits.ToSimUnits(dir);
|
||||||
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound);
|
AttackResult attackResult = hitLimb.AddDamage(simPos, afflictions, playSound);
|
||||||
@@ -2362,7 +2363,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (diff == Vector2.Zero) { continue; }
|
if (diff == Vector2.Zero) { continue; }
|
||||||
limb.body.ApplyLinearImpulse(diff * 50.0f);
|
limb.body.ApplyLinearImpulse(diff * 50.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImplodeFX();
|
ImplodeFX();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using Barotrauma.Networking;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -625,13 +626,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Limb limb = character.AnimController.Limbs[limbIndex];
|
Limb limb = character.AnimController.Limbs[limbIndex];
|
||||||
Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
|
Vector2 forcePos = limb.pullJoint == null ? limb.body.SimPosition : limb.pullJoint.WorldAnchorA;
|
||||||
limb.body.ApplyLinearImpulse(limb.Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos);
|
limb.body.ApplyLinearImpulse(limb.Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos,
|
||||||
|
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
|
Vector2 forcePos = pullJoint == null ? body.SimPosition : pullJoint.WorldAnchorA;
|
||||||
body.ApplyLinearImpulse(Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition), forcePos);
|
body.ApplyLinearImpulse(
|
||||||
|
Mass * attack.Force * Vector2.Normalize(attackSimPos - SimPosition),
|
||||||
|
forcePos,
|
||||||
|
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return wasHit;
|
return wasHit;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using FarseerPhysics;
|
using Barotrauma.Networking;
|
||||||
|
using FarseerPhysics;
|
||||||
using FarseerPhysics.Collision;
|
using FarseerPhysics.Collision;
|
||||||
using FarseerPhysics.Dynamics;
|
using FarseerPhysics.Dynamics;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
@@ -168,7 +169,8 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
//recoil
|
//recoil
|
||||||
item.body.ApplyLinearImpulse(
|
item.body.ApplyLinearImpulse(
|
||||||
new Vector2((float)Math.Cos(projectile.Item.body.Rotation), (float)Math.Sin(projectile.Item.body.Rotation)) * item.body.Mass * -50.0f);
|
new Vector2((float)Math.Cos(projectile.Item.body.Rotation), (float)Math.Sin(projectile.Item.body.Rotation)) * item.body.Mass * -50.0f,
|
||||||
|
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
item.RemoveContained(projectile.Item);
|
item.RemoveContained(projectile.Item);
|
||||||
|
|
||||||
|
|||||||
@@ -106,10 +106,10 @@ namespace Barotrauma.Items.Components
|
|||||||
#endif
|
#endif
|
||||||
Character thrower = picker;
|
Character thrower = picker;
|
||||||
item.Drop(thrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
item.Drop(thrower, createNetworkEvent: GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer);
|
||||||
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f);
|
item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f);
|
ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f);
|
ac.GetLimb(LimbType.Torso).body.ApplyLinearImpulse(throwVector * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
Limb rightHand = ac.GetLimb(LimbType.RightHand);
|
Limb rightHand = ac.GetLimb(LimbType.RightHand);
|
||||||
item.body.AngularVelocity = rightHand.body.AngularVelocity;
|
item.body.AngularVelocity = rightHand.body.AngularVelocity;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using FarseerPhysics;
|
using Barotrauma.Networking;
|
||||||
|
using FarseerPhysics;
|
||||||
using FarseerPhysics.Dynamics;
|
using FarseerPhysics.Dynamics;
|
||||||
using FarseerPhysics.Dynamics.Contacts;
|
using FarseerPhysics.Dynamics.Contacts;
|
||||||
using FarseerPhysics.Dynamics.Joints;
|
using FarseerPhysics.Dynamics.Joints;
|
||||||
@@ -176,7 +177,7 @@ namespace Barotrauma.Items.Components
|
|||||||
item.Drop(null);
|
item.Drop(null);
|
||||||
|
|
||||||
item.body.Enabled = true;
|
item.body.Enabled = true;
|
||||||
item.body.ApplyLinearImpulse(impulse);
|
item.body.ApplyLinearImpulse(impulse, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
item.body.FarseerBody.OnCollision += OnProjectileCollision;
|
item.body.FarseerBody.OnCollision += OnProjectileCollision;
|
||||||
item.body.FarseerBody.IsBullet = true;
|
item.body.FarseerBody.IsBullet = true;
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private float blinkTimer;
|
private float blinkTimer;
|
||||||
|
|
||||||
|
private bool itemLoaded;
|
||||||
|
|
||||||
|
private float blinkTimer;
|
||||||
|
|
||||||
public PhysicsBody ParentBody;
|
public PhysicsBody ParentBody;
|
||||||
|
|
||||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)]
|
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 2048.0f), Serialize(100.0f, true)]
|
||||||
|
|||||||
@@ -1134,7 +1134,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Vector2 drag = body.LinearVelocity * volume;
|
Vector2 drag = body.LinearVelocity * volume;
|
||||||
|
|
||||||
body.ApplyForce((uplift - drag) * 10.0f);
|
body.ApplyForce((uplift - drag) * 10.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
//apply simple angular drag
|
//apply simple angular drag
|
||||||
body.ApplyTorque(body.AngularVelocity * volume * -0.05f);
|
body.ApplyTorque(body.AngularVelocity * volume * -0.05f);
|
||||||
|
|||||||
@@ -236,8 +236,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
Vector2 limbDiff = Vector2.Normalize(limb.WorldPosition - worldPosition);
|
||||||
if (!MathUtils.IsValid(limbDiff)) limbDiff = Rand.Vector(1.0f);
|
if (!MathUtils.IsValid(limbDiff)) limbDiff = Rand.Vector(1.0f);
|
||||||
|
Vector2 impulse = limbDiff * distFactor * force;
|
||||||
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
Vector2 impulsePoint = limb.SimPosition - limbDiff * limbRadius;
|
||||||
limb.body.ApplyLinearImpulse(limbDiff * distFactor * force, impulsePoint);
|
limb.body.ApplyLinearImpulse(impulse, impulsePoint, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -561,17 +561,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
foreach (var gap in ConnectedGaps.Where(gap => gap.Open > 0))
|
foreach (var gap in ConnectedGaps.Where(gap => gap.Open > 0))
|
||||||
{
|
{
|
||||||
//var pos = gap.Position - body.Position;
|
var distance = MathHelper.Max(Vector2.DistanceSquared(item.Position, gap.Position) / 1000, 1f);
|
||||||
var distance = MathHelper.Max(Vector2.DistanceSquared(item.Position, gap.Position)/1000, 1f);
|
item.body.ApplyForce((gap.LerpedFlowForce / distance) * deltaTime, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
|
|
||||||
//pos.Normalize();
|
|
||||||
item.body.ApplyForce((gap.LerpedFlowForce/distance) * deltaTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Extinguish(float deltaTime, float amount, Vector2 position)
|
public void Extinguish(float deltaTime, float amount, Vector2 position)
|
||||||
{
|
{
|
||||||
for (int i = FireSources.Count - 1; i >= 0; i-- )
|
for (int i = FireSources.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
FireSources[i].Extinguish(deltaTime, amount, position);
|
FireSources[i].Extinguish(deltaTime, amount, position);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -543,19 +543,19 @@ namespace Barotrauma
|
|||||||
if (ForceVelocityLimit < 1000.0f)
|
if (ForceVelocityLimit < 1000.0f)
|
||||||
body.ApplyForce(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
|
body.ApplyForce(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
|
||||||
else
|
else
|
||||||
body.ApplyForce(Force * currentForceFluctuation * distFactor);
|
body.ApplyForce(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
break;
|
break;
|
||||||
case TriggerForceMode.Acceleration:
|
case TriggerForceMode.Acceleration:
|
||||||
if (ForceVelocityLimit < 1000.0f)
|
if (ForceVelocityLimit < 1000.0f)
|
||||||
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, ForceVelocityLimit);
|
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, ForceVelocityLimit);
|
||||||
else
|
else
|
||||||
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor);
|
body.ApplyForce(Force * body.Mass * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
break;
|
break;
|
||||||
case TriggerForceMode.Impulse:
|
case TriggerForceMode.Impulse:
|
||||||
if (ForceVelocityLimit < 1000.0f)
|
if (ForceVelocityLimit < 1000.0f)
|
||||||
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, ForceVelocityLimit);
|
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: ForceVelocityLimit);
|
||||||
else
|
else
|
||||||
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor);
|
body.ApplyLinearImpulse(Force * currentForceFluctuation * distFactor, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
break;
|
break;
|
||||||
case TriggerForceMode.LimitVelocity:
|
case TriggerForceMode.LimitVelocity:
|
||||||
float maxVel = ForceVelocityLimit * currentForceFluctuation * distFactor;
|
float maxVel = ForceVelocityLimit * currentForceFluctuation * distFactor;
|
||||||
@@ -563,7 +563,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
body.ApplyForce(
|
body.ApplyForce(
|
||||||
Vector2.Normalize(-body.LinearVelocity) *
|
Vector2.Normalize(-body.LinearVelocity) *
|
||||||
Force.Length() * body.Mass * currentForceFluctuation * distFactor);
|
Force.Length() * body.Mass * currentForceFluctuation * distFactor,
|
||||||
|
maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -587,11 +587,16 @@ namespace Barotrauma
|
|||||||
if (!IsValidValue(impulse / body.Mass, "new velocity")) return;
|
if (!IsValidValue(impulse / body.Mass, "new velocity")) return;
|
||||||
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
||||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||||
|
|
||||||
float currSpeed = body.LinearVelocity.Length();
|
|
||||||
Vector2 velocityAddition = impulse / Mass;
|
Vector2 velocityAddition = impulse / Mass;
|
||||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||||
newVelocity = newVelocity.ClampLength(Math.Max(currSpeed, maxVelocity));
|
float newSpeedSqr = newVelocity.LengthSquared();
|
||||||
|
if (newSpeedSqr > maxVelocity * maxVelocity)
|
||||||
|
{
|
||||||
|
newVelocity = newVelocity.ClampLength(maxVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidValue((newVelocity - body.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||||
|
|
||||||
body.ApplyLinearImpulse((newVelocity - body.LinearVelocity) * Mass);
|
body.ApplyLinearImpulse((newVelocity - body.LinearVelocity) * Mass);
|
||||||
}
|
}
|
||||||
@@ -600,10 +605,36 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
||||||
if (!IsValidValue(point, "point")) return;
|
if (!IsValidValue(point, "point")) return;
|
||||||
if (!IsValidValue(impulse / body.Mass, "new velocity")) return;
|
if (!IsValidValue(impulse / body.Mass, "new velocity", -1000.0f, 1000.0f)) return;
|
||||||
body.ApplyLinearImpulse(impulse, point);
|
body.ApplyLinearImpulse(impulse, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply an impulse to the body without increasing it's velocity above a specific limit.
|
||||||
|
/// </summary>
|
||||||
|
public void ApplyLinearImpulse(Vector2 impulse, Vector2 point, float maxVelocity)
|
||||||
|
{
|
||||||
|
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
||||||
|
if (!IsValidValue(point, "point")) return;
|
||||||
|
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||||
|
|
||||||
|
Vector2 velocityAddition = impulse / Mass;
|
||||||
|
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||||
|
float newSpeedSqr = newVelocity.LengthSquared();
|
||||||
|
if (newSpeedSqr > maxVelocity * maxVelocity)
|
||||||
|
{
|
||||||
|
newVelocity = newVelocity.ClampLength(maxVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidValue((newVelocity - body.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||||
|
|
||||||
|
body.ApplyLinearImpulse((newVelocity - body.LinearVelocity) * Mass, point);
|
||||||
|
body.AngularVelocity = MathHelper.Clamp(
|
||||||
|
body.AngularVelocity,
|
||||||
|
-NetConfig.MaxPhysicsBodyAngularVelocity,
|
||||||
|
NetConfig.MaxPhysicsBodyAngularVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyForce(Vector2 force)
|
public void ApplyForce(Vector2 force)
|
||||||
{
|
{
|
||||||
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
||||||
@@ -618,11 +649,14 @@ namespace Barotrauma
|
|||||||
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
||||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||||
|
|
||||||
float currSpeed = body.LinearVelocity.Length();
|
|
||||||
Vector2 velocityAddition = force / Mass * (float)Timing.Step;
|
Vector2 velocityAddition = force / Mass * (float)Timing.Step;
|
||||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||||
newVelocity = newVelocity.ClampLength(Math.Max(currSpeed, maxVelocity));
|
|
||||||
|
float newSpeedSqr = newVelocity.LengthSquared();
|
||||||
|
if (newSpeedSqr > maxVelocity * maxVelocity)
|
||||||
|
{
|
||||||
|
newVelocity = newVelocity.ClampLength(maxVelocity);
|
||||||
|
}
|
||||||
body.ApplyForce((newVelocity - body.LinearVelocity) * Mass / (float)Timing.Step);
|
body.ApplyForce((newVelocity - body.LinearVelocity) * Mass / (float)Timing.Step);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,17 +759,19 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Vector2 dragForce = Vector2.Zero;
|
Vector2 dragForce = Vector2.Zero;
|
||||||
|
|
||||||
if (LinearVelocity.LengthSquared() > 0.00001f)
|
float speedSqr = LinearVelocity.LengthSquared();
|
||||||
|
if (speedSqr > 0.00001f)
|
||||||
{
|
{
|
||||||
//drag
|
//drag
|
||||||
Vector2 velDir = Vector2.Normalize(LinearVelocity);
|
float speed = (float)Math.Sqrt(speedSqr);
|
||||||
|
Vector2 velDir = LinearVelocity / speed;
|
||||||
|
|
||||||
float vel = LinearVelocity.Length() * 2.0f;
|
float vel = speed * 2.0f;
|
||||||
float drag = vel * vel * Math.Max(height + radius * 2, height);
|
float drag = vel * vel * Math.Max(height + radius * 2, height);
|
||||||
dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
|
dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyForce(dragForce + buoyancy);
|
ApplyForce(dragForce + buoyancy, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||||
ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
|
ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user