目次
はじめに:
pixivが提供しているVroidという3Dモデル作製サービスがあります。
こちらはPC版、モバイル版ともに提供されており、モデリングの知識が無くても簡単に3Dのキャラクターを作ることができます。
今回の解説ではモバイル版を使用します。IOS版 Android版
こちらで作成したモデルをUnityに導入しFBXに変換、そこからAdobeのMixamoというサービスでアニメーションを付与して簡単な移動処理を導入するところまでまとめてみたいと思います。
サンプル:
こちらがサンプルになります。
Vroidで作成したキャラクターにMixamoのアニメーションを付与して動かしています。
環境:
今回はUnity(2018.4.3f1)で実装していきます。
導入:
上記でインストールしたモバイル版Vroidでモデルを作成し、
VroidHubで公開します。(Pixivアカウントが必要です)
公開されたモデルをVroidHubからダウンロードしてUnityで使用する準備をします。
(VroidとVroidHubで同一アカウントでログインしておく必要があります)
Unityでプロジェクトを作成します。
Vroidのモデル形式であるVRMを編集できるパッケージこちらからをダウンロードして、プロジェクトにインポートします。(2021/5/22現在の安定板はv0.66.0)
インポートに成功したら、Assetsの下にフォルダを切ってその中にVroidHubからダウンロードしたVRMフォルダをドラッグして導入します。
以下のように作ったキャラクターのPrefabが追加されていることを確認します。
こちらの名前がわかりにくい状態なので、VroidVRMにリネームしておきます。
Unityのシーンに該当のPrefabと分かりやすいように床用のPlaneを設置します。
Mixamoからアニメーション導入:
ここから、MixamoというAdobeが提供しているFBXへのアニメーション付与のサービスを利用するため、一度こちらのVRMPrefabモデルをFBXに変換します。
UnityEditorのWindow>PackageManagerにて、FBXExporterをインポートします。
(現在最新版だとエラーが出ていたため、version 3.2.1を使用します)
FBXExporterを導入後、該当のVroidVRMを右クリックで選択し、FBXを作成します。
この時作成されたFBXモデルのmaterialが崩れる場合がありますが、
FBXのInspectorからmaterial>LocationをUse External Material(Legacy)に設定し、
展開されたmaterialの中でRendringModeがFadeになっていないものを見つけて修正します。
修正して二つのモデルを並べます。
問題なく表示されていれば、ここからMixamoのアニメーションを適応します。
Adobeのアカウントを作成し、MixamoにアクセスしてUploadCharacterを選択し、
先ほどFBXExporterで作成したキャラクターをインポートします。
モデルのテクスチャはpreviewで反映されていなくても大丈夫です。
キャラクターの読み込みが成功すれば、後は適応したいアニメーションを探してダウンロードしていく流れになります。アニメ適応時にモデルのpreviewを見てパラメータを調整することができるので、この際に動作の速度や腕のスペースが服に重なってしまっていないかなどを見て確認します。
また、Animation に移動量を付与したくない場合は、In placeにチェックを入れましょう。
以下は実際にArm Spaceが足りていなかったので調整した例になります。
調整が終われば、後はモデルpreview画面の上にあるdownloadを押します。
ダウンロード設定ではFormatをFBX for Unityに設定します。
それ以外の設定はとくに変えなくても大丈夫です。
今回は、アイドル(静止)>歩き>走り とジャンプの合計4つのアニメーションを導入しました。
基本動作の三つはBlendで遷移し、ジャンプのみTriggerで動作するように設定していきます。
Unityで動作設定:
FBXで作成したアニメーションは、Inspector>Rig>AnimationTypeをHumanoidに設定します。
そのままでもFBXモデルのアバターでは動作できますが、VRMの方に対応する為に変えます。
(FBX化したモデルでは髪や服の揺れが消えています)
VroidVRMに付与するAnimationControllerを用意します。
AnimationControllerを新規作成しEntryからBlendTreeを作成し、遷移を繋ぎます。
また、AnyStateからmixamo.fbx.Jumpのアニメーションクリップを繋ぎ、そちらもBlendTreeに繋げます。Jumpの遷移にはパラメータにTriggerのフラグを追加し、そちらをConditionに設定します。
BlendTreeの中身はパラメータSpeedで遷移する静止>歩き>走りの三つのClip登録になります。
それぞれ対応するmixamo.FBXのクリップを登録していきます。
こちらのアニメーションクリップの登録が終わったら、VroidVRMのキャラクターモデルにコンポーネントを追加・設定していきます。
・Animatorのcontrollerに先ほど作成したcontrollerの設定
・RigidBodyのMassを10に設定
・RigidBodyのFreezeRotationで回転軸のXZを固定
・CapsuleColliderをキャラクターの見た目と同じくらいの大きさに設定
また、今回のキャラクターはカメラを基準に移動するので、カメラにも回転動作をさせるスクリプトの設定が必要になります。
以下のコードをC# でPlayerCameraの名前で作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerCamera : MonoBehaviour { float angleUp = 60f; float angleDown = -60f; [SerializeField] GameObject player; [SerializeField] Camera camera; [SerializeField] float rotate_speed = 3; [SerializeField] Vector3 axisPos; //マウススクロールの値を入れる [SerializeField] float scroll; //マウスホイールの値を保存 [SerializeField] float scrollLog; void Start() { //CameraのAxisに相対的な位置をlocalPositionで指定 camera.transform.localPosition = new Vector3(0, 0, -3); //CameraとAxisの向きを最初だけそろえる camera.transform.localRotation = transform.rotation; // カーソル非表示 Cursor.visible = false; // カーソルを画面中央にロックする Cursor.lockState = CursorLockMode.Locked; } void Update() { //Axisの位置をモデルの位置+axisPosで決める transform.position = player.transform.position + axisPos; //マウススクロールの値を入れる scroll = Input.GetAxis("Mouse ScrollWheel"); //マウススクロールの値は動かさないと0になるのでここで保存する scrollLog += Input.GetAxis("Mouse ScrollWheel"); //Cameraの位置、Z軸にスクロール分を加える camera.transform.localPosition = new Vector3(camera.transform.localPosition.x, camera.transform.localPosition.y, camera.transform.localPosition.z + scroll); //Cameraの角度にマウスからとった値を入れる //Y軸は反転させておく transform.eulerAngles += new Vector3( Input.GetAxis("Mouse Y") * - rotate_speed, Input.GetAxis("Mouse X") * rotate_speed , 0); //X軸の角度 float angleX = transform.eulerAngles.x; //X軸の値を180度超えたら360引くことで制限しやすくする if (angleX >= 180) { angleX = angleX - 360; } //Mathf.Clamp(値、最小値、最大値)でX軸の値を制限し、反転しないようにする transform.eulerAngles = new Vector3( Mathf.Clamp(angleX, angleDown, angleUp), transform.eulerAngles.y, transform.eulerAngles.z ); } } |
CameraAxis>MainCameraを子に設定し、上記のようにInspectorを設定します。
最後に、以下のC#コードをVroidVRMのキャラクターにアタッチします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerMove : MonoBehaviour { float MAX_MOVE_SPEED = 3.5f; float NORMAL_MOVE_SPEED = 2.0f; float JUMP_VELOCITY = 5.0f; float inputHorizontal; float inputVertical; Rigidbody rigidBory; Animator animator; float moveSpeed = 2.0f; float previousSpeed = 0.0f; void Start() { rigidBory = GetComponent<Rigidbody>(); animator = GetComponent<Animator>(); } void Update() { //移動処理 inputHorizontal = Input.GetAxisRaw("Horizontal"); inputVertical = Input.GetAxisRaw("Vertical"); //ダッシュ処理 if(Input.GetKey(KeyCode.LeftShift)) { moveSpeed = moveSpeed + 0.1f; moveSpeed = Mathf.Clamp(moveSpeed, NORMAL_MOVE_SPEED, MAX_MOVE_SPEED); } else { moveSpeed = Mathf.Lerp(moveSpeed, NORMAL_MOVE_SPEED, 0.1f); } //ジャンプ処理 if(Input.GetKeyDown(KeyCode.Space)) { animator.SetTrigger("Jump"); rigidBory.AddForce(Vector3.up * JUMP_VELOCITY, ForceMode.Impulse); } } void FixedUpdate() { // カメラの方向から、Y軸を除いた単位ベクトルを取得 Vector3 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized; // 方向キーの入力値とカメラの向きから、移動方向を決定 Vector3 moveForward = cameraForward * inputVertical + Camera.main.transform.right * inputHorizontal; // 移動方向にスピードを掛ける if (Mathf.Abs(inputHorizontal + inputVertical) > 0.1f) { rigidBory.velocity = moveForward * moveSpeed + new Vector3(0, rigidBory.velocity.y, 0); } //一定以上速度が変化した場合にcontrollerにSpeedの値を送る if (Mathf.Abs(rigidBory.velocity.magnitude - previousSpeed) > 0.1f) { animator.SetFloat("Speed", rigidBory.velocity.magnitude / MAX_MOVE_SPEED); } previousSpeed = rigidBory.velocity.magnitude; // キャラクターの向きを進行方向に if (moveForward != Vector3.zero) { transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(moveForward), 0.1f); } } } |
こちらのPlayerMove.csは基本の移動処理、ダッシュ、ジャンプのアニメーション制御を行います。
上記のスクリプトをキャラクターに設定し、Unityの実行で動画のように動作テストが可能です。
Scene上にキャラクターがジャンプで乗れる程度のCubeなどを設定し、materialの色を変えたものを設定すると移動している動作が分かりやすくなります。
まとめ:
PC版VroidStudioでは以前から可能でしたが、Mobile版でも3DモデルのVRMダウンロードが可能になりました、使用に際しては規約がありますが、商用利用も可能です。
Unityでのアニメーション対応はモデルの差がある場合は適応が難しいですが、Mixamoを利用することで多くのアニメーションをテスト、導入することができます。
これらのサービスを組み合わせて利用することで、個人製作などでもクオリティの高い3Dモデルとアニメーションの使用が可能になってきていると思います。
参考・リンク一覧