VR Dance Viewer 用 アセットバンドルの作り方 (ランダムでポーズが変わるデータ編)

2025/06/27

Unity VRDanceViewer

t f B! P L

 前回の更新で追加された機能の、読み込み時にランダムでポーズ(アニメーション)が変わるアセットバンドルの作成方法です。 

事前準備

こちらの記事の事前準備をしておいてください。

ランダム要素があるアニメーションコントローラー作成 

プロジェクトビュー上で右クリックして、作成→アニメーターコントローラーを選択し、アニメーターコントローラーを作成します。

 アニメーションクリップをセットします。下のサンプル画像の場合、アニメーション数は3つなので、パラメーターに int 値の random3 を作成します。
移管は random3 の値が 0, 1, 2 で各アニメーションに移管するようにします。

(VR Dance Viewer は アニメーター再生時に int値の random(数字) のパラメーターがある場合、 0 から (数字)-1 の値の乱数を生成します)


あとは MakeABTool の .ab(AnimatorController) に作成したアニメーションコントローラーをセットして start を押せば完成です。

移管作成スクリプト

アニメーションクリップが多いと移管作成が面倒なので、移管と randomXX を自動生成するスクリプトを作りました。

Editor フォルダの中にこのコードを放り込むと uniharu → VRDanceViewer → AnimTool → RandomAnimatorControllerTool の項目が出現します。

アニメーションクリップを配置したアニメーションコントローラー を選択した状態で、このスクリプトを実行すると移管とrandomXX が生成されます。

using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;

public class AnyStateRandomTransitions : MonoBehaviour
{
    [MenuItem("uniharu/VRDanceViewer/AnimTool/RandomAnimatorControllerTool")]
    public static void AddAnyStateTransitionsWithConditions()
    {
        var controller = Selection.activeObject as AnimatorController;
        if (controller == null)
        {
            EditorUtility.DisplayDialog("Error", "AnimatorController が選択されていません", "OK");
            return;
        }

        if (controller != null)
        {
            bool result = EditorUtility.DisplayDialog("Confirmation", "選択されている AnimatorController を書き換えます", "Yes","Cancel" );

            if (!result)
            {
                return;
            }
        }

        if (!HasParameter(controller, "random", AnimatorControllerParameterType.Int))
        {
            controller.AddParameter("random", AnimatorControllerParameterType.Int);
        }

        int rndno = 0;

        foreach (var layer in controller.layers)
        {
            var stateMachine = layer.stateMachine;
            int index = 0;

            foreach (var child in stateMachine.states)
            {
                var state = child.state;

                if (state == stateMachine.defaultState)
                {
                    continue;
                }

                bool exists = false;
                foreach (var transition in stateMachine.anyStateTransitions)
                {
                    if (transition.destinationState == state)
                    {
                        exists = true;
                        break;
                    }
                }

                if (!exists)
                {
                    var transition = stateMachine.AddAnyStateTransition(state);
                    transition.hasExitTime = false;
                    transition.hasFixedDuration = true;
                    transition.exitTime = 0f;
                    transition.duration = 0f;
                    transition.canTransitionToSelf = false;
                    transition.AddCondition(AnimatorConditionMode.Equals, index, "random");
                }
                index++;
                rndno = index;
            }
            
        }
        string newName = $"random{rndno}";
        RenameParameter(controller , "random" , newName);
        AssetDatabase.SaveAssets();
    }

    private static bool HasParameter(AnimatorController controller, string name, AnimatorControllerParameterType type)
    {
        foreach (var param in controller.parameters)
        {
            if (param.name == name && param.type == type)
                return true;
        }
        return false;
    }

    public static void RenameParameter(AnimatorController controller, string oldName, string newName)
    {
        AnimatorControllerParameter oldParam = null;
        foreach (var param in controller.parameters)
        {
            if (param.name == oldName)
            {
                oldParam = param;
                break;
            }
        }

        var newParam = new AnimatorControllerParameter
        {
            name = newName,
            type = oldParam.type,
            defaultInt = oldParam.defaultInt,
        };

        controller.AddParameter(newParam);

        foreach (var layer in controller.layers)
        {
            foreach (var transition in layer.stateMachine.anyStateTransitions)
            {
                var conditions = transition.conditions;
                for (int i = 0; i < conditions.Length; i++)
                {
                    if (conditions[i].parameter == oldName)
                    {
                        var newCondition = conditions[i];
                        newCondition.parameter = newName;
                        conditions[i] = newCondition;
                    }
                }
                transition.conditions = conditions;
            }
            foreach (var state in layer.stateMachine.states)
            {
                foreach (var transition in state.state.transitions)
                {
                    var conditions = transition.conditions;
                    for (int i = 0; i < conditions.Length; i++)
                    {
                        if (conditions[i].parameter == oldName)
                        {
                            var newCondition = conditions[i];
                            newCondition.parameter = newName;
                            conditions[i] = newCondition;
                        }
                    }
                    transition.conditions = conditions;
                }
            }
        }
        controller.RemoveParameter(oldParam);
    }
}

このブログを検索

Amazon.co.jp[PR]

このブログについて

QooQ