Recently idle to have nothing to do, remember unity3d related to some knowledge points, also as note storage. Reprint please indicate source: http://www.cnblogs.com/zblade/
1. How does unity call Start/awake and other related functions?
A common problem in unity is the order of execution of related functions such as awake, start, and update, which is not discussed here, and a more in-depth question is how to invoke these functions. If this is an overload of a virtual function, then why don't we have the override keyword? I looked it up and there was a related question, probably in 2 directions. One is the source code display, Unity's mono supports string fetching of function names, and then makes reflection calls after acquiring these function names. In fact, the more plain, is inherited from the mono class, unity will be the function of the reference statistics, at each frame call, for non-null function, will perform a traversal reflection callback. Many people think that the impact of reflection on the performance of a large, in fact, can be cached, in the first reflection after the execution of the cache, the next execution can be directly from the cache, directly executed, so many people test found that the performance of reflection close to function calls, this is the principle.
2, the principle of Atlas and the reasons for using Atlas?
The essence of the Atlas, in fact, is a large map, a small map of the various atlas into a large map, and then there is a copy of the size of each small map, location, offset and other information data files, so generally a graph assembly corresponds to 2 files, of course, if the data files are also packaged in, there will be only one data file.
There are several reasons for using Atlas: first, the use of Atlas can easily manage the picture resources, second, each time you draw a graph, will be in the GPU phase into a picture in, such an operation will trigger a drawcall, if there are dozens of hundred graphs, then each time in the conversion, Will trigger multiple drawcall, using the atlas, you can only trigger once drawcall, all the relevant pictures are plugged in, thereby greatly reducing drawcall; Finally, the use of Atlas is also convenient for loading and unloading of picture resources.
3. Some questions about LUA
1) The Principle of table implementation in LUA
LUA's design for table is based on the common compatibility of arrays and hashes, and for arrays, which mainly store contiguous data of the same type, the hash is stored by means of key-value. For hash and array, the default size is 0, then 1,2,4 and so on based on the power of 2 increments, because each increment, will do a rehash, so the performance is consumed on the rehash, so when the table is created, try to avoid such rehash operations, such as:
Local T1 = {} t["X"] =1, t["y"] =2, t["z"] = 3, so that three operations, will trigger three times rehash, think of the principle to understand
Local T2 = {"X" = 1, "Y" = 2, "Z" = 3}, which will trigger only one rehash and save 3 performance.
2) Please answer the lookup procedure for key values in Lua
Lua's lookup of the key value first looks for the corresponding key value in the array and hash, returns if it exists, finds if the table has a meta table metatable if it does not exist, and if not, returns nil, if any, to see if there is a __ in metatable The index method, if not, returns nil, or, if any, executes __index[key] lookup, returning the corresponding value.
3) How LUA performs the GC, and the corresponding principles and API settings
LUA GC principle, recommended that you read the cloud in the blog for the detailed process of GC , combined with source code, there is a more detailed explanation of the process:Lua GC source code Analysis
Here's a post-reading note:
(1) Lua GC Object
A total of 9 data types in Lua are nil, Boolean, Lightuserdata, number, string, table, function, UserData, and thread. Where string, table, function, thread are processed by GC, and Proto and Upvalue need to be processed by GC.
(2) Lua data definition method Union + Type
// Union of all Lua values typedef union{ Gcobject* GC; void* p; Lua_number N; int b;} Value; #define Tvaluefields value value; int struct lua_tvalue{ tvaluefields;} TValue
All gcobject have an identical data header, Commonheader, which is defined as:
#define Commonheader gcobject* Next; Lu_byte tt; Lu_byte marked;
All gcobject are then strung together by the same one-way list, with each object based on the TT identification, marked to mark the cleanup work
(3) Lua classification of different types of cleanup operations
Lua is divided into several types each time the GC clears:
For Gcobject, through a number of root nodes, one by one, directly or indirectly, all of the nodes on the left of the tag, after the completion of the tag, the linked list is traversed, the node is not marked to delete operations;
For string types, because all strings are placed in a large hash table, this is to ensure that the same string in the entire LUA is not created two copies, so it is managed separately and will not be strung in the Gcobject list
For the Upvalue type data, it is also a special process, because the GC may be distributed scanning, because Upvalue is an indirect reference to an existing object, when created does not belong to the creation of new data, in Mark's process need to add luac_barrier
For UserData, since UserData has a GC method, the GC method will be executed at the end of the process by traversing all the userdata individually, and there will be some special processing
(4) Several processes that LUA performs in GC
A few of the processes that LUA performs GC can be divided into 5 steps: gcspause\ gcspropagate\gcssweepstring\gcssweep\gcsfinalize, distributing GC from lua5.1 onwards, multiple state transitions per execution
Gcspause is the boot process for the GC phase, marking the root node of the system to
Gcspropagate This is a tagging process that iterates over an object that has not been tagged (a gray list) (repeatedly calls Propagatemark), otherwise executes the token once in the atomic function
Gcssweepstring This is the string type of data that was mentioned earlier, for special processing, in which each step clears a column in the hash table of the string
Gcssweep and the previous state class are, but the object of this step is Gcobject
Gcsfinalize is here primarily for UserData, and if it needs to invoke its GC, the GC operation is performed, because UserData objects and associated data are not purged in the previous purge phase, so their actual cleanup will be performed in the next GC cleanup or in the Lua_ Cleared in close: Lua_close's job is to simply handle all UserData's GC meta-methods and release the memory it uses.
(5) The tagging process for Lua GC
LUA sets a color for all gcobject, initially white, the new node is also white, and then in the tagging phase, the visible nodes are set to black, and if some nodes are associated with other nodes, they are marked dimmed before their associated nodes are processed, and for color markers, It is stored in the Commonheader 8-bit marked domain, for White has two white mark bit, with a ping-pong switch, to avoid the completion of the mark after the cleanup is not completed, the relationship between objects changes, some do not need to be cleaned up the node, Can be converted from one type of white to another type of white, such as the current deletion of type 0 white, then converted to type 1 white, so that the type 1 white will be protected will not be removed, and vice versa. Specifically for the definition and use of 8 bits, you can see the original text of the cloud wind, there is a certain explanation.
(6) Operation of Lua GC
A few api:luac_fullgc\ luac_step\luac_checkgc commonly used
LUAC_FULLGC: Perform a full GC action, for the possible execution of the general process, after the completion of a process, will block the state to perform the GC again, for the first half of the already executed GC, actually do not need to do the cleanup operation, only need to do a status reply
Luac_step: Its core in the call SingleStep function, by setting the Gcstepmul value, you can set the step size, thereby affecting the gcthreshold, in fact, the setting of the step amount, is an empirical value
LUAC_CHECKGC: An automatic GC interface that calls this method in most of the APIs that cause memory growth, automatic GC, which may mark many temporary objects in a certain periodicity, causing the system to occupy a higher peak memory footprint than is actually required. The Gcstep method can be used in this periodic call, and a large data volume is set, which makes the finite period a complete GC.
(7) The mark operation of Lua GC
For the mark operation of Lua, the main operational api:markroot\ reallymarkobject\remarkupvals\atomic\iscleared
(8) Write barrier operation for Lua GC
The main Api:luac_barrier\luac_barriert\luac_objbarrier\luac_objbarriert
(9) The remaining operation of the Lua GC Sweep/finalize
Sweep operation is divided into gcssweepstring and gcsseep, paste 2 source code:
Casegcssweepstring: {lu_mem old= g->totalbytes; Sweepwholelist (L,&g->strt.hash[g->sweepstrgc++]); if(G->SWEEPSTRGC >= g->strt.size)/*To sweep?*/g->gcstate = Gcssweep;/*End sweep-string Phase*/Lua_assert ( old>= g->totalbytes); G->estimate-= old-g->totalbytes; returnGcsweepcost; } Casegcssweep: {lu_mem old= g->totalbytes; G->SWEEPGC = Sweeplist (L, g->SWEEPGC, Gcsweepmax); if(*G->SWEEPGC = = NULL) {/*To sweep?*/checksizes (L); G->gcstate = gcsfinalize;/*End Sweep Phase*/} lua_assert ( old>= g->totalbytes); G->estimate-= old-g->totalbytes; returngcsweepmax*Gcsweepcost; }
For Seeplist, the source code is:
StaticGcobject **sweeplist (lua_state *l, Gcobject * *p, lu_mem count) {Gcobject*Curr; Global_state*g =G (L); intDeadmask =Otherwhite (g); while((Curr = *p)! = NULL && count-->0) { if(curr->gch.tt = = Lua_tthread)/*Sweep Open upvalues of each thread*/sweepwholelist (L,&gco2th (Curr)openupval); if((curr->gch.marked ^ whitebits) & Deadmask) {/*Not dead?*/Lua_assert (!isdead (g, Curr) | | Testbit (curr->gch.marked, fixedbit)); Makewhite (g, Curr); /*Make it white (for next cycle)*/P= &curr->Gch.next; } Else{/*must erase ' Curr '*/Lua_assert (Isdead (g, Curr)|| Deadmask = =bitmask (sfixedbit)); *p = curr->Gch.next; if(Curr = = G->ROOTGC)/*is the first element of the list?*/g->ROOTGC = curr->gch.next;/*Adjust First*/freeobj (L, Curr); } } returnp;}
Basic look at the source code can be understood, for dead freeobj, there is no dead execution makewhite, the last process is GCs finalize, through the GCTM function execution, each call a UserData to reclaim the GC meta-method:
Static voidGCTM (Lua_state *L) {global_state*g =G (L); Gcobject*o = g->tmudata->gch.next;/*Get first element*/Udata*udata =rawgco2u (o); ConstTValue *TM; /*remove Udata from ' tmudata '*/ if(o = = g->tmudata)/*Last element?*/g->tmudata =NULL; Elseg->tmudata->gch.next = udata->Uv.next; Udata->uv.next = g->mainthread->next;/*return it to ' root ' list*/g->mainthread->next =o; Makewhite (g, O); TM= Fasttm (L, udata->uv.metatable, TM_GC); if(tm! =NULL) {Lu_byte Oldah= l->Allowhook; Lu_mem Oldt= g->Gcthreshold; L->allowhook =0;/*Stop debug hooks during GC tag method*/g->gcthreshold =2*g->totalbytes;/*Avoid GC steps*/setobj2s (l, L-Top, TM); Setuvalue (L, L->top+1, Udata); L->top + =2; Luad_call (L, L->top-2,0); L->allowhook = Oldah;/*Restore Hooks*/g->gcthreshold = Oldt;/*Restore Threshold*/ }}
When recovering, set a larger gcthreshold to avoid the re-entry of the GC
4, unity in the understanding of the process
The nature of the process is a partial execution function, executed in Unity's mainthread, unity in each frame of the update, will execute each of the call, respectively, after Fixedupdate and lateupdate some of the call, which is essentially an iterator, When the condition is met, it will be suspended, and when the condition is met, it will be woken up to continue execution. Take an example that you see elsewhere, so it's easy to explain the process:
voidStart () {Startcoroutine (Test1 ());} IEnumerator Test1 () {Logwrapper.error ("A1"); yield returnTest2 (); Logwrapper.error ("A2");} IEnumerator Test2 () {Logwrapper.error ("B1"); yield return NULL; Logwrapper.error ("B2");}
Order of what will be output: A1, B1, B2, A2
The order of execution is to output A1 first, then execute Test2, Output B1, this time encounter yield return null, be suspended, next frame, wake up, continue execution, output b2, then execute output a2
If this process is understood, then the association is basically fine.
5. The role of meta files in unity
There are two functions, the first is to include the current resources (code or prefab, pictures, etc.) in the current project is the only GUID, Unity gets the resource is based on the GUID to obtain, so each resource will be accompanied by a meta file generated;
The second, contains the current resources of the import information, than the slice resources, will contain a bump and other related information
continued to update ing
Unity3d knowledge points to be readily remembered