Exemple #1
0
        public static void Open(string title, List <ArrayCopyAndPasteInfo> arrayCopyAndPasteInfos, Action <ArrayCopyAndPasteInfo> action)
        {
            if (_window == null)
            {
                _window = CreateInstance <CopyAndPasteChoiceWindow>();
            }

            _window.Init(title, arrayCopyAndPasteInfos, action);
            _window.ShowUtility();
        }
Exemple #2
0
        private static void ArrayCopyAndPaste(bool isOverride, params MonoBehaviour[] monoBehaviours)
        {
            var arrayCopyAndPasteInfos = new System.Collections.Generic.List <ArrayCopyAndPasteInfo>();

            foreach (var mono in monoBehaviours)
            {
                var type      = mono.GetType();
                var allFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.Instance);

                foreach (var info in allFields)
                {
                    //PrivateFieldはSerializeFieldAttributeが指定されてないものは対象にできない
                    if (info.IsPrivate && info.GetCustomAttributes(typeof(SerializeField), false).Any() == false)
                    {
                        continue;
                    }

                    //複数の場合があるので、どの配列に対して、どのインデックスから(追加か、上書きか)張り付けるかを判断するためのwindowを表示する
                    var pasteInfo = new ArrayCopyAndPasteInfo
                    {
                        IsOverride          = isOverride,
                        TargetMonoBehaviour = mono,
                        TargetFieldInfo     = info,
                    };

                    //配列かListか単品か判断
                    var arrayType = info.FieldType;
                    if (arrayType.IsGenericType && arrayType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List <>))
                    {
                        pasteInfo.IsTypeList = true;
                    }
                    else if (arrayType.IsArray)
                    {
                        pasteInfo.IsTypeList = false;
                    }
                    else
                    {
                        pasteInfo.IsSingle = true;
                    }

                    //配列(またはList)の要素のType
                    if (pasteInfo.IsSingle)
                    {
                        pasteInfo.ArrayElementType = info.FieldType;
                    }
                    else
                    {
                        pasteInfo.ArrayElementType = pasteInfo.IsTypeList ? arrayType.GetGenericArguments().FirstOrDefault() : arrayType.GetElementType();
                    }
                    if (pasteInfo.ArrayElementType == null)
                    {
                        continue;
                    }

                    //対象がこのMonoBehaviourのこのFieldだった場合のコピー元から張り付ける事ができる要素をまとめる
                    pasteInfo.CopySrcDatas = _data.Select(o =>
                    {
                        if (o.GetType() == pasteInfo.ArrayElementType)
                        {
                            return(o);
                        }

                        Debug.Log(pasteInfo.ArrayElementType.Name);
                        if (pasteInfo.ArrayElementType.IsSubclassOf(typeof(Component)))
                        {
                            var attachedComponent = (o as GameObject)?.GetComponent(pasteInfo.ArrayElementType);
                            if (attachedComponent?.GetType() == pasteInfo.ArrayElementType)
                            {
                                return(attachedComponent);
                            }
                        }
                        return(AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(o), pasteInfo.ArrayElementType));//TODO Spriteそのものの場合と、Spriteを持っているTextureの場合がある
                    }).Where(o => o != null).ToArray();

                    if (pasteInfo.CopySrcDatas.Any() == false)
                    {
                        continue;                                        //コピー元が張り付ける先が無かった
                    }
                    if (pasteInfo.IsTypeList)
                    {
                        var originalData = pasteInfo.TargetFieldInfo.GetValue(pasteInfo.TargetMonoBehaviour) as IList;
                        pasteInfo.OriginalDatas = new Object[originalData.Count];
                        originalData.CopyTo(pasteInfo.OriginalDatas, 0);
                    }
                    else if (pasteInfo.IsSingle)
                    {
                        var originalData = pasteInfo.TargetFieldInfo.GetValue(pasteInfo.TargetMonoBehaviour) as Object;
                        pasteInfo.OriginalDatas = new [] { originalData };
                    }
                    else
                    {
                        var originalData = pasteInfo.TargetFieldInfo.GetValue(pasteInfo.TargetMonoBehaviour) as Array;
                        pasteInfo.OriginalDatas = originalData as Object[];
                    }

                    pasteInfo.DisplayName = pasteInfo.TargetFieldInfo.DeclaringType.FullName + Environment.NewLine;

                    if (pasteInfo.IsSingle)
                    {
                        pasteInfo.DisplayName += pasteInfo.ArrayElementType.Name;
                    }
                    else if (pasteInfo.IsTypeList)
                    {
                        pasteInfo.DisplayName += "List<" + pasteInfo.ArrayElementType.Name + "> ";
                    }
                    else
                    {
                        pasteInfo.DisplayName += pasteInfo.ArrayElementType.Name + "[] ";
                    }

                    pasteInfo.DisplayName += pasteInfo.TargetFieldInfo.Name;

                    arrayCopyAndPasteInfos.Add(pasteInfo);
                }
            }

            //TODO 対象が1つしか無かった場合にWindowを出すべきかどうか悩むところ
            if (arrayCopyAndPasteInfos.Any())
            {
                var message = arrayCopyAndPasteInfos.Count == 1 ? "以下のFieldが候補にあがりました。よろしいですか?" : "複数のFieldが候補にあがりました。どちらのFieldにペーストしますか?";
                CopyAndPasteChoiceWindow.Open(message, arrayCopyAndPasteInfos, pasteInfo =>
                {
                    if (pasteInfo != null)
                    {
                        CopyProcess(pasteInfo);
                    }
                });
            }
        }