Unityでのアバター切り替え:AvatarSwitcherスクリプトの設定と拡張ガイド

このチュートリアルでは、UnityでのAvatarSwitcherスクリプトの設定手順を解説します。このスクリプトを使用すると、プレイヤーが「C」キーを押すことで、2つのキャラクターモデル(アバター)を切り替えられるようになります。


手順

ステップ1:シーンの準備

  1. アバターモデルのインポート
    • プロジェクト内に2つのキャラクターモデルを用意します。各モデルにはそれぞれのGameObject(例:avatarAobjavatarBobj)とAvatar(例:avatarAavatarB)が必要です。
    • 今回の例では、QUERYちゃんアセットを使いますの。SD_QUERY_01 と SD_QUERY_35 の2つのアバターを使用します。
  2. Animatorの設定
    • アバターを切り替えるメインのGameObject(例:Query-Chan-SD)にAnimatorコンポーネントをアタッチします。
    • 各アバターGameObjectが必要なコンポーネント(例:必要なスクリプト、Animatorなど)を持っていることを確認してください。

ステップ2:AvatarSwitcher スクリプトをアタッチ

  1. スクリプトの作成
    • 新しいC#スクリプトを作成し、AvatarSwitcherと名付けます。以下のコードをスクリプトに貼り付けてください。
using UnityEngine;

public class AvatarSwitcher : MonoBehaviour
{
    public GameObject avatarAobj; // ModelAのアバター
    public GameObject avatarBobj; // ModelBのアバター
    public Avatar avatarA; // ModelAのアバター
    public Avatar avatarB; // ModelBのアバター

    private Animator animator;
    private bool isAvatarAActive = true;

    void Start()
    {
        // Animatorコンポーネントの取得
        animator = GetComponent<Animator>();
        // 初期状態のアバターを設定
        animator.avatar = avatarA;
    }

    void Update()
    {
        // Cキーでアバターを切り替え
        if (Input.GetKeyDown(KeyCode.C))
        {
            SwitchAvatar();
        }
    }

    void SwitchAvatar()
    {
        // 現在のアニメーション状態と進行位置を保持
        AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
        float currentTime = currentState.normalizedTime % 1f;

        // アバターを切り替え
        if (isAvatarAActive)
        {
            animator.avatar = avatarB;
            avatarBobj.SetActive(true);
            avatarAobj.SetActive(false);
        }
        else
        {
            animator.avatar = avatarA;
            avatarBobj.SetActive(false);
            avatarAobj.SetActive(true);
        }

        // アニメーションの進行位置を維持して再生
        animator.Play(currentState.fullPathHash, 0, currentTime);

        isAvatarAActive = !isAvatarAActive;
    }
}

スクリプトのアタッチ

  • AvatarSwitcher スクリプトをアバターの切り替えを行うメインのGameObject(例:Query-Chan-SD)にアタッチします。

ステップ3:アニメーション用のアバターの抽出

このサンプルでは、AvatarBをQuery-Chan-SD_Aichiとしています
SD_QUERY_35、子オブジェクトに3Dモデルがありますので、この部分だけProcjectフォルダにドラッグしてPrefab化します

SD_QUERY_01も同様にします

ステップ4:Inspectorでの参照設定

  1. GameObjectおよびAvatarの参照を設定
    • AvatarSwitcher コンポーネントの Inspector にて、以下のように設定を行います。
      • Avatar Aobj フィールドに Prefab化したSD_QUERY_01 をドラッグして割り当てます。
      • Avatar Bobj フィールドに Prefab化したSD_QUERY_35 をドラッグして割り当てます。
      • Avatar A に SD_QUERY_01Avatar を、Avatar B に SD_QUERY_35Avatar を割り当てます。

ステップ5:動作検証

Cキーでキャラクタを切り替わることを確認します
アニメーション中にキャラクタを切り替えることもできます

Cキーを連打しても対応されています

補足

using UnityEngine;

public class AvatarSwitcher : MonoBehaviour
{
    public GameObject avatarAobj; // ModelAのゲームオブジェクト
    public GameObject avatarBobj; // ModelBのゲームオブジェクト
    public Avatar avatarA; // ModelAのアバター
    public Avatar avatarB; // ModelBのアバター
    public RuntimeAnimatorController controllerA; // ModelA用のアニメータコントローラ
    public RuntimeAnimatorController controllerB; // ModelB用のアニメータコントローラ

    private Animator animator;
    private bool isAvatarAActive = true;

    void Start()
    {
        // Animatorコンポーネントの取得
        animator = GetComponent<Animator>();
        // 初期状態のアバターとアニメータコントローラを設定
        animator.avatar = avatarA;
        animator.runtimeAnimatorController = controllerA;
    }

    void Update()
    {
        // Cキーでアバターとコントローラを切り替え
        if (Input.GetKeyDown(KeyCode.C))
        {
            SwitchAvatar();
        }
    }

    void SwitchAvatar()
    {
        // 現在のアニメーション状態と進行位置を保持
        AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
        float currentTime = currentState.normalizedTime % 1f;

        // アバターとアニメータコントローラを切り替え
        if (isAvatarAActive)
        {
            animator.avatar = avatarB;
            animator.runtimeAnimatorController = controllerB;
            avatarBobj.SetActive(true);
            avatarAobj.SetActive(false);
        }
        else
        {
            animator.avatar = avatarA;
            animator.runtimeAnimatorController = controllerA;
            avatarBobj.SetActive(false);
            avatarAobj.SetActive(true);
        }

        // アニメーションの進行位置を維持して再生
        animator.Play(currentState.fullPathHash, 0, currentTime);

        isAvatarAActive = !isAvatarAActive;
    }
}

発展

切り替えるアバターが2つでしたが、それ以上の切り替えをしたいとき次のようにコードを変えることで実現できます

using UnityEngine;

public class AvatarSwitcher : MonoBehaviour
{
    [Header("Avatars")]
    public GameObject[] avatarObjects; // アバターのGameObjectの配列
    public Avatar[] avatars;           // アバターの配列

    private Animator animator;
    private int activeAvatarIndex = 0; // 現在のアクティブなアバターのインデックス

    void Start()
    {
        // Animatorコンポーネントの取得
        animator = GetComponent<Animator>();

        // 初期状態のアバターを設定
        SetAvatar(activeAvatarIndex);
    }

    void Update()
    {
        // Cキーでアバターを切り替え
        if (Input.GetKeyDown(KeyCode.C))
        {
            SwitchAvatar();
        }
    }

    void SwitchAvatar()
    {
        // アクティブなアバターのインデックスを切り替え
        activeAvatarIndex = (activeAvatarIndex + 1) % avatars.Length;
        
        // アバターを設定
        SetAvatar(activeAvatarIndex);
    }

    void SetAvatar(int avatarIndex)
    {
        // 現在のアニメーション状態と進行位置を保持
        AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
        float currentTime = currentState.normalizedTime % 1f;

        // 指定したインデックスのアバターを設定
        animator.avatar = avatars[avatarIndex];

        // 各アバターの可視状態を切り替え
        for (int i = 0; i < avatarObjects.Length; i++)
        {
            avatarObjects[i].SetActive(i == avatarIndex);
        }

        // アニメーションの進行位置を維持して再生
        animator.Play(currentState.fullPathHash, 0, currentTime);
    }
}

Unity

Posted by hidepon