248 lines
6.6 KiB
C#
248 lines
6.6 KiB
C#
|
// 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
|
|||
|
|
|||
|
}
|