2014年11月4日 星期二

Unity script hash code not compatible

1. prefab attach的script更新之後,將prefab包成Asset bundle,包出去之後。下次包版時,script有異動,但是即使Untiy 做Save project的動作,都不會造成prefab本身有任何異動,所以只有script再包出去,結果新的程式讀到舊的AssetBundle,就會造成錯誤。Untiy報的錯誤是 script hash code not compatible。

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);
    }
}