Files
Cielonos/Assets/External VFXs/INab Studio/Post Processing Assets/World Scan FX/Demo Scripts/Highlight UI/CustomUIHighlight.cs
SoulliesOfficial d94241f36c 场景设计
2026-01-12 03:22:16 -05:00

128 lines
4.4 KiB
C#

using System.Collections;
using TMPro;
using UnityEngine;
namespace INab.WorldScanFX
{
[ExecuteAlways]
public class CustomUIHighlight : MonoBehaviour
{
// Reference to the UI component to be highlighted
public GameObject uiComponent;
// Reference to the TextMeshPro component of the UI
public TextMeshProUGUI uiText;
// Duration of the highlight effect
public float highlightDuration = 3f;
// Duration of scaling animation
public float scaleDuration = 0.5f;
// Offset on the Y-axis for the UI component
public float offsetY = 1f;
// Adjustment factor for scale based on distance
public float scaleAdjustment = 10;
// Reference to the player's transform
public Transform playerTransform;
// Reference to the player's camera
public Camera playerCamera;
// Remaining time for the highlight effect
private float timeLeft = 0;
// Current scale of the UI component
private float currentScale = 1;
// Flag to indicate if scaling animation is in progress
private bool isCurrentlyScaling = false;
// Flag to indicate if the highlight effect is active
private bool isEffectActive = false;
private void Start()
{
// Deactivate the UI component initially
uiComponent.SetActive(false);
}
// Method to start the highlight effect
public void StartEffect()
{
if (isEffectActive == true)
{
// Restart the effect if already active
timeLeft = highlightDuration;
}
else
{
// Activate the effect
isEffectActive = true;
uiComponent.SetActive(true);
timeLeft = highlightDuration;
// Start scaling animation
StartCoroutine(ScaleUI(true));
}
}
// Method to stop the highlight effect
public void StopEffect()
{
isEffectActive = false;
// Start scaling animation to hide the UI
StartCoroutine(ScaleUI(false));
}
// Coroutine for scaling the UI component
private IEnumerator ScaleUI(bool show)
{
isCurrentlyScaling = true;
float elapsedTime = 0f;
while (elapsedTime < scaleDuration)
{
elapsedTime += Time.deltaTime;
float effectTime = elapsedTime / scaleDuration;
float value = show ? Mathf.SmoothStep(0, currentScale, effectTime) : Mathf.SmoothStep(currentScale, 0, effectTime);
uiComponent.transform.localScale = new Vector3(value, value, value);
yield return null;
}
isCurrentlyScaling = false;
if (!show)
uiComponent.SetActive(false);
}
// Update is called once per frame
public void Update()
{
if (isEffectActive)
timeLeft -= Time.deltaTime;
if (timeLeft < 0 && Application.isPlaying && isEffectActive)
{
StopEffect();
}
else
{
// Calculate distance between player and UI
float distance = Vector3.Distance(playerTransform.position, transform.position);
// Convert distance to text and display on UI
string distanceText = Mathf.CeilToInt(distance) + "M";
uiText.text = distanceText;
// Calculate new position for UI based on player's camera
// check if position is behind camera
bool isBehindCamera = playerCamera.WorldToScreenPoint(transform.position).z < 0;
var rect = uiComponent.GetComponent<RectTransform>();
if (!isBehindCamera)
{
var newPosition = playerCamera.WorldToScreenPoint(transform.position + new Vector3(0, offsetY, 0));
rect.position = newPosition;
}
// Adjust scale of UI based on distance
currentScale = Mathf.Clamp01(scaleAdjustment / distance);
if (!isCurrentlyScaling)
rect.localScale = new Vector3(currentScale, currentScale, currentScale);
}
}
}
}