ccl4/blueberryPeak/Assets/Scripts/Helper/WindVisualizer.cs

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);
}
}