@@ -43,6 +43,8 @@ internal class DadUiController : KerbalMonoBehaviour
4343 Label TofsLabel ;
4444 // Tangent Velocity
4545 Label TvelLabel ;
46+ // Flight Controls Mode
47+ //Label CtrlLabel;
4648
4749 // Main display
4850 VisualElement Screen ;
@@ -61,6 +63,11 @@ internal class DadUiController : KerbalMonoBehaviour
6163 VisualElement RotationMarker ;
6264 VisualElement RotationMarkerSprite ;
6365
66+ // Tangent velocity marker
67+ VisualElement TvelMarker ;
68+ VisualElement TvelLine ;
69+ VisualElement TvelArrow ;
70+
6471 // No Target error screen
6572 VisualElement NoTargetScreen ;
6673
@@ -77,6 +84,12 @@ private void Update()
7784 return ;
7885 }
7986
87+ // Close UI if not controlling a vessel
88+ if ( Game ? . ViewController ? . GetActiveSimVessel ( true ) is null )
89+ {
90+ DockingAlignmentDisplayPlugin . Instance . ToggleButton ( false ) ;
91+ }
92+
8093 // Update GUI display status
8194 if ( GUIEnabled && DockingAlignmentDisplayPlugin . InterfaceEnabled )
8295 s_container . style . display = DisplayStyle . Flex ;
@@ -91,7 +104,14 @@ private void Update()
91104 _screen_height = Screen . resolvedStyle . height ;
92105
93106 // Update target data
94- target . Update ( Game ) ;
107+ target . Update ( ) ;
108+
109+ // Update flight controls mode indicator
110+ //if (Game?.ViewController?.GetActiveSimVessel(true) != null)
111+ //{
112+ // Vehicle.ActiveVesselVehicle.OnFlightControlsModeChange -= OnFlightControlsModeChanged;
113+ // Vehicle.ActiveVesselVehicle.OnFlightControlsModeChange += OnFlightControlsModeChanged;
114+ //}
95115
96116 if ( target . IsValid )
97117 {
@@ -102,6 +122,7 @@ private void Update()
102122 UpdateMetrics ( target . RelativePosition , target . RelativeVelocity , true ) ;
103123 UpdateAngleCrosshair ( target . RelativeOrientation , true ) ;
104124 UpdateRollIndicator ( target . RelativeRoll , true ) ;
125+ UpdateTvelIndicator ( target . RelativeVelocity , true ) ;
105126 }
106127 else
107128 {
@@ -112,6 +133,7 @@ private void Update()
112133 UpdateMetrics ( Vector3 . zero , Vector3 . zero , false ) ;
113134 UpdateAngleCrosshair ( Vector3 . zero , false ) ;
114135 UpdateRollIndicator ( 0 , false ) ;
136+ UpdateTvelIndicator ( Vector3 . zero , false ) ;
115137 }
116138 }
117139
@@ -163,6 +185,7 @@ private void InitElements()
163185 CvelLabel = s_container . Q < Label > ( "cvel" ) ;
164186 TofsLabel = s_container . Q < Label > ( "tofs" ) ;
165187 TvelLabel = s_container . Q < Label > ( "tvel" ) ;
188+ //CtrlLabel = s_container.Q<Label>("ctrl-mode");
166189
167190 // Main display
168191 Screen = s_container . Q < VisualElement > ( "screen" ) ;
@@ -183,13 +206,23 @@ private void InitElements()
183206 RotationMarker = s_container . Q < VisualElement > ( "rotation-marker" ) ;
184207 RotationMarkerSprite = s_container . Q < VisualElement > ( "rotation-marker-sprite" ) ;
185208
209+ // Tvel indicator
210+ TvelMarker = s_container . Q < VisualElement > ( "tvel-marker" ) ;
211+ TvelLine = s_container . Q < VisualElement > ( "tvel-line" ) ;
212+ TvelArrow = s_container . Q < VisualElement > ( "tvel-arrow" ) ;
213+
186214 // No Target error screen
187215 NoTargetScreen = s_container . Q < VisualElement > ( "no-target" ) ;
188216 NoTargetScreen . style . display = DisplayStyle . None ;
189217
190218 _initialized = true ;
191219 }
192220
221+ //private void OnFlightControlsModeChanged(FlightControlsMode mode)
222+ //{
223+ // CtrlLabel.text = "CTRL: " + (mode == FlightControlsMode.Docking ? "DOCKING" : "NORMAL");
224+ //}
225+
193226 /// <summary>
194227 /// Converts <c>value</c> to a 4-number string with 1 decimal point and correct unit prefix
195228 /// </summary>
@@ -281,6 +314,12 @@ private void UpdateAngleCrosshair(Vector3 relativeOrientation, bool validTarget)
281314 }
282315 }
283316
317+ /// <summary>
318+ /// Moves the rotation indicator arrow based on the relative rotation between the current vessel's docking port
319+ /// and the target docking port. The arrow is green is the angle is less that 5° and red otherwise.
320+ /// </summary>
321+ /// <param name="relativeRoll">Relative roll between the two docking ports</param>
322+ /// <param name="validTarget"></param>
284323 private void UpdateRollIndicator ( float relativeRoll , bool validTarget )
285324 {
286325 if ( validTarget )
@@ -309,6 +348,46 @@ private void UpdateRollIndicator(float relativeRoll, bool validTarget)
309348 }
310349 }
311350
351+ /// <summary>
352+ /// Moves the tangent velocity indicator arrow based on the relative velocity between the two crafts in the target's
353+ /// docking port parallel frame.
354+ /// </summary>
355+ /// <param name="relativeVel">Relative velocity in the target parallel frame</param>
356+ /// <param name="validTarget"></param>
357+ private void UpdateTvelIndicator ( Vector3 relativeVel , bool validTarget )
358+ {
359+ if ( validTarget )
360+ {
361+ // Display indicator
362+ TvelMarker . style . display = DisplayStyle . Flex ;
363+
364+ // Tangent velocity vector
365+ Vector2 tVel = new Vector2 ( relativeVel . x , - relativeVel . y ) ;
366+
367+ // Magnitude
368+ float mag = tVel . magnitude ;
369+
370+ // Display indicator if magnitude > 10cm/s
371+ // TvelMarker.style.display = mag > 0.1f ? DisplayStyle.Flex : DisplayStyle.None;
372+
373+ // Angle from vertical
374+ Vector2 upVec = new Vector2 ( 0 , 1 ) ;
375+ float angle = Vector2 . SignedAngle ( upVec , tVel ) ;
376+
377+ // Rotate indicator
378+ TvelMarker . transform . rotation = Quaternion . AngleAxis ( angle , Vector3 . forward ) ;
379+
380+ // Arrow length
381+ float screenMag = ( Mathf . Log10 ( Mathf . Clamp ( mag , 0.1f , 990f ) ) + 1 ) / 8 * ( _screen_height / 2 ) ;
382+ TvelLine . style . height = screenMag ;
383+ TvelArrow . style . bottom = screenMag - 5 ;
384+ }
385+ else
386+ {
387+ TvelMarker . style . display = DisplayStyle . None ;
388+ }
389+ }
390+
312391 /// <summary>
313392 /// Updates the numerical metrics that represent: course distance, course velocity, tangent offset and tangent velocity.
314393 /// </summary>
0 commit comments