Mathf.SmoothStep sequence Time problem
Help me resolve the issue about SmoothStep I want to make the 'radius' 1st go form 20 to -1, after that from -1 to 5 and after from 5 to 0.
So I tried to make a code with triggers and coroutines, but I don't get it how to make it work properly Because I think the time goes the same in every SmoothStep.
IEnumerator BeHole()
{
if (check1 == false)
{
radius = Mathf.SmoothStep (20, -1, Time.time / 3);
}
yield return null;
}
}
Answer by Hellium · Oct 05, 2018 at 11:20 AM
IEnumerator BeHole( float transitionDuration, params float[] radiuses )
{
float inverseTransitionDuration = 1f / transitionDuration ;
radius = radiuses[0];
yield return null;
for ( int index = 0 ; index < radiuses.Length - 1 ; ++index )
{
for ( float t = Time.deltaTime ; t < transitionDuration ; t = Mathf.Min( t + Time.deltaTime, transitionDuration ) )
{
radius = Mathf.SmoothStep (radiuses[index], radiuses[index + 1], t * inverseTransitionDuration );
yield return null;
}
radius = radiuses[index + 1];
yield return null;
}
}
And you call it as follow ONLY ONCE (not each frame)
// The 1st argument is the time needed to go from 20 to -1
StartCoroutine( BeHole( 1, 20f, -1f, 5f, 0f ) ) ;
// OR
// StartCoroutine( BeHole( 1, new float[]{ 20f, -1f, 5f, 0f } ) ) ;
Wow, It works, but in the end, it looks glitchy like it cant make to absolute zero
Okay, so I need type this StartCoroutine( BeHole( 1,new float[] {15f, -0.5f, 0.5f, 0f}) ) ; On void Update? Or where?
I fixed my code so that the radius gets the correct values in the "control points".
As I said, the coroutine must not be started every frame.
You have two solutions: Either call StartCoroutine
only when $$anonymous$$ain$$anonymous$$enu
is set to true
(supposing $$anonymous$$ain$$anonymous$$enu
is a boolean), or use the following:
IEnumerator BeHoleCall;
void Start()
{
StartBeHole();
}
void Update()
{
if( $$anonymous$$ain$$anonymous$$enu && BeHoleCall != null && !BeHoleCall.$$anonymous$$oveNext() )
BeHoleCall = null; // OR StartBeHole() if you want it to loop
}
private void StartBeHole()
{
BeHoleCall = BeHole( 1, new float[]{ 15f, -0.5f, 0.5f, 0f} );
}
So the final code looks like this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class BlackHoleEffect : $$anonymous$$onoBehaviour {
public Shader shader;
public Transform blackHole;
public float ratio;
public float radius;
public bool $$anonymous$$ain$$anonymous$$enu;
public bool check1 = false;
public bool check2 = false;
public bool check3 = false;
Camera cam;
$$anonymous$$aterial _material;
$$anonymous$$aterial material {
get {
if (_material == null) {
_material = new $$anonymous$$aterial (shader);
_material.hideFlags = HideFlags.HideAndDontSave;
}
return _material;
}
}
IEnumerator BeHoleCall;
protected virtual void Start()
{
BeHoleCall = BeHole( 1, 0, 10, 5, 20 );
}
protected void Update()
{
if( $$anonymous$$ain$$anonymous$$enu && BeHoleCall != null && !BeHoleCall.$$anonymous$$oveNext() )
BeHoleCall = null;
}
void OnEnable(){
cam = GetComponent<Camera> ();
ratio = 1f / cam.aspect;
}
void OnDisable(){
if (_material) {
DestroyImmediate (_material);
}
}
Vector3 wtsp;
Vector2 pos;
void OnRenderImage (RenderTexture source, RenderTexture destination){
if (shader && material && blackHole) {
wtsp = cam.WorldToScreenPoint (blackHole.position);
if (wtsp.z > 0) {
pos = new Vector2 (wtsp.x / cam.pixelWidth, wtsp.y / cam.pixelHeight);
_material.SetVector ("_Position", pos);
_material.SetFloat ("_Ratio", ratio);
_material.SetFloat ("_Rad", radius);
_material.SetFloat ("_Distance", Vector3.Distance (blackHole.position, transform.position));
Graphics.Blit (source, destination, material);
}
}
}
IEnumerator BeHole( float transitionDuration, params float[] radiuses )
{
float inverseTransitionDuration = 1f / transitionDuration ;
for( int index = 0 ; index < radiuses.Length - 1 ; ++index )
{
for( float t = 0 ; t < transitionDuration && !check1 ; t = $$anonymous$$athf.$$anonymous$$in( t + Time.deltaTime, transitionDuration ) )
{
radius = $$anonymous$$athf.SmoothStep (radiuses[index], radiuses[index + 1], t * inverseTransitionDuration );
yield return null;
}
radius = radiuses[index + 1];
yield return null;
}
}
}
Your answer
Follow this Question
Related Questions
Separate Numbers ? 1 Answer
why the Timer isn't working 0 Answers
Pausing a Mathf.PingPong at the ends 0 Answers
Highscore - BestTime 1 Answer
Allow player to Press Input.GetKeyDown once per update ? 0 Answers