2014年10月31日 星期五

Unity mono Awake() and Start() timing

Awake呼叫的時機點在於Component被產生時的那瞬間。
那什麼時候代表Component產生時的那瞬間:

  1. GameObject第一次Active的時候,就會呼叫所有Attached Components的Awake。
  2. 用程式呼叫AddComponent的時候


Start呼叫的時機點在於Component第一次Enable時的那瞬間。
那什麼時候代表Component Enable時的那瞬間:

  1. GameObject上有Implement Start或Update function這種的,在Inspector上就可以看到Script名稱旁有個Check Box,當GameObject第一次Active的時候且Check Box也是打"V"的狀態,就會呼叫Start
  2. 用程式呼叫Component.enabled = true時



Awake一定比Start還早,而且是場景上所有的Awake都結束後,才會呼叫Start。而預設各Component執行Start的順序等同各Component執行Awake的順序,除非在Awake動態改變Component的enable順序。
而Awake和Start最大的差別就在於一種情況:
當GameObject為Active,但是Component是Disabled的狀態,Awake會呼叫的但是Start是不會的。

GameObject上的Components彼此Awake的順序是?
理論上應該是新增Component的順序,但是基本上建議不要依賴這個順序,因為常常會忘記........雖然在Unity工具列的Edit->Project Settings->Script Execution Order來決定,但是一樣不方便。

GameObject之間的Components彼此Awake的順序是?
Unity並未定義GameObject之間的執行順序,一樣建議不要仰賴GameObject的Hierarchy來決定Components之間Awake的順序。


如果真的Components之間或GameObjects之間在Initial之間是有耦合狀態的,建議還是一個Master Script來管理,看是要動態新增GameObject或是動態新增Component,亦或是動態Enable GameObject或Component。




2014年10月15日 星期三

unity render material and shared material

Unity內的render.sharedMaterial,代表的是所有Unity內都使用這份,每次更換屬性時,如果這份是存在Asset內的話,就會發現這份也被修改過(用SVN就可檢查是否被修改)。

用Material xx = render.material,代表是untiy所複製的一份material,每次更換這material的屬性只會改到這份複製的。如果想要讓更改的資料回render,就要做render.material = xx

因為實在太危險了,所以特此記上!!!!!

2014年6月4日 星期三

why grandson class should not call base.base.method?

主要問題是為什麼子類別不能直接呼叫base.base.method?


主要原因就是破壞物件封裝。假設今天有個collection-item的behavior class,有個child class是只能收集red item,而grand child class是只能收集big red item。如果今天grand child class不想透過parent檢查是否為red item,而直接呼叫grand parent add item,是不是有點奇怪?

public class Items
{
    public void add(Item item) { ... }
}

public class RedItems extends Items
{
    @Override
    public void add(Item item)
    {
        if (!item.isRed())
        {
            throw new NotRedItemException();
        }
        super.add(item);
    }
}

public class BigRedItems extends RedItems
{
    @Override
    public void add(Item item)
    {
        if (!item.isBig())
        {
            throw new NotBigItemException();
        }
        super.add(item);
    }
}
public class NaughtyItems extends RedItems
{
    @Override
    public void add(Item item)
    {
        // I don't care if it's red or not. Take that, RedItems!
        super.super.add(item);
    }
}




2013年10月24日 星期四

NGUI Atlas


  1. why use atlas?
    因為atlas只要一個draw call,但是會造成這張atlas內的圖的z值深度都是一樣的
  2. 不會減少圖的size
  3. 壓縮的部分在Texture的import type改成"Advenced",取消掉MipMap(因為是使用平行視角的camera)所以不需要,而圖片壓縮的Default Type改成AutoCompressed,再到各個版本去修改Default值
    (1)IOS的地方勾起Override,並且壓縮格式改成RGBA Compressed PVRTC 4,而壓縮程度改成Best。
    (2)Android的部分勾起Override,這邊根據圖片是否需要帶有Alpha透空的效果,沒有的話選擇RGB Compressed ETC1,有的話則選擇RGBA Compressed DXT5,主要是因為現行還是有部分爛手機沒有支援DXT5,不然理論上還是都選DXT5。Unity已出了新版的選項,可選擇RGB Compressed ETC2(需要OpenGL ES 3.0以上),可讓圖片帶有Alpha的也可做壓縮。如果真的想連舊型手機都要支援的話,得將原圖RGB及Alpha分成兩張圖並使用RGB Compressed ETC1,再改寫NGUI  UITexture的shader傳這兩張圖進去
  4. 最主要的Atlas還是會造成管理上的問題,因為有些會合併,有些會有兩張以上的Atlas,其實相當麻煩,目前還沒有想到好的方式來去做管理,又可以省到效能的方式。

2013年6月23日 星期日

Serialization in ios with Unity

1.         錯誤的Serialize程式碼
[Serializable]
public class MyClass { …………………}

// Same as
XmlSerializer 
MyClass myClass = new MyClass();
IFormatter formatter = new BinaryFormatter();//
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, myClass);

Error Message in ios:
Unhandled Exception: System.ExecutionEngineException: Attempting to JIT compile method 'UInt32__TypeMetadata:.ctor ()' while running with --aot-only.

2.         What JIT and AOT
   
是兩種不同的compile方式。主要用於在intermediate language(解譯式語言)像是java或者.NET Common Intermediate Language (managed code)
   
因為像這種intermediate language都要經過一道解譯後,執行起來就會比較慢。這兩種方式都是用來改善效能的,AOT是預先將byte code直接與VM compilemachine code,而JIT則是在解譯時動態的預先做一些cache或分析來達到效能最佳化。
AOT: http://en.wikipedia.org/wiki/AOT_compiler
JIT: http://en.wikipedia.org/wiki/Just-in-time_compilation
4.         Another Serialize library
I.          JsonFX: http://www.jsonfx.net/
II.         Protobuf-net: https://code.google.com/p/protobuf-net/
5.         Using Protobuf-net in ios -http://wiki.etc.cmu.edu/unity3d/index.php/Serialization_issue_on_iOS
I.           下載protobuf-net r640版本
II.         將要SerializeData class額外用一個dll library專案,並加上protobuf-net特定的Annotation。這邊Referenceprotobuf-net dll要則選擇core onlyios內的dll
[ProtoContract]
    class MyDataClass {

       
[ProtoMember(1)]
        public int Id {get;set;}
    }
Note:不可有任何不是public的變數或method,否則在下一個Step時會出現non-public Exception.
III.       將輸出的data dllprotobuf-net.dll放在相同資料夾,使用protobuf-net內附帶的precompile.exe產生Serializerdll檔,下cmd指令為precompile {path}\ModelName.dll -o: {path}\SerializerDllName.dll -t:Namespace.SerializerTypeName
IV.      最後將三個dll(data classdllSerializerdllprotobuf-net dll)同時給其它專案Reference即可
Note:這邊要注意dll dependency的問題。因為像現在的Unity專案會使用ResouceLoder來讀const data,但是ResouceLoder class必須要放在Unity專案才行,如果的data classDllreferenceResouceLoder,這樣就會造成dll相互依賴。
6.        Serialize Library比較

C#
BinaryFormatter
protobuf-net
JsonFX
Reference
V
V
X
Extend
V
V
V
Polymorphism
V
V
X
List, Dictionary
V
V
V
In IOS
X
V
V
結論
無法使用在IOS
需要額外使用precompile
無法使用在複雜的資料結構上


2013年2月2日 星期六

Circle shape radial blur

圓狀的放射模糊,越靠近圓心的一定越清楚,離圓心越遠的越模糊。意思是說靠近圓心的貢獻度就較高,離圓心越遠的就越低。

假設一個二維的圓心是O,半徑是r,那在圓的任一點p,我們可以用 得到該點p離圓心佔半徑多少百分比。所以我們可以用(1 - ( |p - o| / r) ) * 點p的某個數值(像是顏色之類的),這樣就可以決定離越遠的點最後的數值要多少了。

實際例子:
圓形的地表筆刷在做模糊的方式就是這樣。假設我們現在要塗的Vertex顏色是紅色,所以如果我們算出來的(1 - ( |p - o| / r) ) = X好了,套用到我們這篇所講的Terrain Vertex Color公式,最後公式結果像這樣
X * strength * color + (1 - strength * X) * last time color = Final Vertex color
這樣就會看到紅色從圓心的中間慢慢的變淡紅,最後變成接近跟背景色是相同的。

Learn new program language skill

  1. 找到好的開發環境,像是Compiler和Editor
  2. 上找些基本的Hello word、Example或Tutorial文件
  3. 學習基本的資料型態使用
  4. 試著建立一個基本的hello word的環境
  5. 找到API文件
  6. 試著看有沒有基本的Debug方式,像是中斷點之類的