Kakoのいろいろやったこと記

主にUnity関連でやったことをかいていきます

UnityのEditor拡張で、複数のオブジェクトから一括でPrefabを生成するものを書きました

これはなに?

多分標準機能であるんじゃないかな、と思っているんですが、どうしても見つからなかったので書きました。
複数Objectに何かしらちょっとルール決めて、一括でPrefabを生成しますf:id:Kakovail:20210108172420g:plain

使い方

MultiPrefabGenerator.cs をどこかにおいて、MultiPrefabGenerator/MainWindowを選択。
保存したい先のPathをコピって、Prefixつけたければつけて、数字つけたりObjectの名前を変えたいか選び、D&Dの後にボタンを押します。ボタンが最後でさえあればほかは適当に埋めてOKです。

本体

// Copyright (c) 2021 Hiroyuki Kako
// This software is released under the MIT License, see LICENSE.

#if UNITY_EDITOR
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class MultiPrefabGenerator : EditorWindow
{
    [MenuItem("KEditorExtensions/MultiPrefabGenerator")]
    private static void Open()
    {
        GetWindow<MultiPrefabGenerator>("Generate multi prefab.");
    }

    public List<GameObject> _targetObjectsInEditor;
    private static string _path;
    private static string _objectPrefix;
    private static string _objectName;
    private static bool _wannaCount;
    private static bool _wannaNaming;

    public void OnGUI()
    {
        using (new GUILayout.HorizontalScope())
        {
            _path = EditorGUILayout.TextField("Enter target path", _path);
        }

        using (new GUILayout.HorizontalScope())
        {
            _objectPrefix = EditorGUILayout.TextField("Enter prefix when needed", _objectPrefix);
        }

        using (new GUILayout.HorizontalScope())
        {
            _wannaCount = EditorGUILayout.Toggle("Use count", _wannaCount);
        }

        using (new GUILayout.HorizontalScope())
        {
            _wannaNaming = EditorGUILayout.Toggle("Use original name", _wannaNaming);
            if (_wannaNaming)
            {
                _objectName = EditorGUILayout.TextField("Enter name", _objectName);
            }
        }

        using (new GUILayout.HorizontalScope())
        {
            ScriptableObject target = this;
            SerializedObject so = new SerializedObject(target);
            SerializedProperty stringsProperty = so.FindProperty("_targetObjectsInEditor");
            EditorGUILayout.PropertyField(stringsProperty, true);
            so.ApplyModifiedProperties();
        }

        if (GUILayout.Button("GeneratePrefab"))
        {
            if (!_path.EndsWith("/")) _path += "/";
            foreach (GameObject target in _targetObjectsInEditor)
            {
                string prefab = _path + _objectPrefix + (_wannaNaming ? _objectName : target.name) +
                                (_wannaCount ? _targetObjectsInEditor.IndexOf(target).ToString() : "") + ".prefab";
                var result = PrefabUtility.SaveAsPrefabAsset(target, prefab);

                var newObject = PrefabUtility.InstantiatePrefab(result, target.transform.parent) as GameObject;
                newObject.transform.SetSiblingIndex(target.transform.GetSiblingIndex());

                DestroyImmediate(target);
            }

            _targetObjectsInEditor.Clear();
        }
    }
}
#endif
言い訳か説明かなにか
string prefab = _path + _objectPrefix + (_wannaNaming ? _objectName : target.name) +
                                (_wannaCount ? _targetObjectsInEditor.IndexOf(target).ToString() : "") + ".prefab"; 

ここが本当に無理やりですが、条件で名前を書き換えてます。はい。


最後に

楽しかったですが、標準とかであると思うので、なんかあれだなって。
追加機能等ほしい部分あればお気軽にどうぞ!書くの楽しい。