/// <summary> /// from のプロパティの内容をリフレクションで to に反映 /// </summary> public static bool CopyProps(Object from, Object to) { var fromProps = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList(); var toProps = to.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList(); if (fromProps.Count == 0) { AltoLog.Error($"[ObjectUtil] PropertyInfo of from-object is null."); return(false); } if (toProps.Count == 0) { AltoLog.Error($"[ObjectUtil] PropertyInfo of to-object is null."); return(false); } foreach (var toProp in toProps) { var fromProp = fromProps.Find(prop => { return(prop.Name == toProp.Name && prop.PropertyType == toProp.PropertyType); }); if (fromProp == null) { AltoLog.Error($"[ObjectUtil] Property not found : {toProp.Name}"); return(false); } object fromValue = fromProp.GetValue(from, null); toProp.SetValue(to, fromValue, null); } return(true); }
/// <summary> /// from のフィールドの内容をリフレクションで to に反映 /// </summary> public static bool CopyFields(Object from, Object to) { var fromFields = from.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).ToList(); var toFields = to.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).ToList(); if (fromFields.Count == 0) { AltoLog.Error($"[ObjectUtil] FieldInfo of from-object is null."); return(false); } if (toFields.Count == 0) { AltoLog.Error($"[ObjectUtil] FieldInfo of to-object is null."); return(false); } foreach (var toField in toFields) { var fromField = fromFields.Find(field => { return(field.Name == toField.Name && field.MemberType == toField.MemberType); }); if (fromField == null) { AltoLog.Error($"[ObjectUtil] Field not found : {toField.Name}"); return(false); } object fromValue = fromField.GetValue(from); toField.SetValue(to, fromValue); } return(true); }
/// <summary> /// TryParse のラップ版。Enum.TryParse() は "123" といった数字文字列が渡されたときに /// エラーにならないので、ここでは定義済みの Enum であるかどうかのチェックを含めている /// </summary> public static bool TryParse <T>(string str, out T result) where T : struct { bool parsed = Enum.TryParse(str, out result) && Enum.IsDefined(typeof(T), result); if (!parsed) { AltoLog.Error($"[EnumUtil] Parse error : {str}"); } return(parsed); }
/// <summary> /// "1" や "2" といった数字文字列を Enum の値に変換する。 /// 空文字列の場合は 0 として扱う /// </summary> public static T FromNumericString <T>(string str) where T : struct { if (str == String.Empty) { return(EnumUtil.FromInt <T>(0)); } try { T value = (T)Enum.ToObject(typeof(T), int.Parse(str)); return(value); } catch (Exception ex) { AltoLog.Error($"[EnumUtil] Parse error : {str}"); throw ex; } }
/// <summary> /// 選択したオブジェクトを、選択したもののうち Hierarchy の index の若い 2 つの座標 /// を基準にして等間隔に並べる。(選択順が取得できなかったのでこんな仕様) /// </summary> void ArrangeByFirstTwo() { var objs = Selection.gameObjects.OrderBy(go => go.transform.GetSiblingIndex()).ToList(); if (objs.Count <= 2) { AltoLog.Error("3 つ以上のオブジェクトを選択してください"); return; } var first = objs[0]; var second = objs[1]; Vector3 diff = second.transform.position - first.transform.position; for (int i = 2; i < objs.Count; ++i) { Vector3 pos = first.transform.position + (i * diff); Undo.RecordObject(objs[i].transform, "ArrangeByFirstTwo"); objs[i].transform.position = pos; } }
static void ImportCsv( string csvPath, string dataName, string dataPath, Func <string, Type> dataTypeGetter ) { AltoLog.Info($"Master data csv update detected : { csvPath }"); string destDataPath = $"{ dataPath }{ dataName }.asset"; var data = AssetDatabase.LoadMainAssetAtPath(destDataPath); if (data == null) { AltoLog.Error($"Master data ScriptableObject not exist : { destDataPath }"); return; } var type = dataTypeGetter(dataName); if (type == null) { AltoLog.Error($"Type reflection failed : { dataName }"); return; } MethodInfo method = type.GetMethod("Import"); if (method == null) { AltoLog.Error($"Method reflection failed"); return; } var csvLines = LoadCsvFile(csvPath); method.Invoke(data, new object[] { csvLines }); EditorUtility.SetDirty(data); AssetDatabase.SaveAssets(); AltoLog.Success($"Master data import succeeded : { dataName }"); }