// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Avatar;
using UltimateXR.Core;
using UltimateXR.Core.Components;
using UnityEngine;
using UnityEngine.UI;
namespace UltimateXR.UI.UnityInputModule.Utils
{
///
/// Component that adjusts the dynamic pixels per unit value in a component depending on
/// the distance to the avatar. It helps removing filtering artifacts when using composition layers is not
/// possible.
///
[RequireComponent(typeof(CanvasScaler))]
public class UxrDynamicPixelsPerUnit : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private float _updateSeconds = 0.3f;
[SerializeField] private float _rangeNear = 0.3f;
[SerializeField] private float _rangeFar = 4.0f;
[SerializeField] private float _pixelsPerUnitNear = 1.0f;
[SerializeField] private float _pixelsPerUnitFar = 0.1f;
#endregion
#region Unity
///
/// Caches components.
///
protected override void Awake()
{
base.Awake();
_canvasScaler = GetComponent();
}
///
/// Subscribes to events.
///
protected override void OnEnable()
{
base.OnEnable();
UxrAvatar.GlobalAvatarMoved += UxrAvatar_GlobalAvatarMoved;
}
///
/// Unsubscribes from events.
///
protected override void OnDisable()
{
base.OnDisable();
UxrAvatar.GlobalAvatarMoved += UxrAvatar_GlobalAvatarMoved;
}
#endregion
#region Event Handling Methods
///
/// Called when an avatar moved: Adjusts the dynamic pixels per unit.
///
/// Event sender
/// Event parameters
private void UxrAvatar_GlobalAvatarMoved(object sender, UxrAvatarMoveEventArgs e)
{
UxrAvatar avatar = sender as UxrAvatar;
if (avatar == UxrAvatar.LocalAvatar && Time.time - _timeLastUpdate > _updateSeconds)
{
_timeLastUpdate = Time.time;
float distance = Vector3.Distance(avatar.CameraPosition, _canvasScaler.transform.position);
_canvasScaler.dynamicPixelsPerUnit = Mathf.Lerp(_pixelsPerUnitNear, _pixelsPerUnitFar, Mathf.Clamp01((distance - _rangeNear) / (_rangeFar - _rangeNear)));
}
}
#endregion
#region Private Types & Data
private float _timeLastUpdate = -1.0f;
private CanvasScaler _canvasScaler;
#endregion
}
}