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);
}
}
}