234 lines
7.0 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|