it also is based upon using StartCoroutine and yield functions. There's also code showing how to stop started coroutines and the likes in there.
save as a .cs file and apply the guiDebug to a gameobject of sorts. it also creates a spinning cube for reference, but whatever you want to test it out with should work.
using UnityEngine; using System.Collections; public class GuiDebug : MonoBehaviour { float startTime =0; FrameClock clock; bool isInit =false; void OnGUI () { GUI.Box(new Rect(10,10,200,90), "Loader Menu"); if(GUI.Button(new Rect(20,40,150,20), "test withoutClock")) { if(!isInit) init(); clock.isOn = false; TestFunc(); } if(GUI.Button(new Rect(20,70,150,20), "WithClock")) { if(!isInit) init(); clock.isOn = true; TestFunc(); } } void Awake() { GameObject testCube = GameObject.CreatePrimitive(PrimitiveType.Cube); testCube.renderer.material.color= Color.red; testCube.AddComponent<RotateObj>(); } void init() { GameObject go = transform.gameObject; clock = go.AddComponent<FrameClock>(); isInit = true; } void TestFunc() { print("Starting " + Time.time); startTime = (float)Time.time; if (isShortLoopRunning == true) StopCoroutine("shortLoop"); if (isLongLoopRunning == true) StopCoroutine("isLongLoopRunning"); StartCoroutine("LongLoop",30); StartCoroutine("shortLoop",300); } bool isLongLoopRunning =false; //my way of figuring out if a coroutine is running, in case I want to reset it IEnumerator LongLoop(int iterations) { isLongLoopRunning=true; int mainI=0; float sumFloat=0; while (mainI<iterations) { startTime = (float)Time.realtimeSinceStartup; int i=0; while (i < 1000000){ sumFloat += Mathf.PerlinNoise(i,0); if (clock.outOfTime) yield return 0; i++; } if(clock.isOn == false) yield return 0; //remove this and the loop will just stop the game until its done if you have turned off the clock else if (clock.outOfTime) yield return 0; float endTime = (float)Time.realtimeSinceStartup; float timeElapsed = (endTime-startTime); print("____perlinNoiseLong: "+(sumFloat/1000000)+"time taken: "+timeElapsed+" #"+mainI); her mainI++; } isLongLoopRunning=false; } bool isShortLoopRunning = false; IEnumerator shortLoop(int iterations) { print("start of shortLoop\n"); isShortLoopRunning = true; //int mainI = 0; float sumFloat = 0; int totalRepetitions = 0; for(int mainI=0; mainI < iterations; mainI ++) { int i = 0; while(i<10000){ sumFloat += Mathf.PerlinNoise(i,0); totalRepetitions++; i++; } if(clock.isOn == false) yield return 0; else if ( clock.outOfTime)yield return 0; //if(clock.isOn == false) yield return 0; mainI++; } print("_____________perlinNoiseShort: "+(sumFloat/totalRepetitions)); isShortLoopRunning=false; } } public class RotateObj : MonoBehaviour { void Update () { transform.Rotate(new Vector3(0,180*Time.deltaTime,1*Time.deltaTime)); } } public class FrameClock : MonoBehaviour { //this class is an attempt to make a system that tells you if you got time to do another batch in a loop, //or if you should do a yield and let the other functions within the system keep a good frame-rate // graphics in heavier games takes about 30% of each frame, so for now I'm starting with 80% of previous delta private float currentTime; private float timeOutTime; private float _percentage = 0.8f; private float previousDelta; private float _minFPS = 0.040f; //in case the previous deltatime was horrible long. set to zero to ignore(not recommended here, long deltatime will domino) private float _maxFPS = 0.015f; //in case the previous deltatime was horrible short. set to zero to ignore private float currentDelta; private bool _outOfTime=true; public bool isOn=false; private void Update() { reset(); } public int SetPercentage { get{return (int)_percentage * 100;} set{_percentage = (float)value * 0.01f;} } public int minFPS { get{return (int)(_minFPS*100);} set{_minFPS = (float)(1/value);} } public int maxFPS { get{return (int)(_maxFPS*100);} set{_maxFPS = (float)(1/value);} } public bool outOfTime { get{ CheckTime(); return _outOfTime; } set{ _outOfTime=value; } } public void reset() //use this function from some monobehaviour Updatefunction { currentTime =Time.realtimeSinceStartup; previousDelta = Time.deltaTime * _percentage; if (previousDelta > _minFPS) previousDelta = _minFPS; if (previousDelta < _maxFPS) previousDelta = _maxFPS; timeOutTime = currentTime + previousDelta; } void CheckTime() { currentTime =Time.realtimeSinceStartup; if(currentTime < timeOutTime) _outOfTime = false; else _outOfTime = true; if(isOn==false) outOfTime=false; } }
Hope someone else can get some use out of this. By the way, you have to be a bit careful about how you write coroutine functions: since they are working on things out-of-sync, if your next line of code assumes that the job is done before its done, things will get pear-shaped.
Edited by duke_Qa, 20 July 2012 - 08:06 AM.