Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
759 changes: 79 additions & 680 deletions Assets/Scenes/MainGame.unity

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Assets/Scripts/Core/Constants/GameplayConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ public static class GameplayConstants
/// </summary>
public const float ModuleDestroyedBelowPixelRatio = 0.15f;

public const float ChanceOfSpawningExplosionOnDetachingConnectionPoint = 0.1f;
public const float ChanceOfSpawningExplosionOnDetachingConnectionPoint = 0.3f;
}
}
3 changes: 2 additions & 1 deletion Assets/Scripts/Ships/AIShip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ protected override void ReadMovementInput()
{
_aiShipStateMachine.Tick(Time.deltaTime);
PendingForwardInput = 0f;
PendingHorizontalInput = 0f;
PendingTurnInput = 0f;
_pendingEnginesActive = false;

Expand All @@ -82,7 +83,7 @@ protected override void ApplyMovementPhysics()
return;
}

MarkEnginesActivity(ApplyEngineForces(PendingForwardInput, PendingTurnInput, Time.fixedDeltaTime, true));
MarkEnginesActivity(ApplyEngineForces(PendingForwardInput, 0, PendingTurnInput, Time.fixedDeltaTime, true));
}

private void ComputeNavigationInputs(Vector2 targetPosition)
Expand Down
9 changes: 5 additions & 4 deletions Assets/Scripts/Ships/Modules/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,22 +357,23 @@ private void DetachConnections(Module otherModule)
/// </summary>
public void DetachAllConnections()
{
SpawnExplosionsOnDetachment(_connectionPoints);

foreach (var otherModule in new List<Module>(_connections.Keys))
{
RemoveConnectionTo(otherModule);
if (otherModule) otherModule.RemoveConnectionTo(this);
}

SpawnExplosionsOnDetachment(_connectionPoints);

_connectionPoints.Clear();
}

private void SpawnExplosionsOnDetachment(Dictionary<Module, List<Vector2Int>> connectionPoints)
{
foreach (var worldPos in from connectionPoint in connectionPoints.AsValueEnumerable()
foreach (var worldPos in from allConnectionsPoints in connectionPoints.Values.AsValueEnumerable()
from worldPoint in allConnectionsPoints
where Random.value < GameplayConstants.ChanceOfSpawningExplosionOnDetachingConnectionPoint
select PixelatedRigidbody.LocalToWorldPoint(connectionPoint.Value[0]))
select PixelatedRigidbody.LocalToWorldPoint(worldPoint))
_effectsSpawner.SpawnExplosion(worldPos);
Comment thread
lmProgramming marked this conversation as resolved.
}

Expand Down
6 changes: 4 additions & 2 deletions Assets/Scripts/Ships/PlayerShip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ protected override void ReadMovementInput()
ToggleSas();

PendingForwardInput = Input.GetAxis("Vertical") * speedMultiplier;
PendingTurnInput = -Input.GetAxis("Horizontal") * rotationMultiplier;
PendingHorizontalInput = Input.GetAxis("Horizontal") * speedMultiplier;
PendingTurnInput = -Input.GetAxis("Roll") * rotationMultiplier;
}

protected override void ApplyMovementPhysics()
Expand All @@ -41,7 +42,8 @@ protected override void ApplyMovementPhysics()
return;
}

MarkEnginesActivity(ApplyEngineForces(PendingForwardInput, PendingTurnInput, Time.fixedDeltaTime,
MarkEnginesActivity(ApplyEngineForces(PendingForwardInput, PendingHorizontalInput, PendingTurnInput,
Time.fixedDeltaTime,
sasEnabled));
}

Expand Down
15 changes: 9 additions & 6 deletions Assets/Scripts/Ships/Ship.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public class Ship : MonoBehaviour, IShip


protected float PendingForwardInput;
protected float PendingHorizontalInput;
protected float PendingTurnInput;

[Inject]
Expand Down Expand Up @@ -390,10 +391,11 @@ protected void MarkEnginesActivity(bool active)
engine.SetActive(active);
}

protected bool ApplyEngineForces(float forwardInput, float turnInput, float deltaTime,
protected bool ApplyEngineForces(float forwardInput, float horizontalInput, float turnInput, float deltaTime,
bool sasEnabled = false)
{
forwardInput = Mathf.Clamp(forwardInput, -1f, 1f);
horizontalInput = Mathf.Clamp(horizontalInput, -1f, 1f);
turnInput = Mathf.Clamp(turnInput, -1f, 1f);

var selfRigidbody = CommandModule.PixelatedRigidbody?.Rigidbody;
Expand All @@ -407,7 +409,7 @@ protected bool ApplyEngineForces(float forwardInput, float turnInput, float delt
var centerOfMass = selfRigidbody.worldCenterOfMass;
var maxLeverArm = EngineDirectionSolver.GetMaxLeverArmLength(engines, centerOfMass);
var finalTurnInput = sasEnabled
? _sasTurnInputResolver.ResolveTurnInput(turnInput, forwardInput, selfRigidbody,
? _sasTurnInputResolver.ResolveTurnInput(turnInput, forwardInput, horizontalInput, selfRigidbody,
GetCurrentHeadingDegrees(), engines, forward, centerOfMass, maxLeverArm, GetSasSettings())
: turnInput;
var desiredDirectionPerEngine = new Vector2[engines.Count];
Expand All @@ -424,7 +426,7 @@ protected bool ApplyEngineForces(float forwardInput, float turnInput, float delt
}

var desiredDirection = EngineDirectionSolver.GetDesiredEngineDirection(
forward, centerOfMass, maxLeverArm, engine, forwardInput, finalTurnInput);
forward, centerOfMass, maxLeverArm, engine, forwardInput, horizontalInput, finalTurnInput);
desiredDirectionPerEngine[i] = desiredDirection;

if (desiredDirection.sqrMagnitude <= Mathf.Epsilon)
Expand All @@ -449,7 +451,7 @@ protected bool ApplyEngineForces(float forwardInput, float turnInput, float delt

var thrustRatios = ControlAllocator.AllocateControlInputs(engines, desiredDirectionPerEngine, centerOfMass,
forward,
forwardInput, finalTurnInput, maxLeverArm, GetControlAllocatorSettings());
forwardInput, horizontalInput, finalTurnInput, maxLeverArm, GetControlAllocatorSettings());

var anyForceApplied = false;

Expand Down Expand Up @@ -535,10 +537,11 @@ internal Vector2 GetForwardForTesting()
return CommandModule.Transform!.up;
}

internal void ApplyEngineForcesForTesting(float forwardInput, float turnInput, float deltaTime,
internal void ApplyEngineForcesForTesting(float forwardInput, float horizontalInput, float turnInput,
float deltaTime,
bool sasEnabled = false)
{
ApplyEngineForces(forwardInput, turnInput, deltaTime, sasEnabled);
ApplyEngineForces(forwardInput, horizontalInput, turnInput, deltaTime, sasEnabled);
}

internal void ConfigureAllocatorForTesting(bool isEnabled, int iterations = 24, float forceWeight = 1f,
Expand Down
13 changes: 7 additions & 6 deletions Assets/Scripts/Ships/Systems/Gimbal/ControlAllocator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ public class ControlAllocator
{
public static float[] AllocateControlInputs(IReadOnlyList<Engine> engines,
IReadOnlyList<Vector2> desiredDirections,
Vector2 centerOfMass, Vector2 forward, float forwardInput, float turnInput, float maxLeverArm,
Vector2 centerOfMass, Vector2 forward, float forwardInput, float horizontalInput, float turnInput,
float maxLeverArm,
ControlAllocatorSettings settings)
{
var thrustRatios = new float[engines.Count];
var requestedForceDirection = forwardInput >= 0f ? forward : -forward;
var requestedForceMagnitude = Mathf.Abs(forwardInput);
var shipRight = EngineDirectionSolver.GetShipRight(forward);
var requestedForce = forward * forwardInput + shipRight * horizontalInput;

var columns = new Vector3[engines.Count];
var hasAnyEffectiveColumn = false;
Expand Down Expand Up @@ -48,9 +49,9 @@ public static float[] AllocateControlInputs(IReadOnlyList<Engine> engines,

if (!hasAnyEffectiveColumn) return thrustRatios;

var targetForceMagnitude = requestedForceMagnitude * totalThrustCapacity * settings.ForceWeight;
var targetX = requestedForceDirection.x * targetForceMagnitude;
var targetY = requestedForceDirection.y * targetForceMagnitude;
var targetForceMagnitude = totalThrustCapacity * settings.ForceWeight;
var targetX = requestedForce.x * targetForceMagnitude;
var targetY = requestedForce.y * targetForceMagnitude;

var torqueScale = Mathf.Max(totalTorqueCapacity, Mathf.Max(1f, maxLeverArm));
var targetTorque = turnInput * torqueScale * settings.TorqueWeight;
Expand Down
15 changes: 11 additions & 4 deletions Assets/Scripts/Ships/Systems/Gimbal/EngineDirectionSolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,28 @@ public static float GetMaxLeverArmLength(IEnumerable<Engine> engines, Vector2 ce
return Mathf.Max(maxLeverArm, 0.01f);
}

public static Vector2 GetShipRight(Vector2 shipForward)
{
return new Vector2(shipForward.y, -shipForward.x);
}

public static Vector2 GetDesiredEngineDirection(Vector2 shipForward, Vector2 centerOfMass, float maxLeverArm,
Engine engine, float forwardInput, float turnInput)
Engine engine, float forwardInput, float horizontalInput, float turnInput)
{
var lever = engine.WorldThrustPoint - centerOfMass;
var rotationalDirection = new Vector2(-lever.y, lever.x) / maxLeverArm;
return shipForward * forwardInput + rotationalDirection * turnInput;
return shipForward * forwardInput + GetShipRight(shipForward) * horizontalInput +
rotationalDirection * turnInput;
}

public static float EstimateNetTorqueForTurnInput(IReadOnlyList<Engine> engines, Vector2 shipForward,
Vector2 centerOfMass, float maxLeverArm, float forwardInput, float turnInput)
Vector2 centerOfMass, float maxLeverArm, float forwardInput, float horizontalInput, float turnInput)
{
return (from engine in engines.AsValueEnumerable()
where !(engine.MaxThrust <= 0f)
let desiredDirection =
GetDesiredEngineDirection(shipForward, centerOfMass, maxLeverArm, engine, forwardInput, turnInput)
GetDesiredEngineDirection(shipForward, centerOfMass, maxLeverArm, engine, forwardInput,
horizontalInput, turnInput)
where !(desiredDirection.sqrMagnitude <= Mathf.Epsilon)
let thrust = Mathf.Clamp01(desiredDirection.magnitude) * engine.MaxThrust
let force = desiredDirection.normalized * thrust
Expand Down
25 changes: 14 additions & 11 deletions Assets/Scripts/Ships/Systems/Gimbal/SasTurnInputResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ public void CaptureDesiredHeading(float currentHeadingDegrees)
_hasDesiredHeading = true;
}

public float ResolveTurnInput(float requestedTurnInput, float forwardInput, Rigidbody2D selfRigidbody,
public float ResolveTurnInput(float requestedTurnInput, float forwardInput, float horizontalInput,
Rigidbody2D selfRigidbody,
float currentHeadingDegrees, IReadOnlyList<Engine> engines, Vector2 shipForward, Vector2 centerOfMass,
float maxLeverArm, in SasTurnInputSettings settings)
float maxLeverArm, SasTurnInputSettings settings)
{
UpdateDesiredHeadingOnTurnRelease(requestedTurnInput, currentHeadingDegrees, settings);

var headingHoldTurnInput = GetHeadingHoldTurnInput(requestedTurnInput, selfRigidbody, currentHeadingDegrees,
settings);
if (Mathf.Abs(requestedTurnInput) > settings.TurnReleaseThreshold ||
Mathf.Abs(forwardInput) <= Mathf.Epsilon)
(Mathf.Abs(forwardInput) <= Mathf.Epsilon && Mathf.Abs(horizontalInput) <= Mathf.Epsilon))
return headingHoldTurnInput;

var forwardCompensation = CalculateForwardThrustCompensationTurnInput(forwardInput, engines, shipForward,
var forwardCompensation = CalculateThrustCompensationTurnInput(forwardInput, horizontalInput, engines,
shipForward,
centerOfMass, maxLeverArm, settings);
var withForwardCompensation = headingHoldTurnInput +
forwardCompensation * settings.ForwardCompensationStrength;
Expand All @@ -37,7 +39,7 @@ public float ResolveTurnInput(float requestedTurnInput, float forwardInput, Rigi
}

private void UpdateDesiredHeadingOnTurnRelease(float requestedTurnInput, float currentHeadingDegrees,
in SasTurnInputSettings settings)
SasTurnInputSettings settings)
{
CaptureCurrentHeadingIfNeeded(currentHeadingDegrees);

Expand All @@ -49,7 +51,7 @@ private void UpdateDesiredHeadingOnTurnRelease(float requestedTurnInput, float c
}

private float GetHeadingHoldTurnInput(float requestedTurnInput, Rigidbody2D selfRigidbody,
float currentHeadingDegrees, in SasTurnInputSettings settings)
float currentHeadingDegrees, SasTurnInputSettings settings)
{
if (Mathf.Abs(requestedTurnInput) > settings.TurnReleaseThreshold)
return requestedTurnInput;
Expand All @@ -66,23 +68,24 @@ private float GetHeadingHoldTurnInput(float requestedTurnInput, Rigidbody2D self
return Mathf.Clamp(turnCorrection, -settings.MaxTurnInput, settings.MaxTurnInput);
}

private float CalculateForwardThrustCompensationTurnInput(float forwardInput, IReadOnlyList<Engine> engines,
Vector2 shipForward, Vector2 centerOfMass, float maxLeverArm, in SasTurnInputSettings settings)
private static float CalculateThrustCompensationTurnInput(float forwardInput, float horizontalInput,
IReadOnlyList<Engine> engines,
Vector2 shipForward, Vector2 centerOfMass, float maxLeverArm, SasTurnInputSettings settings)
{
if (engines.Count == 0)
return 0f;

const float sampleTurnInput = 0.2f;

var baselineTorque = EngineDirectionSolver.EstimateNetTorqueForTurnInput(engines, shipForward,
centerOfMass, maxLeverArm, forwardInput, 0f);
centerOfMass, maxLeverArm, forwardInput, horizontalInput, 0f);
if (Mathf.Abs(baselineTorque) <= 0.0001f)
return 0f;

var positiveSampleTorque = EngineDirectionSolver.EstimateNetTorqueForTurnInput(engines, shipForward,
centerOfMass, maxLeverArm, forwardInput, sampleTurnInput);
centerOfMass, maxLeverArm, forwardInput, horizontalInput, sampleTurnInput);
var negativeSampleTorque = EngineDirectionSolver.EstimateNetTorqueForTurnInput(engines, shipForward,
centerOfMass, maxLeverArm, forwardInput, -sampleTurnInput);
centerOfMass, maxLeverArm, forwardInput, horizontalInput, -sampleTurnInput);

var torqueSlope = (positiveSampleTorque - negativeSampleTorque) / (sampleTurnInput * 2f);
if (Mathf.Abs(torqueSlope) <= 0.0001f)
Expand Down
4 changes: 3 additions & 1 deletion Assets/Scripts/Ships/Tests/ModuleConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public IEnumerator UnrotatedModuleOnRight_ConnectsToCommandModule()
var command = shipGo.GetComponentInChildren<Command>();
var engine = shipGo.GetComponentInChildren<Engine>();

Container.InjectGameObject(shipGo);

return (ship, command, engine);
}

Expand Down Expand Up @@ -74,4 +76,4 @@ private static void AssertModulesConnected(Ship ship, Command command, Engine en
"Command module should have connection points to engine");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public class ModuleDestructionThresholdTests : ShipTestBase

var ship = ModuleFactory.WireShip<Ship>(shipGo, Container);

Container.InjectGameObject(shipGo);

return (ship, command, other);
}

Expand Down Expand Up @@ -104,4 +106,4 @@ public IEnumerator CommandModuleBelowPixelThreshold_DestroysShip()
Assert.IsTrue(shipGo == null, "Ship should be destroyed when its command module falls below the threshold");
}
}
}
}
2 changes: 2 additions & 0 deletions Assets/Scripts/Ships/Tests/ModuleJointLifecycleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class ModuleJointLifecycleTests : ShipTestBase

var ship = ModuleFactory.WireShip<Ship>(shipGo, Container);

Container.InjectGameObject(shipGo);

return (ship, command, other);
}

Expand Down
35 changes: 31 additions & 4 deletions Assets/Scripts/Ships/Tests/ShipControlAllocatorThrustTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public IEnumerator ForwardInput_OneRearEngine_UsesAtLeastNinetyPercentThrust()
yield return WaitForLifecycle();

shipWithEngines.Ship.ConfigureAllocatorForTesting(true);
shipWithEngines.Ship.ApplyEngineForcesForTesting(1f, 0f, 0.02f);
shipWithEngines.Ship.ApplyEngineForcesForTesting(1f, 0f, 0f, 0.02f);

Assert.That(shipWithEngines.Engines[0].CurrentThrustRatioForTesting, Is.GreaterThanOrEqualTo(0.9f));
}
Expand All @@ -58,7 +58,7 @@ public IEnumerator BackwardInput_BackwardFacingEngine_UsesAtLeastNinetyPercentTh
yield return WaitForLifecycle();

shipWithEngines.Ship.ConfigureAllocatorForTesting(true);
shipWithEngines.Ship.ApplyEngineForcesForTesting(-1f, 0f, 0.02f);
shipWithEngines.Ship.ApplyEngineForcesForTesting(-1f, 0f, 0f, 0.02f);

Assert.That(shipWithEngines.Engines[0].CurrentThrustRatioForTesting, Is.GreaterThanOrEqualTo(0.9f));
}
Expand All @@ -78,12 +78,37 @@ public IEnumerator ForwardInput_FiveHighThrustWingEngines_UsesAtLeastNinetyPerce
shipWithEngines.Ship.ConfigureAllocatorForTesting(true, 14, 1f,
0.4f, 0.02f);

shipWithEngines.Ship.ApplyEngineForcesForTesting(1f, 0f, 0.02f);
shipWithEngines.Ship.ApplyEngineForcesForTesting(1f, 0f, 0f, 0.02f);

foreach (var engine in shipWithEngines.Engines)
Assert.That(engine.CurrentThrustRatioForTesting, Is.GreaterThanOrEqualTo(0.9f));
}

[UnityTest]
public IEnumerator HorizontalInput_OneRearEngine_UsesAtLeastNinetyPercentThrust()
{
var shipWithEngines = CreateShipWithEngines(
new EngineSpec
{
LocalPosition = new Vector2(0f, -5f),
LocalRotationZ = 0f,
MaxThrust = 10f
},
new EngineSpec
{
LocalPosition = new Vector2(0f, 5f),
LocalRotationZ = 0f,
MaxThrust = 10f
});

yield return WaitForLifecycle();

shipWithEngines.Ship.ConfigureAllocatorForTesting(true);
shipWithEngines.Ship.ApplyEngineForcesForTesting(0f, 1f, 0f, 0.02f);

Assert.That(shipWithEngines.Engines[0].CurrentThrustRatioForTesting, Is.GreaterThanOrEqualTo(0.9f));
}

[UnityTest]
public IEnumerator BackwardInput_ForwardFacingEngine_UsesAtMostTenPercentThrust()
{
Expand All @@ -104,7 +129,7 @@ public IEnumerator BackwardInput_ForwardFacingEngine_UsesAtMostTenPercentThrust(
yield return WaitForLifecycle();

shipWithEngines.Ship.ConfigureAllocatorForTesting(true);
shipWithEngines.Ship.ApplyEngineForcesForTesting(-1f, 0f, 0.02f);
shipWithEngines.Ship.ApplyEngineForcesForTesting(-1f, 0f, 0f, 0.02f);

Assert.That(shipWithEngines.Engines[1].CurrentThrustRatioForTesting, Is.LessThanOrEqualTo(0.1f));
}
Expand All @@ -124,6 +149,8 @@ public IEnumerator BackwardInput_ForwardFacingEngine_UsesAtMostTenPercentThrust(

var ship = ModuleFactory.WireShip<ShipTestProxy>(shipGo, Container);

Container.InjectGameObject(shipGo);

return (ship, engines);
}
}
Expand Down
2 changes: 2 additions & 0 deletions Assets/Scripts/Ships/Tests/ShipCrewAssignmentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ private Ship CreateShipWithModules(params (int crewNeeded, CrewSkillType mainSki
config.crewNeeded, config.mainSkill);
}

Container.InjectGameObject(shipGo);

return ModuleFactory.WireShip<Ship>(shipGo, Container);
}

Expand Down
Loading
Loading