什麼情況下會用到動態Copy component value,因為如果在Unity編輯下,不同物件上有相同的Component可以用Multi-select物件的方式來一齊設定數值,但如果是在遊戲運行中,動態建立一個有這個Component物件的時候就有可能需要重新設定Component上的數值,尤其動態建立的物件不是從預先製作好的prefab來產生的時候,Component上的數值都會是預設的原始數值。
增加一個Component到物件上是使用AddComponent()的方法,如果想要複製一個物件上已經有的Component到新物件上,一般來說複製一個Component可以這樣
//先取得目標物件上的Component並取得此Component的type,這邊測試直接使用已知的type Component source = sourceObj.GetComponent(typeof(MyClass)); System.Type type = source.GetType(); targetGameObject.AddComponent(type);
不過如果只是這樣AddComponent的話會發現,雖然是有把Component複製到這個物件上,但是原本物件上Component設定的數值並沒有一起複製過來,這個新加到物件上的Component數值都是初始化的狀態,這個不是我想要的狀態。
當然可以一個field一個field複製數值,但是如果field數量很多,或是後來有增減一些field,那這個一個一個field複製的方法就要同時修改,這就有點浪費時間了。
所以這邊可以考慮的作法就是使用Reflection把所有的field數值複製過去,但是因為是用Reflection所以同時必須要考慮效率的問題,Reflection有些耗效能,這樣的方式最好不要每個frame一直呼叫。
Component source = sourceObj.GetComponent(typeof(MyClass)); System.Type type = source .GetType(); //同樣先取得Component的type Component target = targetGameObject.AddComponent(type); //先把這個類型的初始Component加到物件上 System.Reflection.FieldInfo[] fields = type.GetFields(); //使用Reflection取得此type上的所有fields foreach(System.Reflection.FieldInfo field in fields) { field.SetValue(target, field.GetValue(source)); //把來源Component上的所有field數值設定到目標Component上 }
把這個功能做成方法,當然使用上還是有些限制,但是一般自己做的Script上面public的field應該都可以正常的複製加上去。
public void AddCopyComponent(GameObject target, Component source) { System.Type type = source.GetType(); Component copy = target.AddComponent(type); System.Reflection.FieldInfo[] fields = type.GetFields(); foreach(System.Reflection.FieldInfo field in fields) { field.SetValue(target, field.GetValue(source)); } }
No comments:
Post a Comment