namespace VRTK.Prefabs.Interactions.Controllables
{
using UnityEngine;
using Malimbe.XmlDocumentationAttribute;
using Malimbe.PropertySerializationAttribute;
using Malimbe.BehaviourStateRequirementMethod;
using Zinnia.Extension;
using Zinnia.Data.Type;
using Zinnia.Data.Attribute;
using Zinnia.Tracking.Modification;
using Zinnia.Data.Type.Transformation;
using VRTK.Prefabs.Interactions.Interactables;
///
/// A directional drive that directly manipulates a to control the linear translation movement without the use of any physics.
///
public class DirectionalTransformDrive : DirectionalDrive
{
#region Reference Settings
///
/// The that controls the movement of the drive.
///
[Serialized]
[field: Header("Reference Settings"), DocumentedByXml, Restricted]
public InteractableFacade Interactable { get; protected set; }
///
/// The to clamp the position of the drive within the drive limits.
///
[Serialized]
[field: DocumentedByXml, Restricted]
public Vector3Restrictor PositionClamper { get; protected set; }
///
/// The to automatically move the drive to a specific location.
///
[Serialized]
[field: DocumentedByXml, Restricted]
public TransformPropertyApplier PropertyApplier { get; protected set; }
#endregion
///
/// The position to automatically move the drive to.
///
private readonly TransformData autoDrivePosition = new TransformData();
///
public override void Process()
{
ConfigureAutoDrive(Facade.MoveToTargetValue);
base.Process();
}
///
[RequiresBehaviourState]
public override Vector3 CalculateDriveAxis(DriveAxis.Axis driveAxis)
{
PositionClamper.XBounds = driveAxis == DriveAxis.Axis.XAxis ? DriveLimits : default;
PositionClamper.YBounds = driveAxis == DriveAxis.Axis.YAxis ? DriveLimits : default;
PositionClamper.ZBounds = driveAxis == DriveAxis.Axis.ZAxis ? DriveLimits : default;
return -base.CalculateDriveAxis(driveAxis);
}
///
public override void ProcessDriveSpeed(float driveSpeed, bool moveToTargetValue)
{
PropertyApplier.TransitionDuration = driveSpeed.ApproxEquals(0f) ? 0f : 1f / driveSpeed;
PropertyApplier.enabled = moveToTargetValue;
if (PropertyApplier.enabled)
{
if (Interactable.ConsumerRigidbody != null)
{
Interactable.ConsumerRigidbody.velocity = Vector3.zero;
}
PropertyApplier.Apply();
}
}
///
protected override Transform GetDriveTransform()
{
return Interactable.transform;
}
///
protected override void SetDriveTargetValue(Vector3 targetValue)
{
autoDrivePosition.UseLocalValues = true;
autoDrivePosition.Transform = GetDriveTransform();
autoDrivePosition.PositionOverride = targetValue;
PropertyApplier.Source = autoDrivePosition;
PropertyApplier.Apply();
}
}
}