diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index 9249053..8450e13 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -154,6 +154,9 @@ MonoBehaviour: type: 3} resolution: 50 function: 4 + transitionMode: 2 + functionDuration: 1 + transitionDuration: 1 --- !u!4 &75389716 Transform: m_ObjectHideFlags: 0 @@ -768,3 +771,5 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: display: {fileID: 1844483591} + displayMode: 0 + sampleDuration: 1 diff --git a/Assets/Script/FunctionLibrary.cs b/Assets/Script/FunctionLibrary.cs index c6400c8..6205c92 100644 --- a/Assets/Script/FunctionLibrary.cs +++ b/Assets/Script/FunctionLibrary.cs @@ -3,7 +3,7 @@ using static UnityEngine.Mathf; public static class FunctionLibrary { - public delegate Vector3 Function(float u, float v, float y); + public delegate Vector3 Function(float u, float v, float t); public enum FunctionName { Wave, MultiWave, Ripple, Sphere, Torus } @@ -84,4 +84,9 @@ public static class FunctionLibrary p.z = s * Cos(PI * u); return p; } + + public static Vector3 Morph(float u, float v, float t, Function from, Function to, float progress) + { + return Vector3.LerpUnclamped(from(u, v, t), to(u, v, t), SmoothStep(0.0f, 1.0f, progress)); + } } diff --git a/Assets/Script/Graph.cs b/Assets/Script/Graph.cs index 0609eb6..de8cef2 100644 --- a/Assets/Script/Graph.cs +++ b/Assets/Script/Graph.cs @@ -19,10 +19,17 @@ public class Graph : MonoBehaviour [SerializeField, Min(0.0f)] float functionDuration = 1.0f; + [SerializeField, Min(0.0f)] + float transitionDuration = 1.0f; + Transform[] points; float duration = 0.0f; + bool transitioning; + + FunctionLibrary.FunctionName transitionFunction; + private void Awake() { var step = 2f / resolution; @@ -40,12 +47,29 @@ public class Graph : MonoBehaviour private void Update() { duration += Time.deltaTime; - if (duration >= functionDuration) + if (transitioning) + { + if (duration >= transitionDuration) + { + duration -= transitionDuration; + transitioning = false; + } + } + else if (duration >= functionDuration) { duration -= functionDuration; + transitioning = true; + transitionFunction = function; PickNextFunction(); } - UpdateFunction(); + if (transitioning) + { + UpdateFunctionTransition(); + } + else + { + UpdateFunction(); + } } private void PickNextFunction() @@ -54,7 +78,6 @@ public class Graph : MonoBehaviour function = transitionMode == TransitionMode.Cycle ? FunctionLibrary.GetNextFunctionName(function) : FunctionLibrary.GetRandomFunctionNameOtherThan(function); - } private void UpdateFunction() @@ -75,5 +98,26 @@ public class Graph : MonoBehaviour points[i].localPosition = f(u, v, time); } } - + + private void UpdateFunctionTransition() + { + FunctionLibrary.Function + from = FunctionLibrary.GetFunction(transitionFunction), + to = FunctionLibrary.GetFunction(function); + float progress = duration / transitionDuration; + float time = Time.time; + float step = 2f / resolution; + float v = 0.5f * step - 1f; + for (int i = 0, x = 0, z = 0; i < points.Length; i++, x++) + { + if (x == resolution) + { + x = 0; + z += 1; + v = (z + 0.5f) * step - 1f; + } + float u = (x + 0.5f) * step - 1f; + points[i].localPosition = FunctionLibrary.Morph(u, v, time, from, to, progress); + } + } }