How unity Optimization implements the co-process in the Unity editor

Source: Internet
Author: User

Tag: sys dex RING View res not open more erase

When you need a co-process in the Unity editor

When we customize the Unity Editor, we often need to start an additional process or thread. For example, when performing some interface updates, requires a large number of calculations, if the user is constantly correcting a parameter, such as from 1 to 2, this change process to go through countless intermediate steps, call n multiple update, if the update is constantly refreshed, the interface is easy to directly die. So in a process to do some optimization, only retain the user last parameter correction, eliminating the intermediate steps, it will be much better. This is the content of the Unity Editor, the content of optimization, or the optimization.

Problem-solving ideas

There are also a lot of people searching for this in Unity's questions, but later it was seen that someone mentioned the method. The key point of the problem is "editorapplication.update", and there is a way to pass the execution of the process to it to automatically execute the loop call under the editor.

The wording of the foreigner

Of course, later I also found a foreigner's writing, code paste out as follows:

usingUnityengine;usingUnityeditor;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Runtime.CompilerServices; Public Static classeditorcoroutinerunner{Private classEditorcoroutine:ienumerator {PrivateStack<ienumerator> Executionstack; Public Editorcoroutine(IEnumerator iterator) { This. Executionstack =NewStack<ienumerator> (); This. Executionstack.push (iterator); } Public BOOL MoveNext() {IEnumerator i = This. Executionstack.peek ();if(I.movenext ()) {Objectresult = I.current;if(Result! =NULL&& result isIEnumerator) { This. Executionstack.push ((IEnumerator) result); }return true; }Else{if( This. Executionstack.count >1)                { This. Executionstack.pop ();return true; }            }return false; } Public void Reset()        {Throw NewSystem.NotSupportedException ("This operation was not supported."); } Public ObjectCurrent {Get{return  This. Executionstack.peek (). Current; }        } Public BOOL Find(IEnumerator iterator) {return  This. Executionstack.contains (iterator); }    }Private StaticList<editorcoroutine> editorcoroutinelist;Private StaticList<ienumerator> buffer; Public StaticIEnumeratorStarteditorcoroutine(IEnumerator iterator) {if(Editorcoroutinelist = =NULL) {editorcoroutinelist =NewList<editorcoroutine> (); }if(Buffer = =NULL) {buffer =NewList<ienumerator> (); }if(Editorcoroutinelist.count = =0{editorapplication.update + = update; }//Add iterator to buffer firstBuffer. ADD (iterator);returnIterator }Private Static BOOL Find(IEnumerator iterator) {//If This iterator is already added        //Then ignore it this time        foreach(Editorcoroutine EditorcoroutineinchEditorcoroutinelist) {if(Editorcoroutine.find (iterator)) {return true; }        }return false; }Private Static void Update()    {//Editorcoroutine execution may append new iterators to buffer        //Therefore We should run Editorcoroutine firstEditorcoroutinelist.removeall (coroutine = {returnCoroutine. MoveNext () = =false; }        );//If We have the iterators in buffer        if(buffer. Count >0)        {foreach(IEnumerator iteratorinchBuffer) {//If This iterators not exists                if(! Find (iterator)) {//Added this as new EditorcoroutineEditorcoroutinelist.add (NewEditorcoroutine (iterator)); }            }//Clear bufferBuffer.        Clear (); }//If We have no running editorcoroutine        //Stop calling Update anymore        if(Editorcoroutinelist.count = =0{editorapplication.update-= update; }    }}

The usage is to slightly modify the start method of your own class, and then add a co-function, as follows:

 void  Start () {            Rope = gameobject.getcomponent<quickrope> (); #if  unity_editor  //Call method  Editorcoroutinerunner.starteditorcoroutine (Onthreadloop ());        #endif  } public  IEnumerator onthreadloop  () {while  (
    
     true ) {Debug.Log (
     ); yield  return             null ; }        }
    

Of course, it is best to add # if Unity_editor preprocessing. This class basically satisfies the requirements. If you make such a modification to your own script, it can be executed in the editing state continuously to loop, note that it needs to be executed to start first, that is, you may need to make gameobject into a prefab, then remove it from the scene, and then drag prefab back to the scene, Activates the loop by triggering the Star method on the script in the edit state.

My wording

However, after a long time you will find a few problems, once the loop begins, you can not stop, even if you delete gameobject from the scene is useless, of course, hidden also has no effect. In order to solve this problem, but also make the script simple, I rewrite the script, I hope that the students need to be happy to use.

usingUnityengine;usingUnityeditor;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Runtime.CompilerServices; Public Static classeditorcoroutinelooper{Private StaticDictionary<ienumerator,monobehaviour> m_loopers =NewDictionary<ienumerator,monobehaviour> ();Private Static BOOLm_started =false;//   <summary>     ///   open Loop    //   </summary>     //   <param name= "MB" > scripts </param>     ///   <param name= "iterator" > methods </param>      Public Static void Startloop(monobehaviour MB, IEnumerator iterator) {if(mb!=NULL&& Iterator! =NULL)        {if(!m_loopers. ContainsKey (iterator)) {m_loopers.            ADD (ITERATOR,MB); }Else{M_LOOPERS[ITERATOR]=MB; }        }if(! m_started) {m_started =true;        Editorapplication.update + = update; }    }Private StaticList<ienumerator> m_dropitems=NewList<ienumerator> ();Private Static void Update()    {if(M_loopers. Count >0)        {varAllItems = M_loopers. GetEnumerator (); while(Allitems.movenext ()) {varitem = allitems.current;varMB = Item. Value;//Discard looper on unload                if(MB = =NULL{M_dropitems.add (item). Key);Continue; }//Do not execute loop when hidden                if(!mb.gameobject.activeinhierarchy) {Continue; }//execute loop, execute and discard LooperIEnumerator ie = Item. Key;if(!ie. MoveNext ()) {M_dropitems.add (item.                Key); }            }//centralize disposal of discarded looper             for(inti =0; i < m_dropitems.count;i++) {if(M_dropitems[i]! =NULL) {m_loopers.                Remove (M_dropitems[i]);        }} m_dropitems.clear (); }if(M_loopers. Count = =0{editorapplication.update-= update; m_started =false; }    }}
//调用方法原来这个样            EditorCoroutineRunner.StartEditorCoroutine(OnThreadLoop());//现在改成这个样            EditorCoroutineLooper.StartLoop(this,OnThreadLoop());

Using this script, you need to pass two parameters, one is your own script, the other is the co-function. The principle is that the code will detect your script state, and when the script is closed or unloaded, it will stop the loop call. Foreigners sometimes write code, is not so fastidious, there is no?

How unity Optimization implements the co-process in the Unity editor

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.