2021-01-10 03:59:47 +00:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using Unity.Mathematics;
|
|
|
|
|
|
using static Unity.Mathematics.math;
|
|
|
|
|
|
using static Unity.Mathematics.noise;
|
|
|
|
|
|
using static Noise1D;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Place an UI element to a world position
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[RequireComponent(typeof(RectTransform))]
|
|
|
|
|
|
public class PlaceUIElementWorldspace : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
public float NoiseAmplitude;
|
|
|
|
|
|
public float NoiseFrequency;
|
2021-01-25 05:53:36 +00:00
|
|
|
|
public Canvas Canvas;
|
2021-01-10 03:59:47 +00:00
|
|
|
|
public float BorderPixels = 10;
|
2021-03-07 23:24:22 +00:00
|
|
|
|
public bool PointAtTarget;
|
|
|
|
|
|
public Vector2 ScreenSpaceOffset;
|
|
|
|
|
|
public float EdgeMargin = .1f;
|
2021-01-10 03:59:47 +00:00
|
|
|
|
|
|
|
|
|
|
public Vector3 Target;
|
|
|
|
|
|
|
|
|
|
|
|
private RectTransform _rectTransform;
|
|
|
|
|
|
private Transform _cameraTransform;
|
|
|
|
|
|
private float _noiseOffset;
|
2021-01-25 05:53:36 +00:00
|
|
|
|
private RectTransform _canvasRectTransform;
|
2021-03-07 23:24:22 +00:00
|
|
|
|
private Camera _mainCamera;
|
|
|
|
|
|
private Quaternion _startRotation;
|
2021-01-10 03:59:47 +00:00
|
|
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get the rect transform
|
|
|
|
|
|
_rectTransform = GetComponent<RectTransform>();
|
|
|
|
|
|
_cameraTransform = Camera.main.transform;
|
2021-01-25 05:53:36 +00:00
|
|
|
|
_canvasRectTransform = Canvas.GetComponent<RectTransform>();
|
2021-03-07 23:24:22 +00:00
|
|
|
|
_mainCamera = Camera.main;
|
|
|
|
|
|
_startRotation = transform.rotation;
|
2021-01-10 03:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
|
{
|
|
|
|
|
|
_noiseOffset = UnityEngine.Random.Range(-100f, 100f);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Move the UI element to the world position
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
void LateUpdate()
|
|
|
|
|
|
{
|
|
|
|
|
|
_noiseOffset += Time.deltaTime * NoiseFrequency;
|
|
|
|
|
|
|
2021-03-07 23:24:22 +00:00
|
|
|
|
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(_mainCamera, Target);
|
|
|
|
|
|
var toTarget = (Target - _mainCamera.transform.position).normalized;
|
|
|
|
|
|
|
2021-01-10 03:59:47 +00:00
|
|
|
|
screenPoint *= Mathf.Sign(Vector3.Dot(_cameraTransform.forward, Target - _cameraTransform.position));
|
|
|
|
|
|
screenPoint += new Vector2(noise(_noiseOffset), noise(10 + _noiseOffset)) * NoiseAmplitude;
|
2021-03-07 23:24:22 +00:00
|
|
|
|
var clampedPoint = new Vector2(
|
|
|
|
|
|
Mathf.Clamp(screenPoint.x, BorderPixels, Screen.width - BorderPixels),
|
|
|
|
|
|
Mathf.Clamp(screenPoint.y, BorderPixels, Screen.height - BorderPixels));
|
|
|
|
|
|
var toEdge = _mainCamera.ScreenPointToRay(clampedPoint);
|
|
|
|
|
|
var edgeLerp = smoothstep(1 - EdgeMargin, 1, dot(toEdge.direction, toTarget));
|
|
|
|
|
|
if (PointAtTarget)
|
|
|
|
|
|
{
|
|
|
|
|
|
transform.rotation = Quaternion.Slerp(
|
|
|
|
|
|
Quaternion.LookRotation(Vector3.forward, (screenPoint - clampedPoint).normalized),
|
|
|
|
|
|
_startRotation, edgeLerp);
|
|
|
|
|
|
}
|
|
|
|
|
|
clampedPoint += ScreenSpaceOffset * edgeLerp;
|
|
|
|
|
|
_rectTransform.anchoredPosition = clampedPoint / Canvas.scaleFactor - _canvasRectTransform.sizeDelta / 2f;
|
2021-01-10 03:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|