見出し画像

VRChat 買った衣装をUnityプロジェクト内でウォークインクローゼット化する

目的

以下のように、単一プロジェクトにアバター用の衣装・アクセサリをまとめてimportし、ウォークインクローゼットのように見れるようにする。


0.前提条件とおすすめ条件とトラップ


●前提条件
・今回のウォークインクローゼットは、UnityのEditorモードのSceneウィンドウで見て回る・またはPlayモードのGameウィンドウで見て回るものとする。
・処理対象のUnityPackageは「アバター以外」「ツール以外」「衣装・アクセサリ」であること。今回はプロジェクトをWorldとするため、AvatarDescriptorはエラーとなる可能性が高い。AvatarSDKとWorldSDKは排他である。

●おすすめ条件
服のみ・アクセサリのみ・髪型のみなど、種類ごとにUnityProjectをわけたほうがよい。服とアクセサリのサイズ差が大きく、ピアスはとても見えにくい。アクセサリプロジェクトはScaleすべて10倍などと大雑把にサイズ制御できる。

●トラップ
・UnityPackage配布ツール類はエラーとなる可能性が高いため除去する必要がある。
・Packageの中にシェーダが組み込まれている場合、importしたときに何で上書きされるか、最終的にどのバージョンが残るか、不定である。そのため消して入れなおす必要がある。
・importするアセット数とテクスチャサイズにより、マシンリソースを大量に消費する。importしたあと最低でもテクスチャサイズの縮小を忘れないこと。
本noteの手順に対応項目を入れたが、念のためトラップとしてあげておく。

1.VCCでプロジェクトをつくる(WORLD)

前提条件にも挙げたように、今回のウォークインクローゼットは、UnityのEditorモードのSceneウィンドウで見て回る・またはPlayモードのGameウィンドウで見て回るものとするため、Worldでプロジェクトを作成する。

2.ZIPを展開してunityPackageをつくる

Explorerで拡張子zipを検索する。

7zipなら右クリックでまとめて展開できる。
展開したUnityPackageは、importするツールで指定する場所に格納する。

3.UnityPackageをぜんぶimportする:ツール使用

ベースツール

↑のプログラムをさらに、ChatGPTに聞いて改造した。

ツール改造結果

改造内容:import対象のPackage一覧で、デフォルトでチェックボックスをONにする。
以下は、改造したプログラムである。

UnityPackageをぜんぶimportするツール

PrefabPathDisplayerEditor.cs
Unity上の置き場:*asset下の任意のフォルダ*\Editor
コンパイル成功するとメニューのTool/Batch Importerができる。

"アセットの保存場所"を自分が使うパスに書き換えること。\はエスケープして\\ね。
書き換えなくても、ウインドウで更新できた。

using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class BatchImporterWindow : EditorWindow
{
    private string rootFolderPath = "アセットの保存場所";
    private Vector2 scrollPosition;
    private bool[] packageToggles;
    private string[] packagePaths;

    [MenuItem("Tools/Batch Importer")]
    public static void ShowWindow()
    {
        GetWindow<BatchImporterWindow>("Batch Importer");
    }

    private void OnEnable()
    {
        FindPackages();
    }

    private void OnGUI()
    {
        EditorGUILayout.LabelField("Batch Importer", EditorStyles.boldLabel);
        EditorGUILayout.LabelField("Root Folder Path", EditorStyles.label);
        rootFolderPath = EditorGUILayout.TextField(rootFolderPath);

        if (GUILayout.Button("Refresh Package List"))
        {
            FindPackages();
        }

        EditorGUILayout.Space();
        EditorGUILayout.LabelField("Packages", EditorStyles.label);

        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

        for (int i = 0; i < packagePaths.Length; i++)
        {
            packageToggles[i] = EditorGUILayout.ToggleLeft(Path.GetFileName(packagePaths[i]), packageToggles[i]);
        }

        EditorGUILayout.EndScrollView();

        if (GUILayout.Button("Import Selected Packages"))
        {
            ImportSelectedPackages();
        }
    }

    private void FindPackages()
    {
        packagePaths = Directory.GetFiles(rootFolderPath, "*.unitypackage", SearchOption.AllDirectories);
        packageToggles = new bool[packagePaths.Length];
        for (int i = 0; i < packageToggles.Length; i++)
        {
            packageToggles[i] = true; // すべてのチェックボックスをデフォルトでチェック済みに設定
        }
    }

    private void ImportSelectedPackages()
    {
        for (int i = 0; i < packagePaths.Length; i++)
        {
            if (packageToggles[i])
            {
                AssetDatabase.ImportPackage(packagePaths[i], false);
            }
        }
    }
}

4.textureをすべて縮小する

すべてのPrefabをHierarchyに入れると、大量のテクスチャでVRAMが枯渇する。ローカルプロジェクトと割り切り、それを防ぐためにtextureをすべて縮小する。MaxSize:1024あたり、もっと小さくてもよい。どうせ自分しか見ない、不満が出たら個別で拡大すればよい。

・texture検索

・textureのみを選択

・texturedのMax Sizeを変更

5.Prefabを全検索してHierarchyに入れる

Unityの検索でprefabを指定。


すべて出てきたprefabを手でHierarchyにD&Dする。
あとでTransformを一気に変更するために、Prefabは空のGameObjectの配下に入れる。

6.シェーダ・エラースクリプト・ツールを除去する

以下の問題が発生している可能性がある。
・同一シェーダの重複import
 3Dアセットpackageにシェーダが同封されている場合、デグレの原因なので除去する。
・3Dアセットでない、ツールアセット
 Assetsから削除してよい。
・エラーとなっているもの

7.シェーダをimportする

シェーダはpackageに一緒に入っている場合もあるため、意図したバージョンの単一パッケージのみにすることを目的とする。
1.前手順にもあるが、packageのimportで一緒に入ってしまったシェーダをできる限り除去する。
2.VCCインストールか手動インストールでシェーダをインストールする。
ピンクでよければシェーダimportを省略してもよい。

8.問題を解消する

この時点でいろいろなエラーが発生している可能性がたかい。
できる限りエラーを解消する。できる限りでよい。
目的の「EditモードでのSceneウィンドウで見れる」「Playモードに入れる」が達成されていれば、すべてのエラーを除去する必要はない。

9.HierarchyのPrefabのtransformを変更する:ツール使用

ChatGPTに聞いてつくってもらった。

HierarchyのPrefabのtransformを変更するツール

ArrangeChildPrefabsFlexible.cs
Unity上の置き場:*asset下の任意のフォルダ*\Editor
コンパイル成功するとメニューのTool/Arrange Child Prefabs Flexiblyができる。


prefabを内包するGameObjectを指定する。
数値はデフォルトでもよい。適当に指定する。

using UnityEngine;
using UnityEditor;

public class ArrangeChildPrefabsFlexible : ScriptableWizard
{
    public GameObject parentObject; // 親GameObject
    public int itemsPerRow = 100; // 1列あたりのアイテム数。これが可変指定値となる。
    public float spacing = 1.0f; // Prefab間のスペース

    [MenuItem("Tools/Arrange Child Prefabs Flexibly")]
    static void CreateWizard()
    {
        ScriptableWizard.DisplayWizard<ArrangeChildPrefabsFlexible>("Arrange Child Prefabs Flexibly", "Arrange");
    }

    void OnWizardCreate()
    {
        if (!parentObject)
        {
            Debug.LogError("Parent object is not assigned.");
            return;
        }

        if (itemsPerRow <= 0)
        {
            Debug.LogError("Items per row must be greater than 0.");
            return;
        }

        int total = parentObject.transform.childCount; // 子オブジェクトの総数
        Vector3 startPosition = Vector3.zero; // 開始位置

        for (int i = 0; i < total; i++)
        {
            Transform child = parentObject.transform.GetChild(i);
            Vector3 newPosition = new Vector3(startPosition.x + (i % itemsPerRow) * spacing, startPosition.y, startPosition.z + (i / itemsPerRow) * spacing);
            child.position = newPosition;
        }
    }
}

処理が完了すると、Scene上でアセットが整列している。

10.クロージング

これで目的の「UnityのEditorモードのSceneウィンドウで見て回る」または「PlayモードのGameウィンドウで見て回る」の準備ができた。


お疲れさまでした

この記事が気に入ったらサポートをしてみませんか?