diff --git a/TrimIndicator/TrimIndicatorAddon.cs b/TrimIndicator/TrimIndicatorAddon.cs index 1cfc754..98cbb45 100644 --- a/TrimIndicator/TrimIndicatorAddon.cs +++ b/TrimIndicator/TrimIndicatorAddon.cs @@ -1,63 +1,62 @@ using System; -using System.Collections.Generic; -using System.Linq; using UnityEngine; namespace TrimIndicator { - [KSPAddon(KSPAddon.Startup.Flight, once: false)] - public class TrimIndicatorAddon : MonoBehaviour - { - void Start() - { - LoadSettings(); - - var gaugesObject = FindObjectOfType().gameObject; - - _pitchTrimLabel = new TrimLabel(gaugesObject, new Vector3(34F, -15.5F), isVertical: true); - _yawTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -63.5F), isVertical: false); - _rollTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -25F), isVertical: false); - - if(_showWheelTrim) - { - _wheelThrottleTrimLabel = new TrimLabel(gaugesObject, new Vector3(62F, -15.5F), isVertical: true); - _wheelSteerTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -76F), isVertical: false); - } - } - - void Update() - { - var ctrlState = FlightInputHandler.state; - - _pitchTrimLabel?.SetValue(ctrlState?.pitchTrim ?? 0); - _yawTrimLabel?.SetValue(ctrlState?.yawTrim ?? 0); - _rollTrimLabel?.SetValue(ctrlState?.rollTrim ?? 0); - _wheelThrottleTrimLabel?.SetValue(ctrlState?.wheelThrottleTrim ?? 0); - _wheelSteerTrimLabel?.SetValue(-(ctrlState?.wheelSteerTrim ?? 0)); - } - - void LoadSettings() - { - try - { - var settings = ConfigNode.Load(SettingsFilePath); - settings.TryGetValue("ShowWheelTrim", ref _showWheelTrim); - } - catch(Exception exception) - { - print($"{nameof(TrimIndicator)}: Cannot load settings. {exception}"); - } - } - - bool _showWheelTrim; - - TrimLabel _pitchTrimLabel; - TrimLabel _yawTrimLabel; - TrimLabel _rollTrimLabel; - TrimLabel _wheelThrottleTrimLabel; - TrimLabel _wheelSteerTrimLabel; - - static readonly string SettingsFilePath = - $"{KSPUtil.ApplicationRootPath}GameData/{nameof(TrimIndicator)}/{nameof(TrimIndicator)}.settings"; - } + [KSPAddon(KSPAddon.Startup.Flight, once: false)] + public class TrimIndicatorAddon : MonoBehaviour + { + void Start() + { + string SettingsFilePath = + $"{KSPUtil.ApplicationRootPath}GameData/{nameof(TrimIndicator)}/{nameof(TrimIndicator)}.settings"; + LoadSettings(SettingsFilePath); + + var gaugesObject = FindObjectOfType().gameObject; + + _pitchTrimLabel = new TrimLabel(gaugesObject, new Vector3(34F, -15.5F), isVertical: true); + _yawTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -63.5F), isVertical: false); + _rollTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -25F), isVertical: false); + + if (_showWheelTrim) + { + _wheelThrottleTrimLabel = new TrimLabel(gaugesObject, new Vector3(62F, -15.5F), isVertical: true); + _wheelSteerTrimLabel = new TrimLabel(gaugesObject, new Vector3(-24F, -76F), isVertical: false); + } + } + + void Update() + { + var ctrlState = FlightInputHandler.state; + + _pitchTrimLabel?.SetValue(ctrlState?.pitchTrim ?? 0); + _yawTrimLabel?.SetValue(ctrlState?.yawTrim ?? 0); + _rollTrimLabel?.SetValue(ctrlState?.rollTrim ?? 0); + _wheelThrottleTrimLabel?.SetValue(ctrlState?.wheelThrottleTrim ?? 0); + _wheelSteerTrimLabel?.SetValue(-(ctrlState?.wheelSteerTrim ?? 0)); + } + + void LoadSettings(string path) + { + try + { + var settings = ConfigNode.Load(path); + settings.TryGetValue("ShowWheelTrim", ref _showWheelTrim); + } + catch (Exception exception) + { + print($"{nameof(TrimIndicator)}: Cannot load settings. {exception}"); + } + } + + bool _showWheelTrim; + + TrimLabel _pitchTrimLabel; + TrimLabel _yawTrimLabel; + TrimLabel _rollTrimLabel; + TrimLabel _wheelThrottleTrimLabel; + TrimLabel _wheelSteerTrimLabel; + + + } } diff --git a/TrimIndicator/TrimLabel.cs b/TrimIndicator/TrimLabel.cs index 5254fe3..24f4956 100644 --- a/TrimIndicator/TrimLabel.cs +++ b/TrimIndicator/TrimLabel.cs @@ -7,106 +7,106 @@ namespace TrimIndicator { - class TrimLabel - { - public TrimLabel(GameObject parent, Vector3 location, bool isVertical) - { - _sliderDirection = isVertical ? Vector3.up : Vector3.right; - _sliderAmplitude = isVertical ? VerticalSliderAmplitude : HorizontalSliderAmplitude; - var textAlignment = isVertical ? TextAlignmentOptions.BaselineLeft : TextAlignmentOptions.Baseline; - - var baseObject = MakeDummyObject(parent, location); - _slider = MakeDummyObject(baseObject); - - _textMeshes = new[] - { - MakeTextMesh(_slider, -OutlineWidth * _sliderDirection, BackgroundColor, textAlignment), - MakeTextMesh(_slider, +OutlineWidth * _sliderDirection, BackgroundColor, textAlignment), - MakeTextMesh(_slider, Vector3.zero, ForegroundColor, textAlignment), - }; - } - - public void SetValue(float value) - { - if(value != _lastValue) - { - int steps = (int)Math.Round(value / Step); - string text = steps != 0 - ? (steps < 0 ? "−" : "+") + Math.Abs(steps).ToString(CultureInfo.InvariantCulture) - : string.Empty; - - _slider.transform.localPosition = _sliderAmplitude * GetSliderPosition(value) * _sliderDirection; - - foreach(var textMesh in _textMeshes) - textMesh.text = text; - - _lastValue = value; - } - } - - readonly Vector3 _sliderDirection; - readonly float _sliderAmplitude; - readonly GameObject _slider; - readonly IEnumerable _textMeshes; - - float _lastValue; - - - static GameObject MakeObject(GameObject parent, Vector3 relativeLocation) - { - var gameObject = new GameObject { layer = LayerMask.NameToLayer("UI") }; - gameObject.transform.SetParent(parent.transform, false); - gameObject.transform.localPosition = relativeLocation; - return gameObject; - } - - static GameObject MakeDummyObject(GameObject parent, Vector3 relativeLocation = default(Vector3)) - { - var gameObject = MakeObject(parent, relativeLocation); - // Just an empty text mesh. Consider replacing by something more adequate - var textMesh = gameObject.AddComponent(); - textMesh.autoSizeTextContainer = true; - return gameObject; - } - - static TextMeshProUGUI MakeTextMesh(GameObject parent, Vector3 relativeLocation, Color color, TextAlignmentOptions alignment) - { - var gameObject = MakeObject(parent, relativeLocation); - - var textMesh = gameObject.AddComponent(); - textMesh.autoSizeTextContainer = true; - textMesh.isOverlay = true; - textMesh.enableWordWrapping = false; - textMesh.alignment = alignment; - textMesh.font = Font; - textMesh.fontMaterial = FontMaterial; - textMesh.fontSize = FontSize; - textMesh.color = color; - - return textMesh; - } - - static float GetSliderPosition(float value) => - (float)(Math.Atan(value * SliderPositionSteepness) / Math.Atan(SliderPositionSteepness)); - - static TMP_FontAsset _font; - static TMP_FontAsset Font => _font ??= - Resources.LoadAll("Fonts") - .FirstOrDefault(f => f.name == "Calibri SDF"); - - static Material _fontMaterial; - static Material FontMaterial => _fontMaterial ??= - Resources.LoadAll("Fonts") - .FirstOrDefault(f => f.name == "Calibri SDF Material"); - - static readonly Color BackgroundColor = new Color(0.235F, 0.274F, 0.310F); // #3C464F - static readonly Color ForegroundColor = new Color(0.827F, 0.827F, 0.827F); // #D3D3D3 - const float FontSize = 17F; - const float OutlineWidth = 1.5F; - const float HorizontalSliderAmplitude = 39F; - const float VerticalSliderAmplitude = 49F; - const double SliderPositionSteepness = 20; - - const float Step = 0.002F; - } + class TrimLabel + { + public TrimLabel(GameObject parent, Vector3 location, bool isVertical) + { + _sliderDirection = isVertical ? Vector3.up : Vector3.right; + _sliderAmplitude = isVertical ? VerticalSliderAmplitude : HorizontalSliderAmplitude; + var textAlignment = isVertical ? TextAlignmentOptions.BaselineLeft : TextAlignmentOptions.Baseline; + + var baseObject = MakeDummyObject(parent, location); + _slider = MakeDummyObject(baseObject); + + _textMeshes = new[] + { + MakeTextMesh(_slider, -OutlineWidth * _sliderDirection, BackgroundColor, textAlignment), + MakeTextMesh(_slider, +OutlineWidth * _sliderDirection, BackgroundColor, textAlignment), + MakeTextMesh(_slider, Vector3.zero, ForegroundColor, textAlignment), + }; + } + + public void SetValue(float value) + { + if (value != _lastValue) + { + int steps = (int)Math.Round(value / Step); + string text = steps != 0 + ? (steps < 0 ? "−" : "+") + Math.Abs(steps).ToString(CultureInfo.InvariantCulture) + : string.Empty; + + _slider.transform.localPosition = _sliderAmplitude * GetSliderPosition(value) * _sliderDirection; + + foreach (var textMesh in _textMeshes) + textMesh.text = text; + + _lastValue = value; + } + } + + readonly Vector3 _sliderDirection; + readonly float _sliderAmplitude; + readonly GameObject _slider; + readonly IEnumerable _textMeshes; + + float _lastValue; + + + static GameObject MakeObject(GameObject parent, Vector3 relativeLocation) + { + var gameObject = new GameObject { layer = LayerMask.NameToLayer("UI") }; + gameObject.transform.SetParent(parent.transform, false); + gameObject.transform.localPosition = relativeLocation; + return gameObject; + } + + static GameObject MakeDummyObject(GameObject parent, Vector3 relativeLocation = default(Vector3)) + { + var gameObject = MakeObject(parent, relativeLocation); + // Just an empty text mesh. Consider replacing by something more adequate + var textMesh = gameObject.AddComponent(); + textMesh.autoSizeTextContainer = true; + return gameObject; + } + + static TextMeshProUGUI MakeTextMesh(GameObject parent, Vector3 relativeLocation, Color color, TextAlignmentOptions alignment) + { + var gameObject = MakeObject(parent, relativeLocation); + + var textMesh = gameObject.AddComponent(); + textMesh.autoSizeTextContainer = true; + textMesh.isOverlay = true; + textMesh.enableWordWrapping = false; + textMesh.alignment = alignment; + textMesh.font = Font; + textMesh.fontMaterial = FontMaterial; + textMesh.fontSize = FontSize; + textMesh.color = color; + + return textMesh; + } + + static float GetSliderPosition(float value) => + (float)(Math.Atan(value * SliderPositionSteepness) / Math.Atan(SliderPositionSteepness)); + + static TMP_FontAsset _font; + static TMP_FontAsset Font => _font ??= + Resources.LoadAll("Fonts") + .FirstOrDefault(f => f.name == "Calibri SDF"); + + static Material _fontMaterial; + static Material FontMaterial => _fontMaterial ??= + Resources.LoadAll("Fonts") + .FirstOrDefault(f => f.name == "Calibri SDF Material"); + + static readonly Color BackgroundColor = new Color(0.235F, 0.274F, 0.310F); // #3C464F + static readonly Color ForegroundColor = new Color(0.827F, 0.827F, 0.827F); // #D3D3D3 + const float FontSize = 17F; + const float OutlineWidth = 1.5F; + const float HorizontalSliderAmplitude = 39F; + const float VerticalSliderAmplitude = 49F; + const double SliderPositionSteepness = 20; + + const float Step = 0.002F; + } }