Files
2026-03-04 10:03:45 +08:00

234 lines
7.0 KiB
C#

using UnityEngine;
using UnityEngine.EventSystems;
namespace FIMSpace.FTail
{
[AddComponentMenu("FImpossible Creations/Tail Animator Utilities/Tail Animator Wind")]
public class TailAnimatorWind : MonoBehaviour, IDropHandler, IEventSystemHandler, IFHierarchyIcon
{
[Header("In playmode you will find this object in DontDestroyOnLoad")]
[FPD_Header("Main Wind Setings", 2f, 4f, 2)]
public float power = 1f;
public float additionalTurbulence = 1f;
public float additionalTurbSpeed = 1f;
[Space(7f)]
public WindZone SyncWithUnityWindZone;
public float UnityWindZonePowerMul = 2f;
public float UnityWindZoneTurbMul = 1f;
[Header("Overriding wind if value below different than 0,0,0")]
public Vector3 overrideWind = Vector3.zero;
[FPD_Header("Procedural Wind Settings (if not syncing and not overriding)", 6f, 4f, 2)]
[Range(0.1f, 1f)]
public float rapidness = 0.95f;
[FPD_Suffix(0f, 360f, FPD_SuffixAttribute.SuffixMode.FromMinToMaxRounded, "°", true, 0)]
public float changesPower = 90f;
[Header("Extra")]
[Range(0f, 10f)]
public float turbulenceSpeed = 1f;
[FPD_Header("World Position Turbulence", 6f, 4f, 2)]
[Tooltip("Increase to make objects next to each other wave in slightly different way")]
public float worldTurb = 1f;
[Tooltip("If higher no performance cost, it is just a number")]
public float worldTurbScale = 512f;
public float worldTurbSpeed = 5f;
[FPD_Header("Tail Compoenents Related", 6f, 4f, 2)]
[Tooltip("When tail is longer then power of wind should be higher")]
public bool powerDependOnTailLength = true;
[Tooltip("Don't destroy on load")]
public bool persistThroughAllScenes;
private Vector3 targetWind = Vector3.zero;
private Vector3 smoothWind = Vector3.zero;
private Vector3 windVeloHelper = Vector3.zero;
private Quaternion windOrientation = Quaternion.identity;
private Quaternion smoothWindOrient = Quaternion.identity;
private Quaternion smoothWindOrientHelper = Quaternion.identity;
private float[] randNumbers;
private float[] randTimes;
private float[] randSpeeds;
private int frameOffset = 2;
private Vector3 finalAddTurbulence = Vector3.zero;
private Vector3 addTurbHelper = Vector3.zero;
private Vector3 smoothAddTurbulence = Vector3.zero;
public string EditorIconPath => "Tail Animator/TailAnimatorWindIconSmall";
public static TailAnimatorWind Instance { get; private set; }
public void OnDrop(PointerEventData data)
{
}
private void Awake()
{
if (Application.isPlaying)
{
Instance = this;
if (persistThroughAllScenes)
{
Object.DontDestroyOnLoad(base.gameObject);
}
}
}
public void OnValidate()
{
Instance = this;
}
private void Update()
{
if (frameOffset > 0)
{
frameOffset--;
}
else
{
ComputeWind();
}
}
public static void Refresh()
{
if (Instance == null)
{
Debug.Log("[Tail Animator Wind] No Tail Animator Wind component on the scene!");
Debug.LogWarning("[Tail Animator Wind] No Tail Animator Wind component on the scene!");
}
}
public void AffectTailWithWind(TailAnimator2 t)
{
if (!t.UseWind || t.WindEffectPower <= 0f || t.TailSegments.Count <= 0)
{
return;
}
float num = 1f;
if (powerDependOnTailLength)
{
num = t._TC_TailLength * t.TailSegments[0].transform.lossyScale.z / 5f;
if (t.TailSegments.Count > 3)
{
num *= Mathf.Lerp(0.7f, 3f, (float)t.TailSegments.Count / 14f);
}
}
if (t.WindWorldNoisePower > 0f)
{
float num2 = worldTurbSpeed;
if ((bool)SyncWithUnityWindZone)
{
num2 *= SyncWithUnityWindZone.windTurbulence * UnityWindZoneTurbMul;
}
float num3 = 0.5f + Mathf.Sin(Time.time * num2 + t.TailSegments[0].ProceduralPosition.x * worldTurbScale) / 2f + (0.5f + Mathf.Cos(Time.time * num2 + t.TailSegments[0].ProceduralPosition.z * worldTurbScale) / 2f);
num += num3 * worldTurb * t.WindWorldNoisePower;
}
num *= t.WindEffectPower;
if (t.WindTurbulencePower > 0f)
{
t.WindEffect = new Vector3(targetWind.x * num + finalAddTurbulence.x * t.WindTurbulencePower, targetWind.y * num + finalAddTurbulence.y * t.WindTurbulencePower, targetWind.z * num + finalAddTurbulence.z * t.WindTurbulencePower);
}
else
{
t.WindEffect = new Vector3(targetWind.x * num, targetWind.y * num, targetWind.z * num);
}
}
private void Start()
{
int num = 10;
randNumbers = new float[num];
randTimes = new float[num];
randSpeeds = new float[num];
for (int i = 0; i < 10; i++)
{
randNumbers[i] = Random.Range(-1000f, 1000f);
randTimes[i] = Random.Range(-1000f, 1000f);
randSpeeds[i] = Random.Range(0.18f, 0.7f);
}
}
private void ComputeWind()
{
Vector3 target;
if ((bool)SyncWithUnityWindZone)
{
target = SyncWithUnityWindZone.transform.forward * SyncWithUnityWindZone.windMain * UnityWindZonePowerMul;
base.transform.rotation = SyncWithUnityWindZone.transform.rotation;
}
else if (overrideWind != Vector3.zero)
{
target = overrideWind;
}
else
{
for (int i = 0; i < 4; i++)
{
randTimes[i] += Time.deltaTime * randSpeeds[i] * turbulenceSpeed;
}
Quaternion quaternion = windOrientation;
float num = -1f + Mathf.PerlinNoise(randTimes[0], 256f + randTimes[1]) * 2f;
float y = -1f + Mathf.PerlinNoise(0f - randTimes[1], 55f + randTimes[2]) * 2f;
float num2 = -1f + Mathf.PerlinNoise(0f - randTimes[3], 55f + randTimes[0]) * 2f;
quaternion *= Quaternion.Euler(new Vector3(0f, y, 0f) * changesPower);
quaternion = Quaternion.Euler(num * (changesPower / 6f), quaternion.eulerAngles.y, num2 * (changesPower / 6f));
smoothWindOrient = smoothWindOrient.SmoothDampRotation(quaternion, ref smoothWindOrientHelper, 1f - rapidness, Time.deltaTime);
base.transform.rotation = smoothWindOrient;
target = smoothWindOrient * Vector3.forward;
}
smoothAddTurbulence = Vector3.SmoothDamp(smoothAddTurbulence, GetAddTurbulence() * additionalTurbulence, ref addTurbHelper, 0.05f, float.PositiveInfinity, Time.deltaTime);
smoothWind = Vector3.SmoothDamp(smoothWind, target, ref windVeloHelper, 0.1f, float.PositiveInfinity, Time.deltaTime);
for (int j = 7; j < 10; j++)
{
randTimes[j] += Time.deltaTime * randSpeeds[j] * turbulenceSpeed;
}
float num3 = power * 0.015f;
num3 *= 0.5f + Mathf.PerlinNoise(randTimes[7] * 2f, 25f + randTimes[8] * 0.5f);
finalAddTurbulence = smoothAddTurbulence * num3;
targetWind = smoothWind * num3;
}
private Vector3 GetAddTurbulence()
{
float num = additionalTurbSpeed;
if ((bool)SyncWithUnityWindZone)
{
num *= SyncWithUnityWindZone.windTurbulence * UnityWindZoneTurbMul;
}
for (int i = 4; i < 7; i++)
{
randTimes[i] += Time.deltaTime * randSpeeds[i] * num;
}
float x = -1f + Mathf.PerlinNoise(randTimes[4] + 7.123f, -2.324f + Time.time * 0.24f) * 2f;
float y = -1f + Mathf.PerlinNoise(randTimes[5] - 4.7523f, -25.324f + Time.time * 0.54f) * 2f;
float z = -1f + Mathf.PerlinNoise(randTimes[6] + 1.123f, -63.324f + Time.time * -0.49f) * 2f;
return new Vector3(x, y, z);
}
}
}