Skip to content

Commit 12d3c9c

Browse files
authored
Rework collider disabling in RSSRunwayFix (#291)
Previous implementation caused severe freezes when coming off the rails.
1 parent 03dd9fd commit 12d3c9c

2 files changed

Lines changed: 63 additions & 80 deletions

File tree

Source/GUI.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ private void ShowGUI(int windowID)
140140

141141
GUILayout.Label("RSSRunwayFix");
142142

143+
GUILayout.BeginHorizontal();
144+
GUILayout.Label("collidersDisabled: ");
145+
GUILayout.Label(RSSRunwayFix.Instance.collidersDisabled.ToString(), GUILayout.ExpandWidth(false));
146+
GUILayout.EndHorizontal();
147+
143148
GUILayout.BeginHorizontal();
144149
GUILayout.Label("isOnRunway: ");
145150
GUILayout.Label(RSSRunwayFix.Instance.isOnRunway.ToString(), GUILayout.ExpandWidth(false));

Source/RSSRunwayFix.cs

Lines changed: 58 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections;
22
using UnityEngine;
3+
using static RunwayCollisionHandler;
34

45
namespace RealSolarSystem
56
{
@@ -22,16 +23,12 @@ public class RSSRunwayFix : MonoBehaviour
2223
internal bool isOnRunway = false;
2324
internal string lastHitColliderName;
2425

26+
internal bool collidersDisabled = false;
2527
private bool waiting = false;
2628
private IEnumerator waitCoro = null;
2729
private bool coroComplete = false;
2830

29-
private Vector3 down;
30-
31-
private string[] collidersToFix =
32-
{
33-
"End09", "Section4", "Section3", "Section2", "Section1", "End27"
34-
};
31+
private Coroutine _sectionsLoadRoutine;
3532

3633
public static RSSRunwayFix Instance { get; private set; } = null;
3734

@@ -46,46 +43,51 @@ public void Awake()
4643

4744
public void Start()
4845
{
49-
PrintDebug("Start");
50-
5146
foreach (ConfigNode n in GameDatabase.Instance.GetConfigNodes("RSSRUNWAYFIX"))
5247
{
5348
if (bool.TryParse(n.GetValue("debug"), out bool bTemp))
5449
{
5550
debug = bTemp;
5651
}
52+
5753
if (float.TryParse(n.GetValue("holdThreshold"), out float fTemp))
5854
{
5955
holdThreshold = fTemp;
6056
}
6157
}
6258

63-
GameEvents.onVesselGoOffRails.Add (OnVesselGoOffRails);
64-
GameEvents.onVesselGoOnRails.Add (OnVesselGoOnRails);
65-
GameEvents.onVesselSwitching.Add (OnVesselSwitching);
66-
GameEvents.onVesselSituationChange.Add (OnVesselSituationChange);
67-
68-
//GameEvents.onFloatingOriginShift.Add(onFloatingOriginShift);
59+
GameEvents.onVesselGoOffRails.Add(OnVesselGoOffRails);
60+
GameEvents.onVesselGoOnRails.Add(OnVesselGoOnRails);
61+
GameEvents.onVesselSwitching.Add(OnVesselSwitching);
62+
GameEvents.onVesselSituationChange.Add(OnVesselSituationChange);
63+
DestructibleBuilding.OnLoaded.Add(OnSectionLoaded);
6964
}
7065

7166
public void OnDestroy()
7267
{
73-
PrintDebug("OnDestroy");
74-
GameEvents.onVesselGoOffRails.Remove (OnVesselGoOffRails);
75-
GameEvents.onVesselGoOnRails.Remove (OnVesselGoOnRails);
76-
GameEvents.onVesselSwitching.Remove (OnVesselSwitching);
68+
GameEvents.onVesselGoOffRails.Remove(OnVesselGoOffRails);
69+
GameEvents.onVesselGoOnRails.Remove(OnVesselGoOnRails);
70+
GameEvents.onVesselSwitching.Remove(OnVesselSwitching);
7771
GameEvents.onVesselSituationChange.Remove(OnVesselSituationChange);
78-
79-
//GameEvents.onFloatingOriginShift.Remove(onFloatingOriginShift);
72+
DestructibleBuilding.OnLoaded.Remove(OnSectionLoaded);
8073
}
8174

82-
public void OnFloatingOriginShift(Vector3d v0, Vector3d v1)
75+
private void OnSectionLoaded(DestructibleBuilding data)
8376
{
84-
if (!hold)
77+
// At the end of the frame, KSP will fire this event for every destructible KSC prop.
78+
// We wait until the next frame so that all of the runway sections are guaranteed to be loaded.
79+
if (!collidersDisabled && _sectionsLoadRoutine == null)
8580
{
86-
return;
81+
_sectionsLoadRoutine = StartCoroutine(SectionsLoadRoutine());
8782
}
88-
if (debug) PrintDebug($"RSSRWF: v0: {v0}, v1: {v1}, threshold: {FloatingOrigin.fetch.threshold}");
83+
}
84+
85+
private IEnumerator SectionsLoadRoutine()
86+
{
87+
yield return null;
88+
89+
TryDisableColliders();
90+
_sectionsLoadRoutine = null;
8991
}
9092

9193
public void OnVesselGoOnRails(Vessel v)
@@ -97,25 +99,19 @@ public void OnVesselGoOnRails(Vessel v)
9799

98100
public void OnVesselGoOffRails(Vessel v)
99101
{
100-
PrintDebug("started");
101-
102102
originalThreshold = FloatingOrigin.fetch.threshold;
103103
originalThresholdSqr = FloatingOrigin.fetch.thresholdSqr;
104104

105105
if (debug) PrintDebug($"original threshold={originalThreshold}");
106106
holdThresholdSqr = holdThreshold * holdThreshold;
107107

108-
GameObject end09 = GameObject.Find(collidersToFix[0]);
109-
if (end09 == null)
108+
if (!collidersDisabled)
110109
{
111-
PrintDebug("no end09 found");
110+
if (debug) PrintDebug("colliders not disabled yet");
112111
hold = false;
113112
return;
114113
}
115114

116-
//combine(end09.transform.parent.gameObject);
117-
DisableColliders();
118-
GetDownwardVector();
119115
hold = true;
120116
waiting = false;
121117
}
@@ -128,14 +124,13 @@ public void OnVesselSwitching(Vessel from, Vessel to)
128124
return;
129125
}
130126

131-
GetDownwardVector();
132127
waiting = false;
133128
}
134129

135-
private void GetDownwardVector()
130+
private Vector3 GetDownwardVector()
136131
{
137132
Vessel v = FlightGlobals.ActiveVessel;
138-
down = (v.CoM - v.mainBody.transform.position).normalized * -1;
133+
return (v.CoM - v.mainBody.transform.position).normalized * -1;
139134
}
140135

141136
public void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel.Situations> data)
@@ -146,19 +141,19 @@ public void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel
146141
}
147142

148143
hold = data.to == Vessel.Situations.LANDED;
149-
PrintDebug($"vessel: {data.host.vesselName}, situation: {data.to}, hold: {hold}");
144+
if (debug) PrintDebug($"vessel: {data.host.vesselName}, situation: {data.to}, hold: {hold}");
150145

151146
if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0)
152147
{
153-
PrintDebug($"coro: {waitCoro}, complete: {coroComplete}");
148+
if (debug) PrintDebug($"coro: {waitCoro}, complete: {coroComplete}");
154149
if (waitCoro != null && !coroComplete)
155150
{
156-
PrintDebug("stopping coro");
151+
if (debug) PrintDebug("stopping coro");
157152
StopCoroutine(waitCoro);
158153
}
159154

160155
waitCoro = RestoreThreshold();
161-
PrintDebug($"created new coro: {waitCoro}");
156+
if (debug) PrintDebug($"created new coro: {waitCoro}");
162157

163158
coroComplete = false;
164159
StartCoroutine(waitCoro);
@@ -174,17 +169,18 @@ private IEnumerator RestoreThreshold()
174169
waiting = true;
175170
yield return new WaitForSeconds(5);
176171
waiting = false;
177-
PrintDebug("waiting is over");
172+
if (debug) PrintDebug("waiting is over");
178173
}
179174

180175
// Check again as situation could have changed
181-
if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0) {
176+
if (!hold && FloatingOrigin.fetch.threshold > originalThreshold && originalThreshold > 0)
177+
{
182178
if (debug) PrintDebug($"Restoring original thresholds ({FloatingOrigin.fetch.threshold} > {originalThreshold}), "+
183179
$"alt={FlightGlobals.ActiveVessel.radarAltitude}");
184180
FloatingOrigin.fetch.threshold = originalThreshold;
185181
FloatingOrigin.fetch.thresholdSqr = originalThresholdSqr;
186182
}
187-
PrintDebug("coro finished");
183+
if (debug) PrintDebug("coro finished");
188184
coroComplete = true;
189185
}
190186

@@ -228,13 +224,12 @@ private bool CheckRunway()
228224
}
229225

230226
Vessel v = FlightGlobals.ActiveVessel;
231-
if (v.situation != Vessel.Situations.LANDED && v.situation != Vessel.Situations.PRELAUNCH)
227+
if (v == null || (v.situation != Vessel.Situations.LANDED && v.situation != Vessel.Situations.PRELAUNCH))
232228
{
233229
return false;
234230
}
235-
236-
GetDownwardVector();
237231

232+
Vector3 down = GetDownwardVector();
238233
bool hit = Physics.Raycast(v.transform.position, down, out RaycastHit raycastHit, 100, layerMask);
239234
if (!hit)
240235
{
@@ -243,17 +238,12 @@ private bool CheckRunway()
243238

244239
lastHitColliderName = raycastHit.collider.gameObject.name;
245240
//if (debug) printDebug($"hit collider: {colliderName}");
246-
if (lastHitColliderName != "runway_collider")
247-
{
248-
return false;
249-
}
250241

251-
return true;
242+
return lastHitColliderName == "runway_collider";
252243
}
253244

254245
internal void PrintDebug(string message)
255246
{
256-
257247
if (!debug) return;
258248

259249
var trace = new System.Diagnostics.StackTrace();
@@ -262,38 +252,26 @@ internal void PrintDebug(string message)
262252
Debug.Log($"[RealSolarSystem] {caller}:{line}: {message}");
263253
}
264254

265-
private void DisableColliders()
255+
private void TryDisableColliders()
266256
{
267-
foreach (string c in collidersToFix)
257+
// Once disabled, the colliders will stay disabled
258+
if (collidersDisabled) return;
259+
260+
var rwHandler = FindObjectOfType<RunwayCollisionHandler>();
261+
if (rwHandler == null)
268262
{
269-
bool notFound = true;
270-
foreach (GameObject o in Resources.FindObjectsOfTypeAll<GameObject>())
271-
{
272-
if (o.name != c)
273-
continue;
274-
275-
notFound = false;
276-
if (!o.activeInHierarchy)
277-
{
278-
if (debug) PrintDebug($"{o.name} is not active, skipping");
279-
continue;
280-
}
281-
282-
MeshCollider cl = o.GetComponentInChildren<MeshCollider>();
283-
if (cl == null)
284-
{
285-
if (debug) PrintDebug($" No mesh collider in {c}");
286-
continue;
287-
}
288-
if (debug) PrintDebug($" disabling {cl.name}");
289-
cl.enabled = false;
290-
}
291-
if (notFound)
292-
{
293-
if (debug) PrintDebug($" Object {c} not found, skipping");
294-
continue;
295-
}
263+
if (debug) PrintDebug("rwHandler is null");
264+
return;
296265
}
266+
267+
foreach (RunwaySection section in rwHandler.runwaySections)
268+
{
269+
Collider sc = section.sectionCollider;
270+
sc.enabled = false;
297271
}
272+
273+
collidersDisabled = true;
274+
if (debug) PrintDebug("disabled runway colliders");
275+
}
298276
}
299277
}

0 commit comments

Comments
 (0)