namespace VRTK.Prefabs.Locomotion.Movement.AxesToVector3 { using UnityEngine; using Malimbe.XmlDocumentationAttribute; using Malimbe.PropertySerializationAttribute; using Malimbe.BehaviourStateRequirementMethod; using Zinnia.Action; using Zinnia.Extension; using Zinnia.Process; using Zinnia.Process.Moment; using Zinnia.Data.Attribute; using Zinnia.Data.Type.Transformation.Aggregation; /// /// Sets up the AxisSlide prefab based on the provided settings and implements the logic to allow moving an object via input from two axes. /// public class AxesToVector3Processor : MonoBehaviour, IProcessable { #region Facade Settings /// /// The public interface facade. /// [Serialized] [field: Header("Facade Settings"), DocumentedByXml, Restricted] public AxesToVector3Facade Facade { get; protected set; } #endregion #region Axis Data Settings /// /// The current axis data to use when processing movement. /// [Serialized] [field: Header("Axis Data Settings"), DocumentedByXml] public Vector3 CurrentAxisData { get; set; } #endregion #region Reference Settings /// /// The lateral to map to. /// [Serialized] [field: Header("Reference Settings"), DocumentedByXml, Restricted] public FloatAction LateralAxis { get; protected set; } /// /// The longitudinal to map to. /// [Serialized] [field: DocumentedByXml, Restricted] public FloatAction LongitudinalAxis { get; protected set; } /// /// The multiplier that operates on the final to modify the speed. /// [Serialized] [field: DocumentedByXml, Restricted] public Vector3Multiplier SpeedMultiplier { get; protected set; } /// /// The multiplier to use as the input mask to limit the forward direction. /// [Serialized] [field: DocumentedByXml, Restricted] public Vector3Multiplier InputMask { get; protected set; } /// /// The GameObject that contains the incremental axis logic. /// [Serialized] [field: DocumentedByXml, Restricted] public GameObject IncrementalAxis { get; protected set; } /// /// The GameObject that contains the directional axis logic. /// [Serialized] [field: DocumentedByXml, Restricted] public GameObject DirectionalAxis { get; protected set; } /// /// The MomentProcessor for processing the axis logic. /// [Serialized] [field: DocumentedByXml, Restricted] public MomentProcessor MomentProcessor { get; protected set; } #endregion /// /// The current calculated movement. /// public Vector3 CurrentMovement { get; protected set; } /// /// Emits the Converted event for the last calculated . /// [RequiresBehaviourState] public virtual void Process() { Vector3 axisDirection = Facade.SourceOfForwardDirection != null ? ApplyForwardSourceToAxis(CurrentAxisData) : CurrentAxisData; float multiplier = Facade.AxisUsageType == AxesToVector3Facade.AxisUsage.Incremental ? (Time.inFixedTimeStep ? Time.fixedDeltaTime : Time.deltaTime) : 1f; CurrentMovement = InputMask.Transform(axisDirection) * multiplier; Facade.Processed?.Invoke(CurrentMovement); } /// /// Configures the speed multipliers. /// public virtual void ConfigureMultipliers() { SpeedMultiplier.RunWhenActiveAndEnabled(() => SpeedMultiplier.SetComponentX(Facade.LateralSpeedMultiplier, 1)); SpeedMultiplier.RunWhenActiveAndEnabled(() => SpeedMultiplier.SetComponentZ(Facade.LongitudinalSpeedMultiplier, 1)); SpeedMultiplier.RunWhenActiveAndEnabled(() => SpeedMultiplier.Collection.CurrentIndex = 0); } /// /// Configures the axis sources. /// /// Whether to only clear the existing sources and not add new ones. public virtual void ConfigureAxisSources(bool clearOnly = false) { if (LateralAxis != null) { LateralAxis.RunWhenActiveAndEnabled(() => LateralAxis.ClearSources()); if (!clearOnly && Facade.LateralAxis != null) { LateralAxis.RunWhenActiveAndEnabled(() => LateralAxis.AddSource(Facade.LateralAxis)); } } if (LongitudinalAxis != null) { LongitudinalAxis.RunWhenActiveAndEnabled(() => LongitudinalAxis.ClearSources()); if (!clearOnly && Facade.LongitudinalAxis != null) { LongitudinalAxis.RunWhenActiveAndEnabled(() => LongitudinalAxis.AddSource(Facade.LongitudinalAxis)); } } } /// /// Configures the Axis Usage Type. /// public virtual void ConfigureAxisUsageType() { switch (Facade.AxisUsageType) { case AxesToVector3Facade.AxisUsage.Directional: IncrementalAxis.SetActive(false); MomentProcessor.gameObject.SetActive(false); DirectionalAxis.SetActive(true); break; case AxesToVector3Facade.AxisUsage.Incremental: DirectionalAxis.SetActive(false); IncrementalAxis.SetActive(true); MomentProcessor.gameObject.SetActive(true); break; } } protected virtual void OnEnable() { ConfigureAxisSources(); ConfigureMultipliers(); ConfigureAxisUsageType(); } protected virtual void OnDisable() { ConfigureAxisSources(true); } /// /// Applies the forward following source data to the axis data. /// /// The axis data to apply. /// The applied result of the forward following data against the axis data. protected virtual Vector3 ApplyForwardSourceToAxis(Vector3 axisData) { return (Facade.SourceOfForwardDirection.transform.right * axisData.x) + (Facade.SourceOfForwardDirection.transform.up * axisData.y) + (Facade.SourceOfForwardDirection.transform.forward * axisData.z); } } }