UP-Viagg-io/Viagg-io/Assets/afca/ViaggioAI/Scripts/Helpers/ThresholdedPositioner.cs

248 lines
6.6 KiB
C#
Executable File

// 04.10.2021 11:00
using System;
using System.Threading.Tasks;
using UnityEngine;
public class ThresholdedPositioner : MonoBehaviour
{
#region Inspector Properties
[Header("Config Values")]
[Tooltip("Sets the desired position relative to target.")]
[SerializeField]
private Vector3 offsetToTarget;
[Tooltip("Should the position be fixed on height of the camera?")]
[SerializeField]
private bool keepOnCamHeight;
[Tooltip("Specifies the desired OnEnable behaviour.")]
[SerializeField]
private EEnablingBehaviour enablingBehaviour = EEnablingBehaviour.Transition;
[Tooltip("Specifies the delay in seconds before initializing.")]
[SerializeField]
private float initDelay = 0.03f;
[Tooltip("Specifies how fast the object will move.")]
[SerializeField]
private float movingSpeed = 4f;
[Tooltip("Distance from desiredPos which will start movement.")]
[SerializeField]
private float startMovingDistance = 0.2f;
[Tooltip("Distance to desiredPos which will stop movement.")]
[SerializeField]
private float stopMovingDistance = 0.02f;
[Tooltip("If keepAwayFromTransform is set: Minimal distance to keepAwayFromTransform.")]
[SerializeField]
private float keepAwayDistance = 0.5f;
[Header("Scene Objects")]
[Tooltip("Uses camera if not set")]
[SerializeField]
private Transform target;
[Tooltip("Stays away from this transform")]
[SerializeField]
private Transform keepAwayTransform;
#endregion
#region Public Properties
#endregion
#region Private Properties
private Camera cam;
private bool isInitialized = false;
private bool isMoving = false;
#endregion
#region Framework Functions
void Awake()
{
this.cam = Camera.main;
}
void OnEnable()
{
this.initPositionerWithDelay();
}
void Update()
{
if (this.isInitialized)
{
this.updateIsMoving();
if (this.isMoving)
{
this.updatePosition();
}
if (this.keepAwayTransform != null)
{
this.ensureMinDistanceToKeepAwayTransform();
}
}
}
void OnDisable()
{
this.isInitialized = false;
}
#endregion
#region Events
#endregion
#region Public Functions
public void OverrideEnablingBehaviour(EEnablingBehaviour newBehaviour)
{
this.enablingBehaviour = newBehaviour;
}
public void OverrideStartMovingDistance(float newStartMovingDistance)
{
this.startMovingDistance = newStartMovingDistance;
}
public void OverrideStopMovingDistance(float newStopMovingDistance)
{
this.stopMovingDistance = newStopMovingDistance;
}
public void OverrideMovingSpeed(float newMovingSpeed)
{
this.movingSpeed = newMovingSpeed;
}
public void OverrideKeepAwayFromTransform(Transform _keepAwayTransform, float _keepAwayDistance)
{
this.keepAwayTransform = _keepAwayTransform;
this.keepAwayDistance = _keepAwayDistance;
}
public void JumpToDesiredPosition()
{
this.transform.position = this.getDesiredPosition();
}
#endregion
#region Private Functions
private async void initPositionerWithDelay()
{
await Task.Delay(TimeSpan.FromSeconds(this.initDelay));
if (this.enablingBehaviour == EEnablingBehaviour.Transition)
{
this.isMoving = true;
}
if (this.enablingBehaviour == EEnablingBehaviour.Hold)
{
this.isMoving = false;
}
if (this.enablingBehaviour == EEnablingBehaviour.Jump)
{
this.transform.position = this.getDesiredPosition();
}
this.isInitialized = true;
}
private Vector3 getDesiredPosition()
{
// Ensure that we always have a target (in case this gets called before init)
if (this.target == null)
{
this.target = this.cam.transform;
}
Vector3 desiredPos = this.target.position
+ this.target.right * this.offsetToTarget.x
+ this.target.up * this.offsetToTarget.y
+ this.target.forward * this.offsetToTarget.z;
if (this.keepOnCamHeight)
{
// Override y position to keep on Cam height
desiredPos.y = this.cam.transform.position.y;
// Check if distance is still sufficient after overriding y pos
float distance = Vector3.Distance(desiredPos, this.target.position);
if (distance < this.offsetToTarget.z)
{
desiredPos = (desiredPos - this.target.position).normalized * this.offsetToTarget.z + this.target.position;
//Vector3 newPos = (this.transform.position - this.keepAwayTransform.position).normalized * this.keepAwayDistance + this.keepAwayTransform.position;
}
}
return desiredPos;
}
private void updateIsMoving()
{
float distance = Vector3.Distance(this.transform.position, this.getDesiredPosition());
if (this.isMoving && distance < this.stopMovingDistance)
{
this.isMoving = false;
}
else if (!this.isMoving && distance > this.startMovingDistance)
{
this.isMoving = true;
}
}
private void updatePosition()
{
Vector3 newPosition = Vector3.Lerp(this.transform.position, this.getDesiredPosition(), this.movingSpeed * Time.deltaTime);
if (this.keepAwayTransform != null)
{
float distance = Vector3.Distance(newPosition, this.keepAwayTransform.position);
if (distance < this.keepAwayDistance)
{
// Getting too close to keep away from transform -> don't move
newPosition = this.transform.position;
}
}
this.transform.position = newPosition;
}
private void ensureMinDistanceToKeepAwayTransform()
{
float distance = Vector3.Distance(this.transform.position, this.keepAwayTransform.position);
if (distance < this.keepAwayDistance)
{
Vector3 newPos = (this.transform.position - this.keepAwayTransform.position).normalized * this.keepAwayDistance + this.keepAwayTransform.position;
this.transform.position = newPos;
}
}
#endregion
}