トマシープが学ぶ

Unity/VR/AR/デザイン好きのミーハー 記事内容は自分用のメモです

UIToolkitを学ぶ【UIBuilder、サンプル触り】

UIToolkit

Unityの新しいUI実装のツール.

昔はUIElementという名前でEditor拡張用のイメージがあったけど、今は普通のゲーム実装でも推奨になっている。ただしuGUIのすべての機能をサポートしていない

docs.unity3d.com

World Space用にもまだ使えない

Html/CSS的な書き方らしい。最近React学んだから相性いいかと思ったけど、jQuery的なものを使うらしくReactとは違うらしい

UI Toolkitメモ - フレームシンセシス

 

あんまり話聞かないから使われてるのかな?Realityでは導入しているって!

note.com

Twitter検索した感じまだガッツリ使ってる人はいないのかな。足りていない機能もあるし

 

とりあえず使う

記事を参考にしながらとりあえず触る

qiita.com

UIBuilder

UIBuilderというUIをドラッグアンドドロップで配置できるツールがある。(ホームページビルダーみたい)

左下の要素を置いていく

適当に面白そうなUI全部置いた

保存するとuxmlファイルができる

シーンに置く

ヒエラルキーでUI Toolkit>UI Document

SourceAssetsにさっきのuxmlをアタッチ

するとゲームビューに表示された!シーンビューには何も映らない。

デザインやレイアウト変更

CSS的なのでもできるけど、Builder上の右側の設定でもいろいろできる

保存したらすぐGameビューのほうに反映されるし楽しい。

カーソルまで設定できて、設定したエリア上にマウスを当てたらそのカーソルになるw

角丸も簡単にできる

スクリプトから操作

UIDocumentごとプレハブ化できる

スクリプトでプレハブ化したUIDocumentを呼び出すと、表示される

ボタンにアクセスするには、名前で参照

参考記事はそれ以外にもリストとして子のカードを並べて表示するとか、スクリプトでの操作がいろいろ紹介されていた。

 

こちらにもInputFieldの値の取り方とか書いてある

tech.framesynthesis.co.jp

デザインやりたいこと

Builderでできるのかな?

日本語フォント

フォントをセットしても反映されない~と思ったら、下のFontAssetsにデフォルトで入っているものを消したら反映された

簡単に使える~と思ったけどこれだとビルドしたとき表示されないらしい

https://amabie-labo.com/dev_article/article01

TextMeshProと同じくFontAssets化しないといけないって。そして下のFontAssetのところにセットする

テキスト省略...

...できるボタンあるけどならない。。。

Unityフォーラムに答えがあった

forum.unity.com

displayのOverflowもhudden(右のやつ)にしないといけなかった。わかるか~

画像を入れる

UIBuilderの中に画像コンポーネントがない;;

ファーラムの投稿にもあったが「ない」らしい。

forum.unity.com

自分で以下のコードを書いてAsstsのどこかに置く。

using UnityEngine.UIElements;
 
public class MyImage : Image
{
    public new class UxmlFactory : UxmlFactory<MyImage, Image.UxmlTraits>{}
 
    public MyImage()
    {
       
    }
}
 

そしたらUIBuilderのLibraryのProjectに入る

これでサイズやBackgroundの画像を設定したら表示できた。

影を付ける

テキストには付けれた。ついでにワードごとの間の値も設定できた

画像とかボタンには付けれないのかな?ないっぽい

これもフォーラムですごい会話されてる。つい最近まで。やっぱりみんなソフトシャドウほしいよな。

forum.unity.com

現時点ではないけどロードマップにあって2024年(今年!)追加されるっぽい。今やりたかったら画像用意するか、コード書く。(有志がコード提供している)

forum.unity.com

デフォルトコンポーネントの細かいUI編集(?)

スクロールバーとかInputFieldとかデフォルトのコンポーネントのデザインは編集できない

どうやるんだろう?

highlighの色など(?)

ボタンなどをホバーしたときとかの色の変化も設定するとこなさそう。一応実行すると大きさ変わったりちょっと色変化するのでどこかに設定されてそう。USSかな?

コードでのuxml,uss編集

uxml

UIBuilderで作ったuxmlをコードとして開くにはどうするんだ?普通にクリックしたらBuilderが表示される。

uibuilderの画面の一番下のアイコンから見れた

ここからしかできないのかな?

さっきのshadowも付けてみた

でか・・・

USSで調整するらしい

USS(?)

デフォルトではunityが定義したtss?

新しく作るにはuibuilderの左上の+から追加できる

公式ドキュメント読んだけどそこからどうするのか全く分からない。。。

docs.unity3d.com

+ボタンの右のAdd new selector...のところに何か自分で入力するっぽい。

そしてUI選んでスタイルシートの欄に名前入力するといいのか???

 

さっきとのuxmlと同じように画面下にコード開くボタンが出る

shadowのcss書いてみた

何も変わらなかった。フォーラムの下のほう見たらUSSでは動かずインスペクタで調整って書いてた。

TextのColor変えたら変わったけど、何か間違ってる・・・まあこれは主題じゃないからいいや

公式サンプルアセット

もうよく分からないのでサンプルを見る

Unity公式から二つサンプルアセットが出てる。QuizUとDragon Crashers

gamemakers.jp

QuizU

assetstore.unity.com

ここから起動する

クイズと設定画面とUIToolKitデモと各種リンクページの4つのコンテンツがある

クイズはUnityのAudioとかUIToolKitとかいろいろ分かれてる。クイズの内容は本題じゃなくてあくまでUIToolKitでのUIを見せるサンプルだと思うけど結構クイズの量多かった。

起動したときから感じてるけど、結構UI崩れる。

UIToolKitはマルチ解像度のUIを作れることも目的だった気がするんだけどな~uGUIでもちゃんとマルチ解像度のUI作れるのに何でデモでマルチ解像度対応しないんだろう?

できないのかやってないのか分からない・・・

テキストの大きさとか折り返し設定とかも気持ち悪いし。

 

DEMOのページではUXMLとかUCCとかの説明とデモ

ボタンのhoverとかの話もあった。

 

では実際に中身を見てみよう~ここにある

私はデフォルトだと崩れている

一番上の部品を選んでWidthとHeightを変えた

気になっていた、〇ボタンの中にアイコンは、丸い形ボタンの下にvisual elementsで画像置いてた

画面全体の解像度変えたときに、丸のサイズとアイコンのサイズが別の比率で変わって気持ち悪かった

 

USSは普通にダブルクリックしたら開くということが分かった。

そしてさっき分からなかったUIBuilderでのUSSのselectorのことも少しわかったような。

作りたい名前のselectorを入力したらUSSにこれが追加されるから、この中はスクリプトで書くのかな?

そしてこれを適用したいコンポーネントにselectorを適用する。

u-queryはサンプルシーン見てもどこに使われてるかよくわからなかった。まず元のjqueryが何なのか知らない

Dragon Crashers

assetstore.unity.com

QuizUとは共存しようとしたらQuizU側でエラーでる。

git管理もしてないし、assetpackageからもremoveできないし詰んだか?と思ったが1個スクリプト消して、もう一つコメントアウトしたらエラー消えた。QuizUにどんな影響が出たかは分からない

MainMenuからプレイできる。


UIのサンプルなのでゲームとしてすべての機能は入ってない

いろいろUI使われている

QuizUよりはきれいなUI。でもマルチ解像度対応完ぺきではない。

UIBuilderで見るとそれぞれのパーツが別のuxmlになっていて組み合わさっている。これはReactのコンポーネント的概念ではないのか

公式ドキュメント

いい加減公式ドキュメントを読もう

docs.unity3d.com

UIBuilder以外にもツールがあった

SamplesはUnityEditor用なのかな?ドキュメントには特にそんなこと書いてないけど

 

UI Toolkit Debugger

docs.unity3d.com

インスペクターの要素見れた

自分で作ったUIの情報も見れるはず。

UIBuilderの右上のPreviewを押した状態で、DebuggerのPickElementを押して要素を選ぶ。もしくはゲームビューで実行中も同じことができる

Figmaの開発モードでもこの多重長方形見るけどこれはWebでの定番なのか?あんまりなじみがない・・・

最後に

もっと踏み込んでいくにはhtml/cssの知識が必要そう。

ui toolkitのudemyの講座は英語しかない><

www.udemy.com

Unity Museを使った!

Unity Muse

Unity用のAI機能

unity.com

www.moguravr.com

今5機能

https://muse.unity.com/en-us/explore

Proライセンスだったら無料で使えるのかと思ったら、1月30ドルで別途購入しないといけなかった。

15日間は無料トライアルができる

XRKaigiで聞いた感じアニメーション作成とかはまだできないのかと思ったが、プレリリース機能へアクセスってあるから使えるのか。

やってる人いる!

チャットはWebでやるのか?これはお試しなのか?Unityバージョン選んでから聞ける

フリートライアルして!って言われてできなかった

各機能の使い方のページ

unity.com

やってみる

フリートライアル

日をあけてサブスクボタン押したら、前は出たこの画面が出ずヌルっとフリートライアル始まった

15日間終わったら自動で有料になったりしないのか?どこでその管理ができるのかわからない・・・

UnityIDのページを見てもUnityMuseのサブスク情報ないから解約とかしなくても大丈夫ということなのかな?クレカ情報消しておいた

更新してしまっても言ったら返金処理されたらしい

 

本来はポイント制だが、4/1までの早期アクセスだとポイントを消費しない!これはフリートライアルでも有料版でも変わらないのかな?

まあ始めるのにぎりぎりいいタイミングだったね

Chat

Webで動かす。Unityに関することを教えてくれる。例題に出ていた質問を押したら画像付きで答えてくれたw

VRMとかUnity公式じゃないものも一応答えてくれる。でも正しくはなさそう

あと最初英語だったからGoogle翻訳で日本語にしてて気づかなかったけど、日本語で質問したら日本語で返信してくれてた。

あと普通にUIも日本語選べた

copilotはプログラミングに関すること以外は答えてくれないらしいけど、Museは今日の朝食についても答えてくれた。でも本来はポイント制だからこんな蔵だない質問をしている場合ではない

Texture

UnityPackageを入れる。2022.3以降

最近アップデートしてもっといい感じになったらしい

Museメニューからテクスチャを作る

プロンプト入れると4種類できた

その中から一つ選ぶと微妙にモードが変わる

そのままだと512x512のサイズだったけど、メニューからUpscaleしたら2048x2048で生成できた

マテリアルビューに切り替えるとDiffusemapとかが生成される

形やライティングも変えれる。

ShaderGraphで作ったことになってるんだ

黒い部分以外透明にしたりとかは難しいのかな~?

マテリアルじゃなくてテクスチャ生成したほうをPlaneに貼ってちょっと透明にした

生成するときShapeとか色とか参考イラストとかを指定できる

バージョン2が指定できないなと思ったら、PackageManagerでアップデートしないといけなかった。pre19にする。公式リンクから行くと18になってた

けどできなかった。

ChangeLog見たら個のアップデートは時期的に関係なさそう。

バージョン2は内部的なものなのかな・・・?

あとやっぱり無料トライアルだとポイント制限あるのか・・・?

不安になってきたので次

Sprite

 

Unitypackage入れたのに選べない><

Unity再起動したら選べた

同じようにプロント入力

もっとシンプルな白黒アイコン風のを作ってほしかったから、InputImageにそういう画像を入れたがあんまりうまく認識してくれなかった。Stypeを選べる項目もあるがDefaultしか今はない。

1枚選ぶとそれに対して範囲指定して追加のプロンプトなどを打てる

テントウムシみたいなのできた・・・

あと今更気づいたけど、Generateを押した時点でファイルがAssets直下に生成されてた。

これを押すと生成画面に移動できる。なのでずっと同じ画面でいろいろなものを生成するのではなく、別の物体を生成するときは、Muse>New XX Generaterから生成するといい。

猫を新しく作ったが、クオリティ低い・・・

作ったものは512x512。Textureと違って大きくはできなさそうだった。

スタイルのデータが見れた。happy Harverstがデフォルトの中身なのかな

Unity公式のゲームなのか

assetstore.unity.com

Style Trainerというのを選ぶと以下のような画面になった。これはいったい・・・・

Animate

人間のモーションを作れる。UE5のプラグインでもやったことある

bibinbaleo.hatenablog.com

 

Editorで使えるようになるのは4月初旬

でもWebではできるはず・・・だったが今うまく動かないらしい

ドキュメント見たらMuseサブスクライブしたからと言って利用できるわけではない。ホーム送信したら優先的に登録されると書いてあった。でもこれは関係ないよね・・・

午後アクセスしたら見れた! 今このページからできるのはAnimateだけだけど、今後Sprite作成もここでできるようになるのか?

使い方日本語化できなくてよくわかってない

まず、UR5のプラグインでも試したswiming。綴り間違ってるせいかうまくいかなかった。でもswimmingでも立ったままだった

UE5でも書いたA person is walking forward hastilyで生成すると前に歩いた。ちなみに文字のコピペができないので、自分で記入しないといけない。

cheers(乾杯)はちょっとそれっぽい

ちゃんと指示したら使えるものできるのかな?

同じこと書いたら同じようなものできた。walking backward and spinning



Make Editableを押して、sampling optionsでConvertすると

モーションが分割されて、それぞれのコマで手などの位置や角度を編集できるようになった

Look Atもある

影響範囲?結構いろいろ編集できる

スピードも変えれる


Webのエディターの情報は更新したら消えてしまうので、いいので来たらすぐにExportしたほうがよさそう。

fbxで出力された、

このモデルもついてくる

移植できた。

どうでもいいけどこのモデルの構造面白い

behavior

スクリプト書いてくれる

これはPackageを入れたらCreate>MuseBehaviorから作る

ファイルができる。open

ノードベース;;

選んだりできる

Actionでなんか適当に打ち込んだら、それぞれの単語がGemaObjectなのかboolなのかとか洗濯できる

Generative AIを押すとこんな画面

csスクリプトが生成される

中身が書いてある。でもコメントみたいなのをコメントアウトされてないから赤線出てる。あとChange Materialで想像してたものではない

いまいちノードだとやる気でないな・・・このノードってほかでも使われてるのかな?

AIならスクリプトベースのほうがやりやすいのでは?

チュートリアルプロジェクトがあるので触ってみる。

assetstore.unity.com

PackageじゃなくてProjectだから空のプロジェクトとに入れたほうがよかったかもしれない。

Unity再起動したりいろいろ時間かかったが、何とか読み込めた。キャラクターが移動する

肝心のノードがどこにあるのかわからない。AIフォルダの下にあるノードを開いても何も出てこない

ここに自分で書いていって空間にいる敵?に個性を追加させていくのかな

この動画と連動しているらしい

www.youtube.com

Muse Sketch

近日公開されるらしい

Unity AI updates | Join the mailing list

このツイートの画像によると3Dのシーンを作れるって書いてる。木とか岩とか生成してくれるんだろうか?一次情報が見つけられない・・・

 



VRM1.0のアバターの表情をスクリプトから変更する

ドキュメントどこだ・・・?これか?でもvrm1.0ではなさそう

vrm.dev

vrm.dev

検索したらいろいろ一般の方の記事は出る

note.com

Vrm10RuntimeExpressionで変更するらしいが、これを検索しても公式ドキュメントみたいなのが出てこない

でもこれでよさそう

[SerializeField] private Vrm10Instance vrmInstance;

private Vrm10RuntimeExpression vrmRuntimeExpression;

void Start(){

vrmRuntimeExpression = vrmInstance.Runtime.Expression;

//表情変える

vrmRuntimeExpression.SetWeight(ExpressionKey.Blink, 1.0f);

}

目をつぶった~

この情報を与えて、ChatGPTに瞬きするスクリプトを作ってもらった。ちなみにこの情報を与えないと正しくvrm1.0で動くスクリプト作ってくれなかった。

 

using UnityEngine;
using UniVRM10;
using System.Collections;

public class vrm10expressionchange : MonoBehaviour
{
    [SerializeField] private Vrm10Instance vrmInstance;
    private Vrm10RuntimeExpression vrmRuntimeExpression;

    [SerializeField] private float blinkInterval = 3.0f; // 瞬きの間隔(秒)
    [SerializeField] private float blinkDuration = 0.1f; // 瞬きの持続時間(秒)

    private float nextBlinkTime = 0.0f; // 次の瞬きのタイミング

    void Start()
    {
        vrmRuntimeExpression = vrmInstance.Runtime.Expression;
    }

    void Update()
    {
        if (Time.time >= nextBlinkTime)
        {
            StartCoroutine(Blink());
            nextBlinkTime = Time.time + blinkInterval;
        }
    }

    IEnumerator Blink()
    {
        vrmRuntimeExpression.SetWeight(ExpressionKey.Blink, 1.0f);
        yield return new WaitForSeconds(blinkDuration);
        vrmRuntimeExpression.SetWeight(ExpressionKey.Blink, 0.0f);
    }
}

 

これで瞬きできるようになった。

 

VRM1.0で1人称モードで頭消したかった

VRM1.0でFirstPersonの設定を呼び出す方法探し

これをVRM1.0でする方法

bibinbaleo.hatenablog.com

VRM1.0って実装方法のドキュメント全然ないの・・・?

中身の仕様とかを見ないといけないのか・・・?

github.com

こちらの記事でFirstPerson周りのことを書いているがよくわからない

zenn.dev

VRM0.xのときのVRMFirstPerson.Setup()に当たるものはどれなんだろう。

構成的にはVrm10Instanceの下?中?

UniVRM 利用アプリケーションの VRM 1.0 への移行について - Speaker Deck

VRMInstanceコンポーネントの中にFirstPerson関連の何かがあるわけではない。関係ないけどFinalIKの文字があった

FirstPerson関連のコンポーネントを調べたらVRM10ObjectFirstPersonというのがあった

頭部を取り除いたモデルを複製している!?

これのSetupAsyncを呼び出すのか?

SetupAsyncでググったら出てきた!

FirstPersonを取得する場合はVRM1.0からはinstance.Vrm.FirstPerson.SetupAsync()で取得できます。

qiita.com

こんな感じか?

using UniVRM10;

でもawaitCallerの部分がわからない

 

あとレイヤー名ももしかしてvrm0.xと設定違うのだろうか

サンプル

サンプルあった。。。

実行して、vrm1.0を読み込んだらFirstPersonには何も表示されなかった。vrm0.xから1.0にuniVRMでアップグレートしたモデルだと、FirstPersonなどのレイヤーの設定引き継がれないのか?

実行中、モデルのすべてのメッシュがTHIRD Person Only layerになってる

もともとはDefalt

この配布モデルでもだめだった

hub.vroid.com

公式がvrm1.0のモデルを配布しているはず・・・

ここから直接ダウンロードできた

https://github.com/vrm-c/vrm-specification/blob/master/samples/Seed-san/vrm/Seed-san.vrm

これだとちゃんと首だけ消えた!モデルの設定なのか・・・

ちなみにsamples/VRM1_Constraint_Twist_Sample/vrm/VRM1_Constraint_Twist_Sample.vrm

のほうは消えなかった。

 

サンプルのスクリプトになんか書いてた。

あとSetupAsync()はVRMをロードしているところでやっていたけど、↑のほうの参考記事と全く同じ・・・

ロードするときはそれでいいのかもだけど、初めからシーンにあるVRMモデルのFirstPersonのセットはどうするんだ?

 

あ、レイヤーをあらかじめセットしておけばいいのか・・・

すごい遠回りした;;

vrm1.0でのFirstPerson設定

vrm.dev

vrm1.0のタブの一番上にある_vrm1_の中に設定する場所がある。

これ

VrmObject と Extract | VRM

 

Select GUIをMetaからFirstpersonに変更

あった。Autoには設定されているのか。vrm0.xではこれでよかったはずなのだが・・・

Autoとかの意味合いは0.xと同じかな

vrm.dev

Autoによる自動分割は重めの処理なんだ・・・知らなかった

以下が推奨

頭に ThirdPersonOnly を指定
体に Both を指定

公式サンプルもちゃんと設定してた。

この設定を自分のvrmにもする

これで書き出して、さっきのサンプルシーンで読み込むと・・・

あれ?

あれ~~Bodyの一部なんだ~。

vrm0.xでSetup()したモデルうまくいってたと思ってたけど気のせいか・・・と思ったが気のせいではない。VRで見たらちゃんと顔消えてる。

え~~~なんで~~

マテリアル非表示にしているのか??



 

Questでのパススルー実装やMRサンプル遊び【Unity】

仮想空間の一部をパススルーモードに切り替えるのやろう~~

Building Blockのパススルー

Passthrough(全体)

Building BlockのPassthroughを入れたらデフォルトでパススルーになった。

でもなんか左端の視界がぐちゃっとなってる。ちょっと時間空けてやったらきれいに見えたから、QuestLinkの負荷とかそこらへんかな・・・?

ここら辺の設定変えても変わらない。Opacityは明るさ、Edge Renderingにチェックを入れたらパススルーで見えている物体に境界線がついた!

かっこいい!!

明るさ真っ黒でEdgeつけるとめっちゃサイバーでかっこいい

ドキュメントあった

developer.oculus.com

Overrayだと一番上に来るから、すべてのバーチャルなものを隠す。

ちなみにパススルーにするときカメラのSolidColorは黒のAlpha0にする必要がある。

それ以外の色だとその色がパススルーに乗ってきた。

Passthrough(平面)

視界の一部をパススルー出来るBlockもある

このメッシュがあるところだけ窓みたいにパススルーになった。

でも実際の方向とあっていない。正面位置がずれた・・・?

パススルー部分も立体感があるから、まじまじと見ていると仮想空間とパススルーの立体感があってなくてちょっと酔う

こういう表現どこかで見たような・・・と思ったら両手部分だけ丸くパススルーになるアプリが何かであったからあれか!

Passthrough(3D)

Windowもあった。こっちは立体なのか?

Quadだった

右目にはパススルーが表示されなかった・・・

Quad以外にも同じシェーダーを適当なオブジェクトに付けたらパススルー表示はされる。(右目表示されなかった)

切り替え

やりたいのは適当なボタンを押したら、VR内の背景の仮想空間が消えて、パススルーが表示されるという切り替え。

デフォルトでパススルー表示しておいて、仮想空間をオンオフするだけでもいいが、パススルー状態って重くないのかな?

パススルーのオンオフはOVR Passthrough Layerコンポーネントのオンオフでできた

 

ドキュメントに初期状態でパススルーにするかどうかのコードはあった

developer.oculus.com

やはりあのコンポーネントをオンオフするのが正解みたい

// Add this to any MonoBehavior
void Start()
{
   if (OVRManager.IsPassthroughRecommended())
   {
      passthroughLayer.enabled = true;

      // Set camera background to transparent
      OVRCameraRig ovrCameraRig = GameObject.Find("OVRCameraRig").GetComponent<OVRCameraRig>();
      var centerCamera = ovrCameraRig.centerEyeAnchor.GetComponent<Camera>();
      centerCamera.clearFlags = CameraClearFlags.SolidColor;
      centerCamera.backgroundColor = Color.clear;

      // Ensure your VR background elements are disabled
   }
   else
   {
      passthroughLayer.enabled = false;

      // Ensure your VR background elements are enabled
   }
}

こんな感じにしてボタンとかから呼び出せるようにした

    public OVRPassthroughLayer passthroughLayer;
    public GameObject vrbackground;
    void Start()
    {
        if (OVRManager.IsPassthroughRecommended())
        {
            OnPassthroughLayerActive(true);

            // Set camera background to transparent
            OVRCameraRig ovrCameraRig = GameObject.Find("OVRCameraRig").GetComponent<OVRCameraRig>();
            var centerCamera = ovrCameraRig.centerEyeAnchor.GetComponent<Camera>();
            centerCamera.clearFlags = CameraClearFlags.SolidColor;
            centerCamera.backgroundColor = Color.clear;

            // Ensure your VR background elements are disabled
        }
        else
        {
            OnPassthroughLayerActive(false);

            // Ensure your VR background elements are enabled
        }
    }

    public void OnPassthroughLayerActive(bool bl)
    {
        passthroughLayer.enabled = bl;
        vrbackground.SetActive(!bl);
    }

Meta MR Utility Kitのサンプル

6つある。一番下のは昔試した。現実空間にポイントライトをリアルタイムで反映するやつ

VirtualHomeはエラーが出たので消した。

他は動いたが、マテリアルエラーになっていたり片目だけでしか表示されないものもあった

Basicは自分の部屋がかっこいい輪郭エフェクト付きでパススルーで表示される

メニューでいろいろ表示とかを変えれる。このメニューの使い方はコントローラーの左手に表示されて、左手スティックで上下、トリガーで決定。(わかりにくいが、片方の手だけで全部完結するの面白い)

メッシュが張られたりいろいろ、ボール投げれたりした

NavMeshシーン二つのライトが動いていた。もしかしたら私の部屋が狭いせいでよくわからない感じになってたのかも

MultiSpawnはよくわからなかった。

FloorZone

AnchorPrefabSpawner

おもしろそう

Building BlockのAnchorColliderSpawnerのことみたい。なんで表記ブレがあるんだろう

このブロック置いて実行したら自分の部屋が出た

Wallなどのプレハブの設定ができるので同じ感じでドアも設定するのだろうか・・・

Cryptic Cabinet 

InteractionSDKのサンプルみたいなのにちょっと毛が生えたやつかと思ったら、結構ちゃんとしたゲームっぽい?すごいレビューがいっぱいある。マルチプレイもできる

www.meta.com

ストアにある動画見たけど楽しそう。自分の部屋で脱出ゲームできるのいいね

中身は公開されている

github.com

とりあえず起動した。

部屋のここにオブジェクトが出るよ~って事前に設定できる。

マルチプレイはコード入力形式

机に合わせて棚が置かれたりしてた。

 

VRM1.0について調べる&アップグレード

ずっとUnityでVRMを使うときvrm0.xを使ってきた。サードパーティーとかOSSの便利ツールが基本vrm0.xにしか対応していないから。

でも1.0が正式版だしそろそろ触ろう

1.0でたの1年半前なのか

gamemakers.jp

VRM0.xから1.0にアップグレード

vrm.dev

互換性

アップグレードの互換性 | VRM

やり方

Editor でアップグレードする | VRM

vrmファイルを選んでMigrate To Vrm1にチェックを入れてApply

vrmファイルがプレハブマークに代わる。これがvrm1.0のvrm

VRM1.0について

Hanatoolを触ったときにはじめてvrm1.0をちゃんと触ったが、フォルダとかも生成されず単体で存在する

bibinbaleo.hatenablog.com

ExtractXXをするとマテリアルとかTextureとか表情のフォルダが生成されてその中にいじれるものが入る

BlendShapeClipはExpressionという名前になった

 

動画を見る

www.youtube.com

ライセンスが0.xの時とは別でちゃんと定義した。VRMパブリックライセンス文書

VRMパブリック・ライセンス文書 1.0

各自が設定したフラグによって解釈を変えれるようにした。文書自体は一つ。配布者はこのライセンスを使わなくてもいい。独自に上書きでライセンスを指定してもいい

項目増えた

楽しいはRelax らく になった。驚き追加!

表情データで、瞬きや口パクで上書きすることを許すかを設定できるようになった!

Blendにしてみて、違和感あったらBlockがいい。

 

瞬きとか口パクはどこから呼び出すんだろう?サードパーティーとか独自のスクリプトで口や目のBlendShapeの変更を呼び出したときにこの設定が適用されるのか?

ドキュメントにあった。以下のExpression

Expression の設定 | VRM

ちなみにBlinkerというスクリプトがvrmデフォルトで用意されてて瞬きするようだが、vrm0.xでしか動かなかった

コンストレイントを設定すると手首がぐにゃっとならない

自作アプリでvrm0.x扱うとき

BlendShapeの値を直接いじらないで><

 

本当はVRMが広がる前に1.0出したかったけど、遅くなってしまったので、1.0が普及するかは皆さんの協力が必要

その他

Clusterが1.0と0.xでの主に見た目などでの変化部分や気を付ける部分をまとめている

https://help.cluster.mu/hc/ja/articles/26313185878553-VRM1-0%E5%AF%BE%E5%BF%9C%E3%81%AB%E3%82%88%E3%82%8BVRM0-x%E3%81%AE%E8%A6%8B%E3%81%9F%E7%9B%AE%E3%81%AE%E5%BD%B1%E9%9F%BF%E4%BA%8B%E4%BE%8B

最後に

VRM1.0に移行できるか心配だったけど、思ったほどたくさん変化があるわけじゃなかったので、今使ってるシステムだと表情操作の部分だけスクリプト対応したらなんとかなるのかな~?

ulipsyncはvrm1.0にも対応しているし

MetaXRSDKのv62の新機能触る【MultiModal、Wide Motion Mode】

v62でいろいろ面白いものが追加されたらしいので見ていく

v62にアップデート

All-in-oneはまだv60のまま

https://developer.oculus.com/downloads/package/meta-xr-sdk-all-in-one-upm/

PackageManagerで見ると一つだけ62にUpdateできるようなのでした。

そのあと再起動をするダイアログが出てした。そしてもう一度見るとなんか真っ赤になってる

とりあえずサンプル系にもUpdateボタンがあったのでUpdateした

62フォルダに入る

そのあともういちどUnity再起動したら赤いの消えてた。Uodateしたもの以外も62になっている。

InteractionSDKのサンプル

以前触った時から3つシーンが追加されている。

UnitySDKのサンプルもだし、AppLabのほうのアプリもアップデートされていた!

Questのハンドジェスチャーでテレポート移動と回転【Unity】 - トマシープが学ぶ

ComprehensiveRigExample

このサンプルを触ってみる

このシーンはもろもろのインタラクションが全て?体験できるシーンみたい。移動もUI操作も遠くの物をとるとかも。

Questのホーム画面のUIみたいなのがあって、大きさ変更したらそれによって内容の数が変わる。

でも実際のアプリのホーム画面は大きさかえれないよね・・・変えたいんだよな~

あと個人的にツボだったのはスプレーの先端の部分を回せたこと。スプレー自体も楽しい

Multimodal機能

また追加されたシーンの一つConcurrentHandsControllersExamplesはハンドトラッキングとコントローラー同時使用のシーン。Multimodal機能と呼ぶらしい

www.moguravr.com

マルチモーダルのドキュメント。Quest3かQuestProのコントローラーでしか使えない。

developer.oculus.com

右手がコントローラー、左手がハンドトラッキングとかできる!!めっちゃいいじゃん。

あと今までハンドトラッキングモードになったらコントローラーの場所が表示されなかったが、この機能が有効だと机の上のコントローラーが表示されるのでコントローラーを見つけやすいのもいい。切り替えも早い。

球を持つときコントローラーを持っているのにコントローラーが非表示になってハンドトラッキングで持っているような演出もあった。

 

もうデフォルトこれでいいのでは…?

 

これでアバター憑依時も片方ハンドトラッキング、片方コントローラーにしたらハンドトラッキングでの表現力も片手分は発揮しつつ、移動やUI操作はコントローラーで簡単にできる。

bibinbaleo.hatenablog.com

と思ったが今使っているOVRBodyとはいっしょに使えないらしい;;

マルチモーダルは、ワイド モーション モード (WMM)、インサイドアウト ボディ トラッキング (IOBT)、およびフル ボディ合成 (FBS) と互換性がありません。これらを一緒に有効にしないでください

developer.oculus.com

bibinbaleo.hatenablog.com

 

設定どれだ・・・?

ドキュメントにある項目はない。ここらへんっぽいが、WMMと一緒に使えないはずなのになんでチェック入ってるんだろ

このスクリプトも関係あるのか?

中身見たがあまり関係なさそう


サンプルシーンの一部説明

developer.oculus.com

QuestLinkだと壊れるんだ

机の上などに置いたときにコントローラーが表示されるようにするには、別途CameraRigの下に新しいアンカーとControllerPrefabを追加しないといけない

でもサンプルシーンにはなんもない



PanelWithManipulators

追加された3つのシーンうち最後はパネルやオブジェクトの大きさ・位置変更操作のUI。オブジェクトの周りに白いラインとかつまむ用の白い点がある。

Wide Motion Mode

手の位置がカメラの範囲から外れても腕の位置から推定して表示してくれる。

www.moguravr.com

Coreのほうのサンプルにあった

実行したけど鏡ないからわからない・・・

鏡追加したけど変わってないと思う・・・Quest3のAirLinkじゃだめなのかな

腕から推測しているときは指の動きは取れないはずだけど、指は動かないけど手の位置は表示されるという場所がない。

Unityの設定はCameraRigのWideMotionModeにチェック

Meta XR SDK(V62)でQuestアプリを開発 | ドクセル

Multimodal機能とは併用できないらしい

OVRBodyが動かない件→解決

MetaXRSDKをv62にしたら、OVRBodyのシーンが動かなくなった。

アバターに動きが反映されず待機モーションのまま

bibinbaleo.hatenablog.com

Oculusソフトのバージョンを確認したら62だったので、ここが原因ではないと思いつつ、なんとなく公開テストチャンネルをオンにしたら、ソフトにアップデートがかかった

そしてアップデートが完了したら動いたw

63になってる。

なんで

VroidHubの撮影機能とVRMアニメーションファイル(.vrma)

VroidHubがアップデート!

www.moguravr.com

撮影機能

昔VRMファイルの撮影ツールでいいのを探してたので、これはどんな感じか気になる。ちなみに今もいいツールなくて結局Unity+スクリプトで撮影してる。

bibinbaleo.hatenablog.com

右上のカメラマーク

ポーズを選ぶ

表情も選べる。

独自の表情パラメーターも変更できる

そして背景で透過&フレームを追加をオフ

撮影サイズは自由には選べない。9:16は1080x1920なので割と大きめではある

 

これでいいタイミングで撮影したら透過pngできた。でも足の影は消せないのかな

パーフェクトシンクの表情も変えれるし、目の位置も変更できるので微妙な顔もできていいね

vrmaをboothで探すというリンクがあったので、押したら5個ぐらい出てきた。タグか

https://booth.pm/ja/items?tags%5B%5D=VRMA

こちらをダウンロードして、vrmaファイルをブラウザで読み込んだ

booth.pm

いい感じ

そういえばモーションが止めれないから撮影しにくいなと思っていたが、右下にモーション再生・停止ボタンがあった

VRMアニメーションファイル

撮影機能にも使えるVRMアニメーションファイル。

XRKaigiのVRMの標準化の講演で初めて聞いた。調べてみる。

 

ここがオリジナルのドキュメント

https://vrm.dev/vrma/

表情や目の位置も記述できるんだ~

エクスポート

uniVRMでの出力

https://vrm.dev/vrma/univrm-vrma/vrma-export/

基本的にbvhしか変換できない

uniVRMが入っているUnityで、menu - VRM1 - Experimental - Convert BVH to VRM-Animation...

そしたらPCにあるbvhファイルを選んで、そのあとすぐに変換されたvrmaファイルの保存ダイアログが出る。

今回はmocopiのbvhデータを使った

Unityにbvhファイルを入れたりする必要もない。Unityの存在感が低い・・・プレビューもないし

それをVRoidHubで読み込ませるとちゃんと動いた。

ばくすたーさんがUnityのAnimationClipをvrmaに変換できるようにしてくださってる

note.com

こちらのunitypackageをいれる

github.com

AnimationClipを右クリック>VRM>Convert

保存

できた~

(VroidHubの撮影機能、vrmaファイルを読み込んで再生停止したあとだと拡大操作などができない・・・)

インポート

スクリプト経由かつランタイムでvrm1.0へしか読み込めなさそう。

vrm.dev

vroidhubだとvrm0.xのモデルにも読み込めるけどな~

表情など

表情とかの情報を含めるのはどうするんだ・・・?

こちらのほうのドキュメントにjsonの仕様?については書いてあった。その中に表情や視線についても書いてある。

github.com

specificationは仕様という意味なのか。

UnityでGLTFをランタイムロード【Unity glTFast】

Unity glTFast

Unity glTFastというのを使う。前から個人の方?が開発してたけど、Unityに統合されたらしい

gamemakers.jp

UnityのほうのGithubページ

github.com

ドキュメント

docs.unity3d.com

zenn.dev

アセットを入れる

これでPackageManagerから入れれる

com.unity.cloud.gltfast

入った

Ver6.2.0

公式ドキュメントのどこにも書いてない・・・と思ってたが、左上のバージョンで6.2.0にしたら書いてあった

ランタイムロード

docs.unity3d.com

空のオブジェクトにGLTFAssetというコンポーネントをつける

そしてgltfかglbのモデルのURLを指定する。

とりあえずこちらの記事の方のURLを使わせていただいた

zenn.dev

そして実行すると3秒後ぐらいに読み込まれた。

GltfAssetをつけたオブジェクトの子になる

 

自分でもLumaAIのスキャンデータをgithubにおいてそれを読み込もうとしたら

glTF has no (main) scene defined. No scene will be instantiated.

と出て読み込まれなかった。

gltfファイルにシーンを設定しないといけないのか・・・?

エディタへのインポート

ドキュメントを見ると普通にglbファイルをインポートできそうだけどインポートしても何も起こらない・・・

docs.unity3d.com

最初一度uniGLTFが競合しているみたいなエラーが出たからそれのせいかな?2回目以降何も出ないが

複数glbインポーターがデフォルトとしてあるときは、片方をオフせよと書いてあった。VRMのほうはオフの仕方わからない・・・

vrm.dev

しょうがないのでglTFastのほうをオフにする

Player設定のOther SettingsでGLTFAST_FORCE_DEFAULT_IMPORTER_OFFを追加する

カスタム製スクリプトシンボル - Unity マニュアル

そしたら無事読み込めるようになった。確かに二つのインポーターがあってuniGLTFのほうがデフォルトになってる。

読み込んだ後でGLTFastのほうに変更できた。

エディタからのエクスポート

うまくランタイムで読み込めたadamHeadと読み込めなかったlumaAIのデータを比べたら階層構造が違うようだ

読み込むためのデータを作るのに、Unity glTFastでエクスポートしたほうがいいのかな~?

docs.unity3d.com

エクスポートは簡単で3種類やり方があってそれぞれ、glb形式かgltfか選べる

これで書き出したら勝手に階層構造がいい感じに変わるのかと思ったが、書き出したものをエディタにインポートしても特に階層は変わっていない。

ランタイムインポートできるか

でもまたgithub経由でランタイムインポートしたら読み込まれた!テクスチャないが

シーンごと書き出しも試した。ついでにポイントライトとかも追加した。

それをランタイムインポートしたら読み込まれた!

やはり一度Unityから書き出さないと読み込まれないのか・・・

テクスチャ

あとテクスチャに関してはUnityから書き出している時点でついてなかった;;

別のfbxのとましーぷちゃんをglbで書き出してランタイムインポートしたらちゃんとテクスチャついた。

glbをglbで書き出してたのがダメだったのか・・・?

LumaAIからobjデータで書き出して、それをUnityでGlbに変換したらちゃんとテクスチャがついた!

ボタンを押したらインポート

またこちらの記事にあるスクリプトを使ったらできた

Unityのラインタイム中に表現に利用する3Dモデルを動的に差し替える

「gltf.Url = "url";」が呼ばれたときに読み込まれるのか~

なんか直感的じゃないような

 

ボタンから呼び出し

最後に

重いモデルだと読み込みに時間がかかるがうまくいっているのかわからないのでローディング中画面を出したい。ドキュメント見た限りそういう機能はないのかな?それとも一般的なやり方がなにかあるのかな~

Haptics Studioを使って振動をUnityに取り込む【Meta】

HapticsStudioというのがあるらしい

去年の3月に出たんだ~

気になるので触ってみる。

環境構築

ドキュメント

developer.oculus.com

PCとQuestにそれぞれアプリを入れる

developer.oculus.com

www.meta.com

Quest側のアプリ単体でいろいろな振動のサンプルを体験できた。

ちなみにQuest3だとアプリは強制的にパススルーモードになる。絶対イマーシブモードにはならない。PCを見ながら操作できるようにという配慮だろうけど、スクショ撮るためにイマーシブモードにしたい

 

同じWiFiにつなげているのにPCとQuestのアプリ同士が接続しない・・・

Quest側に「つながらないときは・・・」みたいなボタンがあったのでそれを押したら、IPアドレスを入れる画面が出てきてそれでPCのIPアドレスを入れたらつながった

 

ドキュメントにはまず最初にLearningからチュートリアルをやろうと書いてあった

チュートリアルは英語。Quest側で同期されるはずだが、Yボタンを押してもずっと一緒の振動しか返ってこない。

Projectsのほうのサンプルは同期した!

ちゃんと同期したらHMDかぶらなくてもYボタン押したら振動が再生される。

UIに使う系のものや、武器・環境音などいろいろある

新規作成

新しいものを作るとき、絶対オーディオファイルから作らないといけない。チュートリアルの最初はシンプルだったのに~

こちらのピンポン!という音をドラッグ&ドロップ

otologic.jp

そしたらすぐに振動になったので、右のスライダーでいろいろいじってみる

いや・・・いい塩梅が全然わからない・・・

サンプルを触ったときは音と振動がすごいしっくりくるな~と思ったけど、自分で作るとただの普通の振動に感じる。何のセンスが必要なんだろう

最初の状態がいいからリセットしたいけどリセットボタンなさそう。

もう一度取り込んだ。

Unityへ

自分のアプリへ取り込む

.haptics形式でエクスポート

ちなみに「音声波形を受け入れるほかのプラットフォーム用に、.wavファイルを統合することもできます。」

 

UnityでHapticsSDKを入れる。All in oneパッケージを入れてたらすでに入ってる

assetstore.unity.com

書き出した.hapticsはそのまま適当に入れればよさそう。SDKの中にもサンプルのhapticsが入っている。でもPCソフトに入っているサンプル全部は入ってなかった。

ui_clickとか使いやすいのに入ってない

サンプルシーンもある

再生の仕方はドキュメントにコード例とか書いてある。

developer.oculus.com

こんな感じ

Clipに.hapticsファイルをセットする。

呼び出したら無事再生できた。

PCソフトのサンプルに入っているui_clickも書きだして、Unityに入れて、uGUIのボタンを押したときにその振動を再生するようにしたら結構いい感じだった。

 

腕を振る移動ジェスチャーで移動したい【Meta】

VRでの移動方法

前回ハンドジェスチャーでテレポート移動はできた。

bibinbaleo.hatenablog.com

でも諸事情でテレポート移動ではなく、アバターが少しずつ動いて移動したい。

傍から見たときに瞬間移動するのではなくちゃんと歩いて移動したように見えたい。

 

腕を振ったら移動するようなのが、コントローラーを使わない中での方法だといいのかなと思った。

vcl.jp

この記事にいろいろな操作方法が書いてある

zenn.dev

 

ハンドジェスチャの認識はIntaractionSDKのサンプル内にもあった。

実際に手話の認識をやっている人もいる

zenn.dev

でも腕を振るというのはハンドジェスチャの認識なのだろうか?

Intarection SDKのサンプルの中にそのポーズをしたかどうか判定してくれるものもあった。これ使えないかな~?ポーズと動作では違うかな。判定も結構シビアだったしな

実装1(ChatGPT)

ChatGPTに聞いたら速度で判定したらといわれた。でもこれだと手を素早く動かしたら移動判定になっちゃうのかな?

とりあえずChatGPTに依頼して作ってもらったコードで動かしたら、手を振ったときに移動するというのはできた。

using UnityEngine;

public class HandMovementController : MonoBehaviour
{
    public Transform leftHandTransform; // 左手のTransformをInspectorから割り当てる
    public Transform rightHandTransform; // 右手のTransformをInspectorから割り当てる
    public Transform hmdTransform; // HMDのTransformをInspectorから割り当てる

    public GameObject cameraRig; // CameraRigオブジェクトをInspectorから割り当てる
    public float movementSpeed = 1.0f; // 移動速度
    public float handMovementThreshold = 0.05f; // 手の動きのしきい値

    private Vector3 previousLeftHandPosition;
    private Vector3 previousRightHandPosition;
    private bool isLeftHandMoving;
    private bool isRightHandMoving;

    void Start()
    {
        // 初期位置を記録
        previousLeftHandPosition = leftHandTransform.position;
        previousRightHandPosition = rightHandTransform.position;
    }

    void Update()
    {
        Vector3 currentLeftHandPosition = leftHandTransform.position;
        Vector3 currentRightHandPosition = rightHandTransform.position;
        Vector3 hmdForward = Quaternion.Euler(0, hmdTransform.eulerAngles.y, 0) * Vector3.forward;

        // 左右の手の前後の動きを判定
        isLeftHandMoving = IsHandMoving(currentLeftHandPosition, previousLeftHandPosition);
        isRightHandMoving = IsHandMoving(currentRightHandPosition, previousRightHandPosition);

        // 交互に手が動いているかを判定
        if (isLeftHandMoving != isRightHandMoving)
        {
            // HMDの向いている方向に水平移動
            cameraRig.transform.position += hmdForward * movementSpeed * Time.deltaTime;
        }

        // 現在の手の位置を更新
        previousLeftHandPosition = currentLeftHandPosition;
        previousRightHandPosition = currentRightHandPosition;
    }

    bool IsHandMoving(Vector3 currentHandPosition, Vector3 previousHandPosition)
    {
        // 手の動きがしきい値より大きいかを判定
        return (currentHandPosition - previousHandPosition).magnitude > handMovementThreshold;
    }
}

動きがかなりかくかくしてる・・・

あと手を振るとかほかの動作をしているときにも動く。

Godotのシーンをもう一度いろいろ動かしたが、片手だけ降っているときとかバイバイ👋の動作とか、両手を同時に同じ方向に振るとかをやっても動かない。

ちゃんと左右交互に走るときみたいに動かしたときだけ反応する。

あとGodotは移動パワーが加わってる感じでスーって動く

もうGodotの実装見ようと思ったが、どこが実装のコードなのかわからない。それっぽいのないんだけど;;

実装2

私のググり方が悪いだけでどこかにコードあるかもと思ってcopilotに聞いたら普通に出てきた。

qiita.com

こちらはOVRPlayerControllerがある状態で動く

ハンドトラッキングだと動かなかったが、コントローラーを持った状態だと動いた。

スクリプト内でコントローラー参照しているな~

ただこちらも同じく手を振る動作とかでも少し移動してしまう。ChatGPTのよりは誤作動少なそうだが

ChatGPTのと違うのは頭の方向じゃなくてコントローラーを振った方向に移動する。前後じゃなくて左右気味に動かしたらそちらに動く。頭を動かさないでいいので便利。

ChatGPTに聞いて

//touchVelocityL
//    = OVRInput.GetLocalControllerVelocity(OVRInput.Controller.LTouch);

の部分を手の位置から計算したVelocityなどに変えてハンドトラッキングモードでも動くようにスクリプト変更しようとしたが、手を動かすと動きはするが移動する向きが合わない・・・

ちなみにOVRInput.GetLocalControllerVelocityで検索したら別の腕振り移動記事が出てきた。

qiita.com

手の加速度

communityforums.atmeta.com

【Unity】QuestのハンドトラッキングでuGUIのUI入力【Poke&Ray】

以前Building BlockのPoke機能を使ってのUI入力はやった

bibinbaleo.hatenablog.com

このときはuGUIで作ったUIへの入力がうまくいかなかったが、InteractionSDK内に公式uGUI操作サンプルを見つけたのでそれをもとにやる。

この記事の時に見つけた。

bibinbaleo.hatenablog.com

Poke

PokeExample

カーブとフラットの二つのuGUIキャンバスがあった。フラットのほうがシンプルだしフラットでいいのでそちらを見る

Canvasの親にPokeInteractableなど3つついてる。EventWrapperはEvent使わないならいらない。

普通のCanvasにPlaneSurfaceというのがついている。テレポートの時も使ったな~

Surface

自分のシーンへ

FlatUnityCanvasをプレハブ化して、以前Pokeを実装した自分のシーンにもっていったらすぐに動いた。

でも別のPokeを実装してないシーンにもっていっても動かない。

OVRInteractionはあって、HandPokeInteractorもあって、CameraRigの下にはOVRHandもあって手は表示されるのにな~

 

よくわからないけどHandRayInteractorを追加したら動いた。関係ないかも

コントローラーではできないかと思ったら、次の章でRayを追加したおかげかわからないけどコントローラーの白い丸のところで押せた。

Ray

RayExample

前も書いたが、PokeよりRayのほうがUIの置き場所が自由で使いやすそう。QuestのハンドトラッキングのRayはちょっと精度が悪くて使いにくいけど

RayExampleにあるUIもuGUIを使っているものだった

UnderlayとAlphaCutoutの違いはよくわからない・・・AppLabので実機でも見たけど何が違うんだろう

MeshについているRenderingModeでかえれる

PointableCanvasModuleというのもいるのかな?

自分のシーンへ

以前BuildingBlockのPointableItemを置いたシーン(Pokeと同じシーン)にPointableCanvasModuleとCylinderごと置いたら動いた。

でもその下のCanvas単体(OculusInteractionSamplesRayCanvas)を置いても動かない・・・

細かく見たらMeshというところにCylinderをセットする必要があった

これで反応するようになった。

 

別のシーンにもっていってOVRInteractionの下にHandRayInteractorを追加したら動いた

あとコントローラーでもRayを出すためにここにこれを入れる

できた

これでこの記事の時実装したコントローラーからのRayもいらなくなった!metaデザインのRayを使える

bibinbaleo.hatenablog.com

2重

UIも変えたとき2重に表示されることがあった

Meshオブジェクトの位置にも表示されるらしい。Rayが反応するのはこちら。

Canvasの位置を0,0,0にしてMeshオブジェクト同じ位置にしたら治った。

もしくはCanvasについているこれをFixにしたら、Cameraからは表示されなくなった。シーン上では2重に表示される

 

最後に

結構プレハブが複雑で自分で一から作るという気になれない。

諸々デフォルトでuGUI対応したらいいのにな~

AppleVisionProなら勝手にいい感じになるんだろうな~

Questのハンドジェスチャーでテレポート移動と回転【Unity】

時代はコントローラーレス!!

コントローラーを使わず、ハンドトラッキングによるハンドジェスチャーだけで仮想空間内を移動&回転したい

今のところアプリづくりにMetaXRSDKしか使ってないので、その機能だけで作れると嬉しい・・・

 

あと本当はコントローラーを使いたくない理由としては、アバターに憑依するときに指の動きなどを反映したいからだから、指輪型の小さいデバイスとかでもいいんだが

bibinbaleo.hatenablog.com

サンプル

FirstHand

唯一知っている事例は最近Quest3発売に合わせてMetaが正式に出したFirstHandアプリ内の移動ジェスチャー

www.meta.com

この中で移動・回転があって感動した。初めてハンドジェスチャーで移動した。

ちなみにこの部分以外も初めのパススルーと組み合わせてポータルが開くところとかめっちゃクオリティ高くて楽しい。

 

昔からFirst Handというアプリはあったけどたぶん進化している?

www.moguravr.com

昔のFirstHandバージョンはソースコードもあったらしいが見たら2年前で更新終わってた

github.com

Interaction SDK

でもInteraction SDKのページを見たらサンプルの中に移動とかスナップあるらしい!

developer.oculus.com

サンプルはInteraction SDK SamplesがAppLabで出てる!

www.meta.com

遊んだけどいろいろサンプルあってすごい面白かった!!!!

移動はFirstHandと同じ方式。いまいちテレポートの発動の仕方がわからない・・・

そして今回の記事には関係ないけど移動以外にもいろいろある。

RayでのUI選択や

PokeのuGUI!これ前試してできなかったたやつだ!サンプルここにあったのか

bibinbaleo.hatenablog.com

あと面白かったのは自分のポーズを目の前のフィギュアがしてくれるやつ。ちゃんと身長も反映されている?

Move Fast

ちなみにMove Fastというサンプルアプリもある

https://www.meta.com/ja-jp/experiences/6087525674710349/

こちらはGithubもあって4か月前の更新

github.com

でも遊んだらこちらはボクシングの音ゲーみたいなやつだった。めちゃクオリティ高いけど移動はない

Unityで実装

InteractionSDKのサンプルはUnityAssetStoreにもあった。

assetstore.unity.com

入れた

All In Oneパッケージの中にはサンプルはなかったのか。フェイストラッキングのサンプルが入ってたMovementと同じような感じかな?ちょっと形式が違うけど

bibinbaleo.hatenablog.com

AppLabにあったシーンが一通り入っている

その中のLocomotionExampleが今回のターゲット

どれが最低限必要な要素なんだ・・・

NavMeshいるのか?青い範囲しかテレポートできなかったけど。

ドキュメントページが見れない

developer.oculus.com

と思ったが左上のプラットフォームをUnityにしたら表示された

ドキュメントによると「テレポート インタラクションは、TeleportInteractorとTeleportInteractableという 2 つのコンポーネントで構成されます。」

これはコントローラーの時もそうだった気がする。

そしてHandの場合、TeleportInteractorはここにあった!

Turnも同様

OVR Interaction配下を自分のシーンに置いたらいいのかなと思ってOVRCameraRigtとかアバターとかいろいろ入っているシーンにおいたけど、自分の手の形も出なかった;;

 

InteractionRigOVR-Syntheticごと新しいシーンに置いたら手も出て、回転もできた!

テレポートもUIは出た。でもPlaneだけだと移動できる場所がないのか赤いレイが出るだけで移動できない。床の設定方法は後述

 

OVRCameraRigがあらあじめ置いてあるシーンで、OVRCameraRigのHandAnchorの下にOVRHandPrefabを置いておくと動いた。OVRMeshはオフにしておかないと2重で手が描画される。

確かにサンプルのほうのCameraを見てもOVRHandが置いてあるな~

これで一応自分のシーンでも移動と回転ができるようにはなった。

でも回転の決定で親指と人差し指をタップする動作が、たぶんAボタンにかぶっていて、もともとAボタンに設定していた操作も反応するようになった;;

まあハンドトラッキングオンリーで行くならその操作もどうにかしないといけないからしょうがないのか。

Teleport Interactable

移動するための床側に必要なTeleport Interactableに設定するSurfaceには3種類設定できるらしい

コライダーとPlaneとNavMesh

plane

Planeは普通の3DオブジェクトのプレーンじゃなくてPlaneSurface。AllowTeleportはオフにして、TileBreakerStoreは-100だって

これでこの格子が表示されてテレポートのレイは反応するようにはなったけど、AllowTeleportしていないのでテレポートできない

なんでAllowTeleportしてはいけないんだろう・・・Plane上を移動したいのに

AllowTeleportにチェック入れたら移動できたからつけておけばいいのかな?

NavMeshの作成には床にしたい場所のオブジェクトのStatic状態をNavigation Staticにするって書いてた。けど選べない

docs.unity3d.com

最後に

途中で気づいたけど私がしたい移動はテレポート移動じゃなくてスーって動くジョイスティック移動?だった

それはそれでUI難しい。

走るときのように腕を振ったら移動するというサンプルがGodotにあるはずなのでそれできるとよさそう。Metaにもないかな~

 

Figma→UnityのToolを試す【UnityFigmaBridge】

ここで紹介されているUnityFigmaBridgeを試す

zenn.dev

Unity Figma Bridge ver1.0.8

Unity 2022.3.7

初期設定

Figma側の構成やUnityの設定でいろいろできることが変わるが、とりあえず流れを知るためにざっくり適当なファイルで連携してみる

Figma側

設定から個人トークンを作成

あとシーンのURLが必要

Unity側

PackageManagerで

https://github.com/simonoliver/UnityFigmaBridge.git

を取り込む

github.com

Unityの上のメニューのFigmaBridgeのAccessTokenでFigmaのトークンをはる

 

プロジェクトセッティングのUnityFigmaBridgeでCreateを押す

CreateしたらAssets直下にUnityFigmaBridgeSettingsというのができる。メニューからも選択でき手インスペクタで表示される

Document URLにFigmaファイルのURLを貼る。これデスクトップで作ってたらどうやって確認するんだろう~ 

OKなURLだったら緑でValidFigmaと出る

RunTimeAssetsSceneにシーンのパスを書くらしい。(Figmaにシーンなんて概念なくない!?って思ったらUnityのシーンだった。最悪書かなくても今開いているシーンが勝手に入ってくれた)

TextMeshProがUnityに入ってなかったら入れておく

そのあとSyncDocumentをメニューから選ぶとインポートされる

ここにページ丸ごとプレハブが入ってた

Screensフォルダの中にはFrameが全部プレハブ化されている

それをシーンに勝手に追加されていたCanvasの下に置いたらとりあえず表示された!

日本語以外は表示されている

Figma

Shadowコンポーネント、Unity側にもついてるのになんか反映されてないな~

ImageコンポーネントはFigmaImageというものになってる。画像名はFigmaから変わっている

いろいろ設定

ドキュメントなど読みつついろいろ細かい設定してみる

Unity側

Only Import Selected Pageにチェックを入れるとFigma側のページを選べる

フォントも一致するGoogleフォントをダウンロードしてくれるみたいだけどどこで有効にするか分からないな~

名前でも検索してくれるらしいので、最初からUnityに入れておいてもよさそう

Figma側

最初の紹介記事によると

Figma上に「SafeArea」という名前のオブジェクトがあればSafeArea対応のコードも自動付与してくれたり、

「button」という名前が入っているオブジェクトがあればボタン化してくれたり、

フレームと同じ名前のクラスがあれば自動でAdd Componentしてくれて、

さらにSerialize Fieldされた変数の名前と一致するオブジェクトがあれば自動割り当てしてくれたり

してくれるらしい!!

Readmeにも確かに書いてある

あとFigmaのプロトタイプ機能で実装した遷移も反映してくれるらしい

ということでプロトタイプ機能でつなぎつつ、safeareaとbuttonの名前がついたものを追加したデザインを作った

そしてUnityの別シーンへsynxしたら今度は最初からCanvasの下に入った!

プロトタイプ機能で最初の画面を設定しているからかな?

プロトタイプ機能

そして実行したらちゃんと遷移した!プレハブが読み込まれて差しかわる

なんか一瞬黒くなるトランジションのエフェクトも入ってる

text

英語のテキストでNotosansを使ってると、Unityにも勝手にフォントを入れてくれてた

でも日本語はだめだ~

ボタン

ボタンには普通のButtonコンポーネントと遷移用のスクリプトがついてる

「ボタンが追加されると、「selected」という子ノードが検索されます。これが見つかった場合は、これをロールオーバー状態に使用します。」って書いてたからFigma側でどうにかしてselected状態のUIを設定したら反映されるのかな?

同じ名前にselectedを付けたものを近くに置いてるだけじゃさすがにダメだった

InputField

Figmaで名前にInputFieldを付けたら、Unityでもついてた。でもこれはTextMeshPro用じゃないんだな。参照するTextが普通のTextのみになってる・・・

safearea

safeareaもスクリプトついた。

しかもすごいのが実行したら、UI自体は非表示になった。Figmaではsafeareaの範囲を分かりやすくするためにいつもピンクの枠にしていて、Unityでも実行前はその枠があるけど実行したら消える

でもよく考えたらsafeareaはUnityでは構造的には親にあってほしい

bibinbaleo.hatenablog.com

 

同期後の修正の反映

Unityに一度取り込んだ後、Figma側でUIを追加して、もういちどsyncしたらちゃんとシーン上のプレハブに反映された。

でもプロトタイプの遷移の変更は反映されないのかな・・・?

スクロール

プロトタイプでスクロール対応したらちゃんと反映された。

マルチ解像度

一番大変なマルチ解像度対応

Figmaでなにも設定しない状態だと上固定かな?

そして私がFigmaであんまりレイアウト設定しないから、FigmaでどうしたらUnityみたいなレイアウト設定ができるかわからん・・・

なんかここで設定するはず

適当に設定して同期したらUnityでも反映されていることは確認した。

Unityで変更

Unityでプレハブ内の構造やコンポーネントなどを変えた後、Figmaから再度同期したらどうなるか。

Unityで行った変更はどこかに行ってFigmaの構造に戻ってしまった;;

Unityでvaliantのプレハブにしてその中で変更した後に、同期したらさすがに大丈夫かと思ったが、Variantでの変更も消えた;;

QuestのOVRBodyのFullBodyのサンプル触る&自分のキャラへ適用【Unity】【IOBT+Generative Legs】

IOBTとGenerative Legs

IOBTというやつでQuest3では全身トラッキングができる!と思ったけどちょっと違った。

IOBT自体は上半身を精密にトラッキングするというもの。

脚の部分は

AI 生成の脚は、Meta が「Generative Legs」と呼んでおり、より現実的なアバターの脚を可能にします。

IOBT とは異なり、ユーザーの脚の位置は Quest の内蔵センサーによって追跡されません。IOBT の追跡データをより正確に機能させる AI モデルによって推定されます。ただし、ジェネレーティブ レッグは IOBT なしでも機能し、古いQuest 2およびQuest Proヘッドセットによってサポートされます (精度は低くなります)。

mixed-news.com

だって。QuestProとか2でもFullBodyのトラッキングができるということ!

でもQuest3のほうが足も精度は高くなるらしい

 

あと開発者向けの記事にいろいろ注意点が書いてあった

Generative Legs の場合、ボディ トラッキングの開始時に、ヘッドセットから床までのおおよその高さが測定されます。各セッションは、ユーザーが立った状態で開始する必要があります。ボディスケールが正しく見えない場合は、Oculus ボタンを 2 回押してキャリブレーションをリセットします。また、このキャリブレーションのためにガーディアンを初期化する必要があることにも注意してください。座っているユーザーの場合、ユーザーは手を伸ばして円を描くように移動し、翼幅を使用して身長を推定できます。あるいは、新しいキャリブレーション API を使用して高さを明示的に設定することもできます。

https://developer.oculus.com/documentation/unity/move-body-tracking/

 

酔い改善に貢献するらしい

 

Dodge Arcade 

上の記事に載っていたDodge ArcadeというMetaが出しているアプリで体験できるって

https://www.meta.com/ja-jp/experiences/6511679575602893/

やってみたがかなり楽しい。小さい自分を後ろから見る

飛んでくるドッチボールはよけてサッカーボールは取るというゲームで、なんかツイスターとかポーズをとって迫り来る壁を抜けるゲームみたい

prtimes.jp

上半身は遠くのボールを取りつつ、足はよけるみたいなシーンもあってちゃんと反映されてた気がする

PVより

MovementLocomotionサンプル

環境

・Quest3

・Unity2022.3.7

・MetaXRSDKv60

 

ちょっと特殊な場所にあるMovementSDK内のMovementLocomotionというサンプルで全身を動かすのを体験できる

bibinbaleo.hatenablog.com

IBOTにするかどうかも選べる。

動かしても違いが分からなくて、ボタンがどっちの状態だとIOBTなのかもわからなかった。

youtu.be

他のUIの法則性やインスペクタを見た限りIBOTと表示されているときにIOBTになっているようだ。

CurrentFidelityがHighがIOBTっぽい

自分のキャラへの適用

これをVRMキャラに適用したい。

これができればFinalIKいらないかな~?

Twitterでやっている人いるけど記事なさそう・・・

 

サンプルシーン経由(無理)

サンプルシーンを参考に一つ一つコンポーネントつけていくか~

とりあえずサンプルシーンのアバターをプレハブ化して自分のシーンに持ってきたらちゃんと動いた

いろいろついてるんだよな~

VRMアバターに全部つけてみたけどRigBuilderとかもろもろよくわからない。当然ピクリともしなかった

ドキュメント見ながら

日本語のドキュメントを見てたけど、

Unity向けMovement SDKのボディトラッキング: Unity | Oculus開発者

同じページの英語版を見たらめっちゃ細かくセットアップの仕方を書いてた!!

https://developer.oculus.com/documentation/unity/move-body-tracking/

(※ログインしないと詳しい内容のページにたどり着けない?ログアウトしている状態だとURLは同じなのに内容が日本語版ページ版になってた)

 

Modelのfbxデータとかがある場合は、Humanoidにしたり、「マッスルと設定」で、設定の一番下にあるTranslation DOFがチェックされていることを確認する。

VRMのデータだと見れないので、チェック入ってることを願う

Mixamoでインポートしたモデルだとチェック入ってなかった・・・

あと初めて知ったが、Modelのところで大きさを変更できる!モデルをシーンで大きさを変えると不具合が出るのはよく知られているし、ドキュメントにもそう書いてあったので、程よい大きさにするにはここで調整

そしてモデルデータを右クリックしてMovement Samples > Body Tracking > Animation Rigging Retargeting (full body) (constraints)

すると必要なコンポーネントが一気についた!

Rigもいい感じに入ってる!

OVRManagerではIOBT(BodyTrackingFidelityをHigh)とFullBodyを設定

なんとこれだけで動いた!!!

すごいことにはなっているけど!

 

指は完ぺきに動いた!すごい!

これしなくてもOVRBodyの機能で動くんだ!

bibinbaleo.hatenablog.com

FullBodyHandDeformationのおかげかな?

調整(分からない・・・)

この感じは、MovementSDKのサンプルでもあった。

MovementRetargeting

あれはちゃんと設定しないとこうなるよっていうサンプルだったのかな~

で、調整しようとドキュメント後半を読んだけどよくわからない・・・Weightを調整するっぽいが・・・

RigのDeformationConstraintについて書いてはありそう

あとモデルの一番上についているRetargetingLayerのWeight

ここら辺変えたけどうまくいかない。ウエイトを0にしたら動かない代わりに破綻しないとかはあったけど

 

VRMモデルのせいかと思ったが、Mixamoのモデルでも変わらない。

腕だけが目立ちがちだが、上半身の胴体が回転しないとかもある。

youtu.be

手の位置はあっているけど、それ以外があっていないのか・・・

ボーンビジュアライズ

ボーンのビジュアライズはできた。


DebugBonesとDebugBonesOVRSkeletonFullBodyというプレハブがあるのでそれを置いて、それぞれ設定

FullBodyのほう(白色)はOVRから来るボーンのが見える化される

DebugBone(黄色)は実際にAnimatorで動いているボーン?白いボーンはちゃんといい感じになっているのがわかる

具体的にどこのボーンのせいでぐちゃぐちゃになっているかがわかりやすい

 

Animator経由で送る(失敗)

うまくいっている青いサンプルアバターの動きをAnimator経由で送ったらどうなるか試した。

受け取るほうのアバターはOVRBodyとか何もつけていないVRMアバターの素の状態にした

ChatGPTに頼んだら動くもの作れた

public class AvatarMotionTransfer : MonoBehaviour
{
    public Animator sourceAnimator;
    public Animator targetAnimator;

    void LateUpdate()
    {
        CopyAvatarTransforms(sourceAnimator, targetAnimator);
    }

    void CopyAvatarTransforms(Animator source, Animator target)
    {
        foreach (HumanBodyBones bone in System.Enum.GetValues(typeof(HumanBodyBones)))
        {
            if (bone == HumanBodyBones.LastBone) continue;

            Transform sourceTransform = source.GetBoneTransform(bone);
            Transform targetTransform = target.GetBoneTransform(bone);

            if (sourceTransform != null && targetTransform != null)
            {
                targetTransform.localPosition = sourceTransform.localPosition;
                targetTransform.localRotation = sourceTransform.localRotation;
            }
        }
    }
}

そしたら動きは同期はされたけど、相変わらずVRMアバターは崩れたままだった;;

左がAnimator経由で動きを送った子。右の子のようにOVR経由だと指とかはうまくいってたのにそれも変になっている。


解決

HumanPoseHandlerを送るようにしたら反映された

using UnityEngine;

public class AvatarMotionTransfer : MonoBehaviour
{
    public Animator sourceAnimator;
    public Animator targetAnimator;
    private Avatar m_SourceAvatar;
    private Avatar m_TargetAvatar;
    public HumanPoseHandler m_SourcePoseHandler;
    public HumanPoseHandler m_TargetPoseHandler;
    private HumanPose m_SourcePose;
    private HumanPose m_TargetPose;
    public bool m_LerpEnabled = true;
    public bool m_FixedBodyPosition = false;
    public Vector3 BodyPositionCorrection = new Vector3(0.0f, 1f, 0.0f);

    void Awake()
    {

        if (sourceAnimator != null && sourceAnimator.avatar != null)
        {
            m_SourceAvatar = sourceAnimator.avatar;
            m_SourcePoseHandler = new HumanPoseHandler(m_SourceAvatar, sourceAnimator.transform);
            m_SourcePoseHandler.GetHumanPose(ref m_SourcePose);
        }

        if (targetAnimator != null && targetAnimator.avatar != null)
        {
            m_TargetAvatar = targetAnimator.avatar;
            m_TargetPoseHandler = new HumanPoseHandler(m_TargetAvatar, targetAnimator.transform);
            m_TargetPoseHandler.GetHumanPose(ref m_TargetPose);

        }
    }


    void LateUpdate()
    {
        CopyAvatarHumanPose(sourceAnimator, targetAnimator);
    }

    void CopyAvatarHumanPose(Animator source, Animator target)
    {
        if (m_SourcePoseHandler != null && m_TargetPoseHandler != null)
        {
            m_SourcePoseHandler.GetHumanPose(ref m_SourcePose);

            m_TargetPoseHandler.SetHumanPose(ref m_SourcePose);

        }
    }
}