// ╔════════════════════════════════════════════════════════════════╗ // ║ Copyright © 2025 NWH Coding d.o.o. All rights reserved. ║ // ║ Licensed under Unity Asset Store Terms of Service: ║ // ║ https://unity.com/legal/as-terms ║ // ║ Use permitted only in compliance with the License. ║ // ║ Distributed "AS IS", without warranty of any kind. ║ // ╚════════════════════════════════════════════════════════════════╝ #region using System; using NWH.Common.Input; using UnityEngine; using UnityEngine.Events; #if UNITY_EDITOR using NWH.NUI; using NWH.DWP2.ShipController; using UnityEditor; #endif #endregion namespace NWH.DWP2.ShipController { /// /// Manages ship input by retrieving values from active ShipInputProviders and storing them in ShipInputStates. /// Automatically polls all registered input providers and combines their inputs. /// Can be disabled for manual input control via scripting or AI. /// [Serializable] public class ShipInputHandler { /// /// When enabled input will be auto-retrieved from the InputProviders present in the scene. /// Disable to manualy set the input through external scripts, i.e. AI controller. /// [Tooltip( "When enabled input will be auto-retrieved from the InputProviders present in the scene.\r\nDisable to manualy set the input through external scripts, i.e. AI controller.")] public bool autoSetInput = true; /// /// Callback invoked after input is processed each frame. /// Use this to modify input values programmatically before they are used. /// public UnityEvent modifyInputCallback = new(); /// /// All the input states of the vehicle. Can be used to set input through scripting or copy the inputs /// over from other vehicle, such as truck to trailer. /// [Tooltip( "All the input states of the vehicle. Can be used to set input through scripting or copy the inputs\r\nover from other vehicle, such as truck to trailer.")] public ShipInputStates states; /// /// Primary throttle input from -1 (full reverse) to 1 (full forward). /// public float Throttle { get { return states.throttle; } set { states.throttle = Mathf.Clamp(value, -1f, 1f); } } /// /// Secondary throttle for independent engine control. /// public float Throttle2 { get { return states.throttle2; } set { states.throttle2 = Mathf.Clamp(value, -1f, 1f); } } /// /// Tertiary throttle for independent engine control. /// public float Throttle3 { get { return states.throttle3; } set { states.throttle3 = Mathf.Clamp(value, -1f, 1f); } } /// /// Quaternary throttle for independent engine control. /// public float Throttle4 { get { return states.throttle4; } set { states.throttle4 = Mathf.Clamp(value, -1f, 1f); } } /// /// Steering input from -1 (port/left) to 1 (starboard/right). /// public float Steering { get { return states.steering; } set { states.steering = Mathf.Clamp(value, -1f, 1f); } } /// /// Stern thruster input from -1 to 1. /// public float SternThruster { get { return states.sternThruster; } set { states.sternThruster = Mathf.Clamp(value, -1f, 1f); } } /// /// Bow thruster input from -1 to 1. /// public float BowThruster { get { return states.bowThruster; } set { states.bowThruster = Mathf.Clamp(value, -1f, 1f); } } /// /// Submarine depth control from -1 (surface) to 1 (dive). /// public float SubmarineDepth { get { return states.submarineDepth; } set { states.submarineDepth = Mathf.Clamp01(value); } } /// /// Anchor toggle state. True for one frame when anchor input is pressed. /// public bool Anchor { get { return states.anchor; } set { states.anchor = value; } } /// /// Engine start/stop toggle state. True for one frame when toggle input is pressed. /// public bool EngineStartStop { get { return states.engineStartStop; } set { states.engineStartStop = value; } } /// /// Sail rotation input for sailing vessels. /// public float RotateSail { get { return states.rotateSail; } set { states.rotateSail = value; } } /// /// Updates all input values from registered input providers. /// Called automatically by AdvancedShipController. /// public void Update() { if (!autoSetInput) { return; } Steering = InputProvider.CombinedInput(i => i.Steering()); Throttle = InputProvider.CombinedInput(i => i.Throttle()); Throttle2 = InputProvider.CombinedInput(i => i.Throttle2()); Throttle3 = InputProvider.CombinedInput(i => i.Throttle3()); Throttle4 = InputProvider.CombinedInput(i => i.Throttle4()); BowThruster = InputProvider.CombinedInput(i => i.BowThruster()); SternThruster = InputProvider.CombinedInput(i => i.SternThruster()); SubmarineDepth = InputProvider.CombinedInput(i => i.SubmarineDepth()); RotateSail = InputProvider.CombinedInput(i => i.RotateSail()); EngineStartStop |= InputProvider.CombinedInput(i => i.EngineStartStop()); Anchor |= InputProvider.CombinedInput(i => i.Anchor()); modifyInputCallback.Invoke(); } } } #if UNITY_EDITOR namespace NWH.DWP2.WaterObjects { /// /// Property drawer for Input. /// [CustomPropertyDrawer(typeof(ShipInputHandler))] public class ShipInputHandlerDrawer : NUIPropertyDrawer { public override bool OnNUI(Rect position, SerializedProperty property, GUIContent label) { if (!base.OnNUI(position, property, label)) { return false; } drawer.Field("autoSetInput"); drawer.Field("states"); drawer.EndProperty(); return true; } } } #endif