91 lines
4.2 KiB
C#
91 lines
4.2 KiB
C#
using UnityEngine;
|
|
|
|
public class WindVisualizer : MonoBehaviour
|
|
{
|
|
[SerializeField] private Transform windTransform; // The object that will move (e.g., your LineRenderer GameObject)
|
|
[SerializeField] private Transform windStart; // The starting point of the wind path
|
|
[SerializeField] private Transform windEnd; // The ending point of the wind path
|
|
[SerializeField] private float windSpeed = 1.0f; // Controls how fast the wind moves along the path
|
|
[SerializeField] private float curveAmplitude = 1.0f; // How high/wide the sine curve is
|
|
[SerializeField] private float curveFrequency = 1.0f; // How many waves are in the path
|
|
[SerializeField] private TrailRenderer trailRenderer; // How many waves are in the path
|
|
[SerializeField] private float initialPhaseOffset = 0f; // To offset the start time for multiple wind effects
|
|
|
|
private float previousNormalizedTime = 0f; // To detect when the loop restarts
|
|
|
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
void Start()
|
|
{
|
|
// Basic validation
|
|
if (windTransform == null || windStart == null || windEnd == null)
|
|
{
|
|
Debug.LogError("WindVisualizer: 'windTransform', 'windStart', or 'windEnd' is not assigned. Please assign them in the Inspector.", this);
|
|
enabled = false; // Disable the script if essential components are missing
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
trailRenderer.enabled = true;
|
|
if (windTransform == null || windStart == null || windEnd == null)
|
|
{
|
|
return; // Don't proceed if validation failed in Start
|
|
}
|
|
|
|
// Calculate the length of the path
|
|
float pathLength = Vector3.Distance(windStart.position, windEnd.position);
|
|
if (pathLength == 0) // Avoid division by zero if start and end are at the same position
|
|
{
|
|
windTransform.position = windStart.position; // Stay at start
|
|
return;
|
|
}
|
|
|
|
// Calculate a normalized position along the path (0 to 1, then loops back to 0)
|
|
float currentPathTime = (Time.time + initialPhaseOffset) * windSpeed / pathLength;
|
|
float normalizedTime = Mathf.Repeat(currentPathTime, 1f); // Loops between 0 and 1
|
|
|
|
// --- Function Call Logic ---
|
|
// If normalizedTime has wrapped around (i.e., it was high and now it's low),
|
|
// it means the windTransform has logically reached the end and "jumped" back to the start.
|
|
if (normalizedTime < previousNormalizedTime)
|
|
{
|
|
OnWindCycleComplete(); // Call your function here
|
|
}
|
|
previousNormalizedTime = normalizedTime; // Store for the next frame's comparison
|
|
// --- End Function Call Logic ---
|
|
|
|
|
|
// Get the straight-line position between start and end based on normalizedTime
|
|
Vector3 straightLinePosition = Vector3.Lerp(windStart.position, windEnd.position, normalizedTime);
|
|
|
|
// Calculate the direction vector from start to end
|
|
Vector3 pathDirection = (windEnd.position - windStart.position).normalized;
|
|
|
|
// Find a perpendicular direction for the sine wave offset
|
|
Vector3 perpendicularDirection = Vector3.Cross(pathDirection, Vector3.forward);
|
|
if (perpendicularDirection == Vector3.zero)
|
|
{
|
|
perpendicularDirection = Vector3.up;
|
|
}
|
|
perpendicularDirection.Normalize();
|
|
|
|
// Calculate the sine wave offset
|
|
float sineInput = normalizedTime * curveFrequency * Mathf.PI * 2 + Time.time;
|
|
float sineOffset = Mathf.Sin(sineInput) * curveAmplitude;
|
|
|
|
// Apply the sine offset to the straight-line position
|
|
windTransform.position = straightLinePosition + perpendicularDirection * sineOffset;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This function is called every time the wind visualizer completes a full cycle
|
|
/// (i.e., it reaches the end position and resets to the start).
|
|
/// </summary>
|
|
private void OnWindCycleComplete()
|
|
{
|
|
trailRenderer.enabled = false;
|
|
Instantiate(this.gameObject, transform.position, transform.rotation);
|
|
Destroy(this.gameObject);
|
|
}
|
|
} |