20211201のUnityに関する記事は19件です。

[Unity] Visual Effect GraphのSDFとParticle Stripを使ってみた

初めてVisual Effect Graphを触ったので、作ったものの紹介や感想を書いていきます。 今回VFXの説明は省きます(まだそんなに詳しくない)のでVFXについて知りたい方は別途調べてみてください!  環境 ・Unity2020.3.20f1 ・Visual Effect Graph 10.6.0 ・Universal RP 10.6.0 作ったもの 早速ですが制作したものがこちら 外側から画面奥にかけてパーティクルが動いています。 カラフルな線に包まれているようなエフェクトです。周りの白いパーティクルもランダムに生成されています。 もう一つは球体の周りを這うようなエフェクトです。 それでは制作過程の紹介に入ります!   Particle Strip 最初はカラフルな線のほうから! Particle Stripについて軽く説明すると、パーティクルの軌跡を描画できるものです! Particle Stripの説明はUnityJapanのこちらの動画がとても分かりやすいです! https://youtu.be/gdb9zvHh3r0 今回作りたかったのは奥に向かって流れるカラフルな線だったので、カラーの設定以外には特別な処理はありません。 Update Particle Stripの中身をいじればぐにゃぐにゃにすることもできます! 今回は触りだけやってみましたが、いろいろと遊べそうな感じです。 そして、制作中につまづいたところの話 TriggerEventRateがない 最初にTriggerEventRateを使おうと思ったときでした、検索しても出てきません!! なんでないんだ?????と調べてみると、どうやらデフォルトでは使えないようになっているようです。 PreferencesのVisualEffects内の Experimental Operators/Blocks にチェックを入れると使えるようになります!まだ実験的実装ということでしょうか…  SDF 次は球体のほうです! SDFを使うと、メッシュの表面にパーティクルを這わせたり、メッシュ表面に向かってパーティクルを飛ばすなどができます! 今回の作品だとわかりづらいと思うのでStanfordBunnyに協力してもらいました。 それがこちら パーティクルがメッシュの表面に生成されて、よく見るウサギさんが現れました!! このようにSDFを使うといろんな形を表現できます! ちなみに、メッシュ表面にパーティクルを生成するだけならPoint Cacheでも表現できます! メッシュから一定距離を保ちながら移動できるのがSDFのいいところだと思います。 注意! 製作途中で気が付いたのですが、メッシュをSDFにベイクするためのSDF Bake ToolがUnityにあるのですが最新バージョンでしか使えないそうです。 具体的には2021.2以上で使うことができるようです… 今回は2020.3.20を使っていたので、ベイクできない!!  なのでウサギさんと球体は別プロジェクトを作りそこでベイクしたものを持ってきました。 (ほかのやり方もあるみたいですが、Unity内でできる2021.2以上のバージョンのほうが楽そうです) まとめ 初めてVisual Effect Graphを試してみましたが、きれいな見た目を簡単に作れるのでとても楽しいです! 新機能も追加されていくそうなので、またいじくってみようと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

同じシーンの中で状態遷移を実装するベストプラクティス

はじめに メインゲームなど中心的なシーンでは、開始演出、ゲーム本編、結果発表、などの複数の状態を同じシーンの中で切り替えて実装する場合があります。 最初はキレイにかけていたとしても、作り込むにつれて複雑で見通しが悪いコードになってしまうこともしばしばありました。この記事では、先日リリースできたゲームの状態管理の仕組みをベースに、開発中に課題に思った点を整理して、自分なりのベストプラクティスな設計を考えてみます。 この記事に含まれている要素は、主に以下の通りです。 状態遷移の管理方法の一例 UniRxの購読を止める方法 ポーズの実装方法の一例 この記事では説明用に一部のソースコードのみ抜粋・編集しています。 動作する全コードを知りたい場合は、githubのサンプルを御覧ください。 作成した状態遷移のサンプル 仕様 同じシーンの中にSTATE_A(黄)STATE_B(青)STATE_C(紫)の3つの状態がある。 それぞれの状態では、0.1秒ごとにオブジェクトを生成し、20個になると次の状態に進む。 スペースキーで、ポーズの開始と解除が切り替わる。 画面をクリックすると、どの状態が有効なのかをログに表示する。 実装の特徴 状態とUIをセットにする 状態とUI画面は、ほとんどの場合、セットになるのではないでしょうか。 この設計では、Canvas以下のゲームオブジェクトに状態名をつけ、併せてUIのレイアウトを行いました。 また、Sceneウィンドウで、全UIを見渡しやすくするために、並べています。 (全UIは、実行時に中央に集まるようにしています) レイアウトの位置が分かりやすいように、少しだけ背景に色をつけています。 (これも実行時に透明になります) オブジェクトのアクティブ・非アクティブで、状態の有効・無効を表現する ゲーム実行中、アクティブな状態はヒエラルキーで、白文字で表示され、無効な状態は、グレーアウトします。 ヒエラルキーを見るだけで、どの状態が有効かが、すぐに分かります。 また、その状態で必要なオブジェクトは、各状態の子要素として生成します。 オブジェクトをアクティブ、非アクティブにしたときをトリガーにして呼ばれる関数があります。 OnEnable() と OnDisable() です。 ここでは、この仕組みを利用して各状態の初期化、終了処理を記述しています。 状態の開始時と終了時にUniRxの購読を開始、停止している UniRxの購読は、気が付かないところで購読され続け、不具合の原因になることがあります。 例えば、適当なスクリプトのUpdate関数に、何か処理を書いたとしましょう。シーン遷移した場合、オブジェクトは破棄され、そのUpdate関数の中に書かれた処理が実行されることはありません。 しかし、UniRxの Observable.EveryUpdate() を使い、購読した場合、停止処理を書かないとシーンを遷移しても実行され続けます。 ここでの設計では、前述のシーン遷移時に呼ばれる、OnEnable() と OnDisable() を利用して、購読の開始と停止を記述します。 public class EachScene : MonoBehaviour { // 購読しているリスト private List<IDisposable> disposables = new List<IDisposable>(); // 状態オブジェクトがアクティブになったときに呼ばれる void OnEnable() { Observable.Interval(TimeSpan.FromSeconds(0.1f)) // 0.1秒ごとに生成 .TakeWhile(_ => this.objectsRoot.childCount < 20) // 20個に達するまで .Subscribe(_ => { // 生成部分 }, () => // 20個に達したら呼ばれる { // 自らを非表示にすると、OnDisableが呼ばれる this.gameObject.SetActive(false); }) .AddTo(this.disposables); // 購読しているリストに追加 } // 自分自身が破壊されたり、非アクティブになったときに呼ばれる void OnDisable() { // 後述するが、子要素を破壊する foreach (Transform child in this.transform) Destroy(child.gameObject); // 購読停止処理 foreach (IDisposable disposable in this.disposables) disposable.Dispose(); } } サンプルでは、立方体などのオブジェクトが次々に生成され、回転します。 この回転にもUniRxを使用しています。 ここでは Start() で購読が開始され、このスクリプトが破棄されたとき購読が停止されます。 public class SimpleRotation : MonoBehaviour { void Start() { Observable.EveryFixedUpdate() .Subscribe(_ => this.transform .Rotate(Vector3.right * Time.deltaTime * 100f)) .AddTo(this); // このスクリプトが破棄されたときに、購読も停止されるように指定 } } 状態遷移時に、その状態の子要素を一括して破壊することで、まとめて購読を停止される設計です。 非アクティブになるときを状態遷移のトリガーにしている SceneManager.cs が、意図した順番に、状態のオブジェクトをアクティブにします。 それぞれの状態のスクリプト(ここではEachState.cs)が、それぞれの条件を満たしたときに、自らを非アクティブにします。 SceneManager.csは、状態のオブジェクトの非アクティブを監視しており、その状態が終了したことを知ります。 非アクティブになったオブジェクト名(状態名)から、次の状態のオブジェクトをアクティブにします。 public class SceneManager : MonoBehaviour { private GameObject targetState; // 監視する状態のオブジェクト void Start() { // 最初の状態を指定 ActivateState("STATE_A"); // 各状態が終わったときの遷移先を指定 Observable.EveryFixedUpdate() .Select(_ => this.targetState.activeInHierarchy) .DistinctUntilChanged() .Where(active => !active) .Select(_ => this.targetState.name) .Subscribe(stateName => { switch (stateName) { // ここにそれぞれの状態が終了したときに、次に何をすべきかを指定する case "STATE_A" : ActivateState("STATE_B"); break; case "STATE_B" : ActivateState("STATE_C"); break; case "STATE_C" : ActivateState("STATE_A"); break; default: break; } }) .AddTo(this); } private void ActivateState(string stateName) { var state = this.transform.Find(stateName).gameObject; state.SetActive(true); // 監視対象に this.targetState = state; } } TimeScaleでポーズ機能を実装している ポーズ機能を実装するにあたり、お手軽な方法はTime.timeScaleを0にすることです。 Time.timeScale = 0f; こうすることで、Time.delataTimeを使ったアニメーション処理を止められます。 サンプルではスペースキーを押すとポーズの開始と解除ができます。 一見簡単なのですが、気をつけなくてはならないことがいくつかあります。 Update()はtimeScaleの影響を受けないので、この関数の中に書かれた処理は動き続けます。 一方で、FixedUpdate()はtimeScale=0のときは止まるので、ポーズで止めたい処理はこちらを利用します。 ただしInputクラスはFixedUpdate()の中に書くと、挙動が変になるので、Update()関数内で書かなくてはなりません。 ここではUniRxのBatchFrameオペレーターを使用して、止められるようにしています。 Observable.EveryUpdate() .Where(_ => Input.GetMouseButtonDown(0)) .BatchFrame(0, FrameCountType.FixedUpdate) // InputはUpdateでないと正しく動かない .Subscribe(_ => Debug.Log(" Click! <= " + this.gameObject.name)) .AddTo(this.disposables); ポーズ画面で動かしたい処理は、Update() で書けば動きます。 ただしアニメーションさせたいときはdeltaTimeを使ってアニメーションの見え方を一定にしたいところ。 無理やりですが、UniRxのスケジューラー機能を使って、timeScaleを無視するスレッドを指定します。 Observable.EveryUpdate() .Where(_ => Input.GetMouseButtonDown(0)) .BatchFrame(0, FrameCountType.FixedUpdate) // InputはUpdateでないと正しく動かない .Subscribe(_ => Debug.Log(" Click! <= " + this.gameObject.name)) .AddTo(this.disposables); 最後に… 以上が、現段階の状態遷移の設計です。 分かりづらい部分や、もっと良くするアイディアがありましたら、ご指摘頂けますと幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DOTSベースのUnity PhysicsはPhysXよりどの程度軽量なのか?

PONOS Advent Calendar 2021の7日目の記事です。 昨日は@blockさんでした。 はじめに Unityの物理演算はPhysXが採用されていますが、既に発表されているように新たにDOTSベースで動作するUnity Physics/Havok Physicsが開発されており、現在Preview版となっています。 Unity Physics/Havok Physicsについてはこちら こちらによるとUnity Physicsは高速、軽量、ステートレス、カスタマイズ可能と謳われています。 既に色々なところで紹介されていると思いますので、詳しい紹介は割愛し、今回はDOTSベースのUnity Physicsがこれまでのシステムと比較して本当に高速/軽量なのかどうか、試してみたいと思います。 検証内容 動作環境 今回はエディタ実行ではなく、Mac向けのアプリビルドを行ってパフォーマンスを確認します。 私の手元にあるMacBookProを使用します。スペックは以下の通りです。 CPU: Core i5-1038NG7 (Cores: 4, Threads: 8, Clockspeed: 2.0GHz) Memory: LPDDR4X PC4-29800 32GB GPU: Iris Plus Graphics G7 使用バージョン Unity: 2019.4.33f1  * 2020を使用してもよいのですが、2020.3系でUnity Physicsを使用した場合、Default World DebugStreamというおそらくデバッグ用の何かだと思われる仕組みが、パフォーマンスの大半を使用してしまう現象に遭遇したためです。 PhysX: 4.1  * 2019.3以降は4.1が使用されている。。はず Unity Physics: 0.4.1 preview  ※ 2020.3だと0.6が最新だと思います。 何をするのか 負荷を計測するといっても、実際のゲームでは様々なシーンが想定されますし、一つのケースを見ただけではなんとも言えないとは思いつつも。。今回は単純に多くのCubeを使用してみようと思います。 一定の高さから地面に対して定期的に1000個のCubeを自由落下させます。 Cube一つのサイズは1、Massは0.3で、BoxColliderを持つものとします。 プロジェクトのPhysics関係の設定や、Time関連の設定は同Unityでプロジェクトを新規作成したときのデフォルト値とします。 つまり、定期的に1000個ずつCubeが落下してきて、衝突し、蓄積していきます。この時のFPSの変化を計測してみます。 検証 今回はどちらのバージョンもスクリプトバックエンドにはIL2CPPを選択して行います。 1. 従来版のプロジェクトを作る ごくごく単純なので手順はほぼ割愛しますが、検証用のプロジェクトでいじったところを簡単に箇条書きします。 広めの地面を用意する(Colliderもね) CubeのPrefabを作成し、Rigidbodyを設定し、Massを0.3に設定する 適当なスクリプトを作成する。ここではこのCubeのPrefabをある程度の高さのところから、縦10x横10x高10に並べて生成するプログラムにしました。 カメラ位置を全体を見渡せるところに移動させる。 生成タイミングをコントロールしたかったので、Cubeの生成を呼ぶボタンをつけました。 その他、FPSを表示するためのコンポーネントをつけたりなんだりしました。 スクリプトバックエンドをIL2CPPに変更 2. Unity Physics版のプロジェクトを作る 2-1 プロジェクトコピー 先ほど作ったプロジェクトを丸ごとコピー 2-2 パッケージを導入する PackageManagerでUnity PhysicsとHybrid Rendererをインストールします。 ※ Unity PhysicsはGameObjectではなくEntity(ECS)として動作するため、そのままだとレンダリングされません。なので今回はHybrid Rendererを利用しました。 (余談ですが、2020系のPackageManagerでは、これらのパッケージが一覧に表示されないようになっていました。設定からPreview Packageを有効にしても、それでも表示されません。 その際のインストール方法はUnityのヘルプデスクにあります。) 2-3 Unity Physicsに切り替える 今回はConvert To Entityコンポーネントを使用します。 このコンポーネントはGameObjectからEntityに自動的に変換するためのコンポーネントです。プログラムから呼び出すAPIも存在しますが、特に必要ないためこれを使用することにしました。 地面のオブジェクトにConvert To Entityをアタッチする CubeのPrefabにConvert To Entityをアタッチする 以上です。 この状態でゲームを実行すると、地面もCubeもGameObjectからEntityに変換され、ヒエラルキーから消え去ります。 コンバート方法を選べばGameObjectを残したりも出来ます。これらのオブジェクトを操作するためには、DOTS(ECS)を前提に行う必要が出てくるでしょうけれども、今回の検証ではそういったことは一切しないため、単純に変換して終わりです。 3. 従来版 vs Unity Physics版 1000個のときー 多少のスパイクはありますが、この時は双方ともほぼほぼ60FPSを維持できています。 (動きは少し異なっています。このケースではPhysX版のほうが大胆に動いています。) 従来版 Unity Physics版 3000個のときー 従来版では、新たな1000個が出現し、衝突した時に大きくFPSが落ち、最終的には40FPS前後で落ち着いています。 Unity Physics版では、わずかなスパイクはありますが、一貫してほとんど60FPSから落ちておらず安定しています。 従来版 Unity Physics版 6000個のときー 従来版では、流石に厳しくなりました。Cubeの出現時や衝突時には10FPSを下回り、平均的には15FPS程度です。 Unity Physics版では、瞬間的なスパイクを除けば、概ね30~35FPS程度で安定しています。しかしFPSは落ちてきましたね。 従来版 Unity Physics版 10000個のときー 従来版では、2FPSとかになったので割愛します。 Unity Physics版も15FPSまで落ちてきました。 Unity Physics版 まとめ 今回の検証では、ほぼほぼ2倍強程度のパフォーマンスの違いが確認できました。 Unity PhysicsはDOTSベースで動作するため、GameObjectを持ちませんし、純粋な物理演算以外の部分でもパフォーマンスに違いが生じていると思います。 また、負荷やFPSの推移をみている限りでは、従来版は出現時や衝突時のスパイクが大きく、一方でDOTSベースのシステムでは全くスパイクが無いわけではないですが、かなり緩やかな変化に感じました。 現在まだPreview版ですが、正式版では更なるパフォーマンスの改善が見込めるのでしょうか!? ということで、明日も引き続き私の記事です!よろしくお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクトに触れると音が鳴るギミックを作る|UdonSharpを書いてみよう(1)

目次 1.UdonSharpを書くための準備をする 2.UdonSharpを書く 3.ボタンにするゲームオブジェクトを作る 4.ワールドを完成させる 5.動作確認 6.次回 1.UdonSharpを書くための準備をする Unityで新しくプロジェクトを立ち上げる テンプレートは3D、 プロジェクト名はUdonなどわかりやすい名前にしておきましょう 右下の作成でプロジェクトを作成します VRCSDKをインポートする プロジェクトが開いたら、VRCSDKをインポートします VRCSDKは自分に合ったバージョンの物をインポートしましょう SDK3-Worldsをもっていない場合は、VRChat Homeから、ダウンロードできます インポートは、VRCSDKをUnityのAssetsへ、ドラッグアンドドロップします インポートを押します インポートが終わると、フォルダが追加されると思います 最新のUdonSharpをダウンロードする UdonSharpは、MerlinVRさんがGitHubで公開しているものを使います 最新のUdonSharpをダウンロード ダウンロードができると、UdonSharpのUnityPackageを、Unityにインポートします インポートを押します インポートが終わると、フォルダが追加されると思います UdonSharpを作るフォルダを作る Assetsにファイルが散らばるのも嫌なので・・・ 今回はAudioPalyなどの名前で、フォルダを作ります 作りました U#Scriptを作る AudioPlayにU#Scriptを作ります Create/VRChat/Udon/Udon C# Program Asset で、ProgramAssetを作成します 名前は、AudioPlayとかにしておきます これでProgramAssetはできました 次に、ProgramAssetを開いて、Scriptを作成していきます InspectorからCreate Scriptを押します 保存選択画面が出てくると思いますが、名前は最初から入力されているので、そのまま保存します これでU#Scriptが完成しました 2.UdonSharpを書く AudioPlay.csを開きます 変数を宣言する オーディオを扱うために、変数を宣言します privateな、AudioSource型の変数を、定義します 名前は、わかりやすい名前にしておきます 今回私は、audioSourceで宣言しました private AudioSource audioSource; これで変数はできました スタート時にオーディオソースを取得する オーディオソースを取得するため、最初からあるStartメソッドに、コードを書いていきます Scriptを入れたゲームオブジェクトに入っているオーディオソースを取得したいので、 GetComponentを使って、AudioSourceを取得します 次に、取得したオーディオソースは、audioSource変数に代入します void Start() { audioSource = GetComponent<AudioSource>(); } これでオーディオソースの取得ができました ゲームオブジェクトをクリックできるようにする ゲームオブジェクトをクリックしたときに、イベントを発生させるメソッドは二つあり、 MonoBehaviourに入っているOnMouseDownと、 UdonSharpBehaviourに入っているInteractがあります また、InteractはVRChat用に作られています(詳しいことはしらない、勉強不足) 今回はInteractを使います publicな、戻り値無しの上書き可能メソッドとして、定義します public override void Interact() { } これで、クリック判定ができるようになりました クリックされた時の処理を書く クリックされた時の処理は、上記で取得したオーディオを再生したいので、 AudioSource .Playを使って再生します (Interactメソッドの中に書きます) audioSource.Play(); これで、クリックしたときに再生されるようになりました スクリプトを保存して、Unityに戻りましょう 3.ボタンにするゲームオブジェクトを作る ゲームオブジェクトにスクリプトを入れる まずは、ゲームオブジェクトを作ります 名前はAudioPlayButtonにしておきました (コライダー判定が邪魔な人は、Box Collider の IsTriggerをオンにしましょう) この中に、スクリプトを入れていきます ゲームオブジェクトに、AudioPlayスクリプトを、ドラッグアンドドロップします ドラッグアンドドロップをすると、Convert to UdonBehaviourを押します これで、Scriptが使えるようになりました Useするときの文字を変えたい場合は、Interaction Textを書き換えることで、変更できます 再生するオーディオソースを入れる オーディオソースは、効果音ラボさんから、いただきました 今回使用した音源は、ボタン・システム音の、[決定、ボタン押下3]を利用しました ダウンロードがおわったら、オーディオを、ドラッグアンドドロップでインポートします オーディオが入ったら、このオーディオを、ゲームオブジェクトにドラッグアンドドロップします これで、オーディオソースがはいったので、設定していきます Play on Awakeを外します Priorityを0にします Volumeを0.5にします これで設定ができました 4.ワールドを完成させる このままでは、地面も何もないので実行できません 地面とスポーンするためのVRCWorldを追加していきます まずは、地面を作ります Terrainやキューブなどで、地面を作ります 地面が完成しました 次に、VRCWorldを追加して、リスポーン位置を設定します Assets/VRChat Examples/Prefabs の中にあります これを、ドラッグアンドドロップで、Hierarchyに追加します 追加できました これで、ワールドとして使えるようになりました 5.動作確認 VRChat SDKから、Build & Testを実行します テスト動画 動いていれば成功です 動いてない場合は、もう一度、スクリプトを確認してみてください お疲れさまでした 6.次回 また何か作ります UdonSharpを書いてみよう(2) coming soon
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HoloLens2 × ZIGSIM やーる(Quaternion)

はじめに HoloLensアドベントカレンダー2021の1日目の記事です。 今回はZIGSIMを用いて、iPhoneのQuaternionをHoloLens2にUDP送信し、HoloLens2上のCapsuleをiPhoneの姿勢に合わせて動かしてみましょう。 開発環境 Windows 10 PC Unity 2020.3.0f1 MRTK 2.7.2 HoloLens2 iPhone 12 Pro ZIG SIM PRO 実装 1.MixedRealityFeatureTool-1.0.2104.4-Betaを用いてMRTKをインストールします MRTK導入部分の詳細はこちらのHoloLens2 はじめーる(Unity 2020.3、MRTK2.7.2)をご参照ください。 2.ZigSimManager.csを作成し、objにCapsuleをアタッチします ZigSimManager.cs using System; using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using System.Net; using System.Net.Sockets; #else using System; using System.IO; using Windows.Networking.Sockets; #endif public class ZigSimManager : MonoBehaviour { int port = 3333; Osc.Parser osc = new Osc.Parser(); public GameObject obj; void OnMessage(Osc.Message msg) { // Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]); if (String.Equals(msg.path,"/ZIGSIM/{Device UUID}/quaternion")){ obj.transform.rotation = new Quaternion(-(float)msg.data[0], -(float)msg.data[2], -(float)msg.data[1], (float)msg.data[3]) * Quaternion.Euler(90.0f, 0.0f, 0.0f); } } #if UNITY_EDITOR UdpClient udpClient; IPEndPoint endPoint; void Start() { endPoint = new IPEndPoint(IPAddress.Any, port); udpClient = new UdpClient(endPoint); } void Update() { while (udpClient.Available > 0) { var data = udpClient.Receive(ref endPoint); osc.FeedData(data); } while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } #else DatagramSocket socket; object lockObject = new object(); const int MAX_BUFFER_SIZE = 1024; byte[] buffer = new byte[MAX_BUFFER_SIZE]; async void Start() { try { socket = new DatagramSocket(); socket.MessageReceived += OnMessage; await socket.BindServiceNameAsync(port.ToString()); } catch (System.Exception e) { Debug.LogError(e.ToString()); } } void Update() { lock (lockObject) { while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } } async void OnMessage(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { using (var stream = args.GetDataStream().AsStreamForRead()) { await stream.ReadAsync(buffer, 0, MAX_BUFFER_SIZE); lock (lockObject) { osc.FeedData(buffer); } } } #endif } Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]);のところで /{Device UUID}/deviceinfo => iPhone13,3 /ZIGSIM/{Device UUID}/quaternion => 0.3267779 こんな感じのOSCメッセージが送られてきます。{Device UUID}はZIGSIMの設定からコピペしてください。OSCのメッセージの処理については、keijiroさんのunity-oscを使ってます。 msg.pathがquaternionのときに、msg.data[0]~[3]がそれぞれx,y,z,wになります。 object型になっているのでfloat型にキャストして、Unityの座標系に合わせてCapsuleのrotationに代入します。 3.HoloLens2にデプロイしましょう。PlayerSettings->CapabilitiesのInternetClientServerとPrivateNetworkClientServerにチェック入れるのを忘れずに。 反映されてないこともあるので、Package.appxmanifestもチェックしましょう。 4.アプリを起動したら、ZIGSIMも起動します。ZIGSIMの設定でHoloLens2のIPアドレスを指定してStartしてください。CapsuleがiPhoneに合わせて動いたら成功です。 Sensor Setting Start デモ #HoloLens2 x #ZIGSIM quaternion test pic.twitter.com/FsXFjlfiOr— がちもとさん@メタバース熊本 (@sotongshi) December 1, 2021 参考文献 HoloLens で UDP 通信を行う方法について調べてみた UnityでiOSのジャイロの使い方をちゃんと説明する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HoloLens2 x ZIGSIM やーる

はじめに HoloLensアドベントカレンダー2021の1日目の記事です。 今回はZIGSIMを用いて、iPhoneのQuaternionをHoloLens2にUDP送信し、HoloLens2上のCapsuleをiPhoneの姿勢に合わせて動かしてみましょう。 開発環境 Windows 10 PC Unity 2020.3.0f1 MRTK 2.7.2 HoloLens2 iPhone 12 Pro ZIG SIM PRO 実装 1.MixedRealityFeatureTool-1.0.2104.4-Betaを用いてMRTKをインストールします 2.ZigSimManager.csを作成し、objにCapsuleをアタッチします ZigSimManager.cs using System; using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using System.Net; using System.Net.Sockets; #else using System; using System.IO; using Windows.Networking.Sockets; #endif public class ZigSimManager : MonoBehaviour { int port = 3333; Osc.Parser osc = new Osc.Parser(); public GameObject obj; void OnMessage(Osc.Message msg) { // Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]); if (String.Equals(msg.path,"/ZIGSIM/{Device UUID}/quaternion")){ obj.transform.rotation = new Quaternion(-(float)msg.data[0], -(float)msg.data[2], -(float)msg.data[1], (float)msg.data[3]) * Quaternion.Euler(90.0f, 0.0f, 0.0f); } } #if UNITY_EDITOR UdpClient udpClient; IPEndPoint endPoint; void Start() { endPoint = new IPEndPoint(IPAddress.Any, port); udpClient = new UdpClient(endPoint); } void Update() { while (udpClient.Available > 0) { var data = udpClient.Receive(ref endPoint); osc.FeedData(data); } while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } #else DatagramSocket socket; object lockObject = new object(); const int MAX_BUFFER_SIZE = 1024; byte[] buffer = new byte[MAX_BUFFER_SIZE]; async void Start() { try { socket = new DatagramSocket(); socket.MessageReceived += OnMessage; await socket.BindServiceNameAsync(port.ToString()); } catch (System.Exception e) { Debug.LogError(e.ToString()); } } void Update() { lock (lockObject) { while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } } async void OnMessage(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { using (var stream = args.GetDataStream().AsStreamForRead()) { await stream.ReadAsync(buffer, 0, MAX_BUFFER_SIZE); lock (lockObject) { osc.FeedData(buffer); } } } #endif } Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]);のところで /{Device UUID}/deviceinfo => iPhone13,3 /ZIGSIM/{Device UUID}/quaternion => 0.3267779 こんな感じのメッセージが送られてきます。{Device UUID}はZIGSIMの設定からコピペしてください。 msg.pathがquaternionのときに、msg.data[0]~[3]がそれぞれx,y,z,wになります。 object型になっているのでfloat型にキャストして、Unityの座標系に合わせてCapsuleのrotationに代入します。 3.HoloLens2にデプロイしましょう。PlayerSettings->CapabilitiesのInternetClientServerとPrivateNetworkClientServerにチェック入れるのを忘れずに。 反映されてないこともあるので、Package.appxmanifestもチェックしましょう。 4.アプリを起動したら、ZIGSIMも起動します。ZIGSIMの設定でHoloLens2のIPアドレスを指定してStartしてください。CapsuleがiPhoneに合わせて動いたら成功です。 Sensor Setting Start デモ #HoloLens2 x #ZIGSIM quaternion test pic.twitter.com/FsXFjlfiOr— がちもとさん@メタバース熊本 (@sotongshi) December 1, 2021 参考文献 HoloLens で UDP 通信を行う方法について調べてみた UnityでiOSのジャイロの使い方をちゃんと説明する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HoloLens2 x ZIGSIM やーる(Quaternion)

はじめに HoloLensアドベントカレンダー2021の1日目の記事です。 今回はZIGSIMを用いて、iPhoneのQuaternionをHoloLens2にUDP送信し、HoloLens2上のCapsuleをiPhoneの姿勢に合わせて動かしてみましょう。 開発環境 Windows 10 PC Unity 2020.3.0f1 MRTK 2.7.2 HoloLens2 iPhone 12 Pro ZIG SIM PRO 実装 1.MixedRealityFeatureTool-1.0.2104.4-Betaを用いてMRTKをインストールします MRTK導入部分の詳細はこちらのHoloLens2 はじめーる(Unity 2020.3、MRTK2.7.2)をご参照ください。 2.ZigSimManager.csを作成し、objにCapsuleをアタッチします ZigSimManager.cs using System; using System.Collections; using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using System.Net; using System.Net.Sockets; #else using System; using System.IO; using Windows.Networking.Sockets; #endif public class ZigSimManager : MonoBehaviour { int port = 3333; Osc.Parser osc = new Osc.Parser(); public GameObject obj; void OnMessage(Osc.Message msg) { // Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]); if (String.Equals(msg.path,"/ZIGSIM/{Device UUID}/quaternion")){ obj.transform.rotation = new Quaternion(-(float)msg.data[0], -(float)msg.data[2], -(float)msg.data[1], (float)msg.data[3]) * Quaternion.Euler(90.0f, 0.0f, 0.0f); } } #if UNITY_EDITOR UdpClient udpClient; IPEndPoint endPoint; void Start() { endPoint = new IPEndPoint(IPAddress.Any, port); udpClient = new UdpClient(endPoint); } void Update() { while (udpClient.Available > 0) { var data = udpClient.Receive(ref endPoint); osc.FeedData(data); } while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } #else DatagramSocket socket; object lockObject = new object(); const int MAX_BUFFER_SIZE = 1024; byte[] buffer = new byte[MAX_BUFFER_SIZE]; async void Start() { try { socket = new DatagramSocket(); socket.MessageReceived += OnMessage; await socket.BindServiceNameAsync(port.ToString()); } catch (System.Exception e) { Debug.LogError(e.ToString()); } } void Update() { lock (lockObject) { while (osc.MessageCount > 0) { var msg = osc.PopMessage(); OnMessage(msg); } } } async void OnMessage(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) { using (var stream = args.GetDataStream().AsStreamForRead()) { await stream.ReadAsync(buffer, 0, MAX_BUFFER_SIZE); lock (lockObject) { osc.FeedData(buffer); } } } #endif } Debug.LogFormat("{0} => {1}", msg.path, msg.data[0]);のところで /{Device UUID}/deviceinfo => iPhone13,3 /ZIGSIM/{Device UUID}/quaternion => 0.3267779 こんな感じのOSCメッセージが送られてきます。{Device UUID}はZIGSIMの設定からコピペしてください。OSCのメッセージの処理については、keijiroさんのunity-oscを使ってます。 msg.pathがquaternionのときに、msg.data[0]~[3]がそれぞれx,y,z,wになります。 object型になっているのでfloat型にキャストして、Unityの座標系に合わせてCapsuleのrotationに代入します。 3.HoloLens2にデプロイしましょう。PlayerSettings->CapabilitiesのInternetClientServerとPrivateNetworkClientServerにチェック入れるのを忘れずに。 反映されてないこともあるので、Package.appxmanifestもチェックしましょう。 4.アプリを起動したら、ZIGSIMも起動します。ZIGSIMの設定でHoloLens2のIPアドレスを指定してStartしてください。CapsuleがiPhoneに合わせて動いたら成功です。 Sensor Setting Start デモ #HoloLens2 x #ZIGSIM quaternion test pic.twitter.com/FsXFjlfiOr— がちもとさん@メタバース熊本 (@sotongshi) December 1, 2021 参考文献 HoloLens で UDP 通信を行う方法について調べてみた UnityでiOSのジャイロの使い方をちゃんと説明する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

落合博満がtoioを使うなら。

落合博満がtoioを使うなら。 この記事は、2021年の toio のアドベントカレンダー の 2日目の記事です。 今回は落合博満がtoioを使うなら。を想像して書くとします。 テンションは toio™サッカー誕生のアレコレの李忠成のようなテンションで書いております。 落合博満とは wiki 落合氏は私が小学生高学年の2004年くらいから高校生卒業の2011年まで中日ドラゴンズで監督として君臨した名将であり、年末年始に和歌山の落合博満記念館に足を運ぶとなんとご本人が接客され、色んな話しを赤裸々にしてくれるしコーヒも入れてくれる。(2021年12月は改装中の為閉館中) 色んなキャラクターを持つオレ流である。 その時の写真。(まさかQiitaに落合さんをアップロードしてしまうとは) ※一応ご本人には撮影時SNS等にアップする事の許可は頂いております。 前置き 最近宮城の登米市という所を本拠地にしており、toioのようなガジェットが身の回りで出会うケースがもっぱら減った。今回はtoioがこんな風に一般的にしれっと役に立つかも知れないアイデアを書いていきます。 落合氏の無表情が好きだ 落合氏といえば、無表情。例えばチームの選手がホームランを打っても、エラーをしても顔色を変えないのだ。実際はイニング交代時に顔を変えていたそうだ。そして初期の2004年はアレックス・オチョアのサヨナラホームランで顔を変えていたりした。実際はオールスターで采配した際の落合氏がナチュラルなようだ。そんなナチュラルを隠して無表情でいれることがすごい。 落合氏は腕を組んで指でサインを出していた。 とある講演会の質問時間でコアなファンが手をあげた。質問は「落合さんは無表情なのにどうやってサインを出していたのですか?何かそれらしい所をずっと試合中双眼鏡でみていたが何も本当に動いていなかったのですが」と。さすが講演会にくるだけあって変態である。一般の人からすれば、それが生きていく上で全く役に立たない事かもしれない。しかしこの一つの質問がこの記事の生まれるきっかけになるのである。落合氏は苦笑いしながらも「おれは腕を組んでいただろ? 腕を組んで隠れた指で1はバント、2はエンドライン。そんな感じでだしていたよ。3と4が見にくいって間違えてスクイズになった事もあったけどな」と。なるほどそれはわからない。そしてサインを出すコーチからしたらそれは見にくい。そんな形で常勝ドラゴンズは成り立っていたというのだ。 そこに1つのtoioコアキューブがあるだろ?  落合氏がもしプログラミングやガジェットに興味があって、何か作れたとする。そしたら間違いなくtoioを選ぶだろう。toioには姿勢角検出を始めとした様々なイベントがある。何でも出来るtoioをシンプルに使うまさにオレ流である。そしてなにより腕を組んで手の中にtoioコアキューブは収まる。収まってしまう。 Unityだよ。Unity。Unity! 「toioはただのおもちゃじゃない。お前らがそう思うのは無理はないけどオレはそんな単純に見ていないから。このコアキューブをな。」 と言いながら toio SDK for Unityを指差した。toioにはSDKがある。このSDKはシミュレータもあり、なんとMacのUnity EditorでPlay時にキューブと通信する等開発時にもやさしい。 やるといいこと、やっちゃだめな事は仕様にすべて書いてあるだろ? toio SDK for Unityはサンプルが非常に充実している。toio SDK for Unity ドキュメントではセットアップの流れややってはダメな事も書いてある、先程MacのUnity EditorでPlay時にキューブと通信できると書いたが、セットアップ時にしっかりバージョンに合わせてライブラリを読み込む必要がある。UniTask のインストールやMacBLE利用方法そしてスクリプトの依存関係はふとした時に忘れたり、手順を飛ばしてしまう恐れがある。何かうまく行かない時は原点に戻る、これもオレ流である。 ネタが昨日と被っている?そういう日もあるよ。長いシーズンだからな。 センサーのイベントを検知のサンプルを見ると、姿勢のイベントは // 姿勢イベント // https://toio.github.io/toio-spec/docs/ble_sensor#姿勢検出 cube.poseCallback.AddListener("EventScene", OnPose); こんな形で書いてある。いかにもシンプルだ。 さらに。制御のCASE文についてもサンプルがある。 public void OnPose(Cube c) { switch (cube.pose) { case Cube.PoseType.Up: this.textPose.text = "Pose: Up"; break; case Cube.PoseType.Down: this.textPose.text = "Pose: Down"; break; case Cube.PoseType.Front: this.textPose.text = "Pose: Front"; break; case Cube.PoseType.Back: this.textPose.text = "Pose: Back"; break; case Cube.PoseType.Right: this.textPose.text = "Pose: Right"; break; case Cube.PoseType.Left: this.textPose.text = "Pose: Left"; break; default: this.textPose.text = "Pose: Up"; break; } } サインは4種類 例外もたまにあるけど4種類だよ。 落合氏は講演会で意味深にこう発言した。例外があるにしても4種類。 こんな感じで定義しているのではないか。 Cube.PoseType.Up サインなし Cube.PoseType.Down バント Cube.PoseType.Front バント(バスター) Cube.PoseType.Back エンドラン Cube.PoseType.Right 盗塁 Cube.PoseType.Left 待て ほら、出来るじゃないか。 こんな感じに仕組めば4種類のサインなんて簡単だ。手に握って上手く転がせばサインは無表情で出すことができる。草野球でも使える技だ、一番最初にサインを出す人間が表情にバントだのエンドランだの出ていたら草野球でもバツが悪い。 使い方 こんな形で軽く腕を絡めるスタイルや、脇に手を隠すスタイルをベースに悟られないようにサインを出そう。 ※これは筆者の写真 もっと落合氏になるには 大人の都合で画像は貼れない…このブログでも見てくれ… https://plaza.rakuten.co.jp/snowrun29/diary/201110180000/ キシリクリスタルを脇に置いておきましょう。これで落合氏がtoioを使うなら。の完全再現が完了です。 さいごに という事でまずは登米市の草野球でtoioを使ってサインを出す儀をやりながら薄く広くtoioの認知度を上げていきたいと思います。もしかしたら新庄氏がtoioを転がしてサインを決める日が来るやも知れません。ドラベース。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityのAndroid SDKにAPIレベル30のSDKツールを導入する

Google Play ConsoleでAndroidアプリをリリースしようとしたらエラーになった ターゲットのAPIレベルが29のアプリをリリースしようとしたところ、エラーになりました。 どうやら、ターゲットレベルが30以上じゃないとダメみたいです。 どうやって30をインストールするんだっけ? ということで、Android SDKに新しいAPIレベルのツールを導入する手順を、備忘録として残します。 今回は Unity 2019.3.6f1 に API level 30 を導入します。 Unityが参照している Android SDK のパスを確認する Unity の Preferences > External Tools > Android SDK Tools installed with Unity 欄に Android SDK のパスが記載されています。 今回の私の環境では、 C:\Program Files\Unity\Hub\Editor\2019.3.6f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK でした。 Android SDK に API level 30 を導入する 管理者権限でコマンドプロンプトを開きます。 カレントディレクトリを先程の SDK フォルダにします。 cd "C:\Program Files\Unity\Hub\Editor\2019.3.6f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK" ※コマンドは一例です。SDKフォルダーへのパスはご自身の環境に合わせてください。 以下のコマンドで API level 30 をインストールできます! tools\bin\sdkmanager "platform-tools" "platforms;android-30" 以下のように表示されたら y を入力しましょう! Accept? (y/N): y ゲージが 100% になったら成功です! さいごに 本記事作成にあたり、以下を参考にさせていただきました。 https://developer.android.com/studio/command-line/sdkmanager?hl=ja
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Visual Studioのインテリセンス活用

インテリセンスとは、自動入力補完のことです。 1文字でもコードを書くと、自分の宣言した変数や予約語の候補がポップアップで出てくるあれです。 ちなみにこのポップアップを消してしまったときや任意のタイミングで出したいときは、ctrl + space (command + space)で再度表示できます。 (Macはデフォルトでは違うキーかも) 名前空間に適用 この機能は名前空間(using~のやつ)にも適用されます。 unityエディタ上で作りたてのスクリプトでは、例えばText型を宣言すると名前空間がないと怒られます。 ここで、エラーが出ている波線にカーソルを合わせると、ポップアップが出るので、考えられる修正内容を表示するをクリック usingの候補が出るので、今回はUnityEngine.UIを選択 追加してくれました 以前いくつかの場所で聞いたら、手動で書いてる人も割といたようなので、名前空間もできますよと。。。 構文を自動で for文やforeach文等の構文の雛型も自動で作ってくれます 途中まで書いて候補が出たら、ポップアップにあるようにTabキーを2回押すと、 一瞬でやってくれました 出番の少ない構文は書き方忘れやすいので便利ですね
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity] UIのワールド矩形領域を得る

World座標系のオブジェクトがUI領域にあるかどうかを知りたい時などに、 RectTransform.GetWorldCorners(Vector3[4]) を使うと、UI(RectTransform)の4頂点を一気にとれる。 もちろん回転していても大丈夫。 void debugDrawMargin(RectTransform _marginRT) { Vector3[] corners = new Vector3[4]; _marginRT.GetWorldCorners(corners); Debug.DrawLine(corners[0], corners[1], Color.yellow); Debug.DrawLine(corners[1], corners[2], Color.yellow); Debug.DrawLine(corners[2], corners[3], Color.yellow); Debug.DrawLine(corners[3], corners[0], Color.yellow); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

同人プロジェクトマネジメント入門:仕様書作成編その2

同人プロジェクトマネジメント入門の目次はこちら はじめに 仕様書を書くツールが決まったら、次はどこまでを仕様とするかを決める必要があります。今回は、同人プロジェクトに適した仕様決定の方法について書いていこうと思います。 仕様決定のタイミング 長期的な仕様の意味は薄い なぜ巨大な仕様は壊れやすいか まず、最も重要な点として、同人プロジェクトにおいては、最初に作った仕様書は、ほとんど最後には忘れられるということを強調しておきます。その原因としては以下のものが挙げられます。 はじめにはメンバーの力量が分かっておらず、実現性がないものが仕様に含まれる はじめはメンバーにモチベーションがあるので、実際にはできないような量の仕様が書き込まれる 仕様書を書くのは楽しいので、ついつい高すぎる理想を書いてしまう(往々にして、あとで消せばいいや!という言い訳を伴います) 実装途中に仕様がどんどん変わっていく 「いきなり大作を目指した結果、途中でモチベーションが尽きて死ぬ」というのは典型的なパターンだと思います。 長期仕様の作り方 ポイントをいくつか並べておきます。 未来のことはあまり決めない:将来の情報を後から織り込んでいくための「余白」が大事です。「○○機能が欲しい!」以上の情報を詰めてもあんまりいいことないです。 すぐに外せる仕様に徹する:「作れなくてもいい」「コアのシステムとインターフェースが分離され着脱性が高い」「本体システムとは完全に別に作れる」などの特徴がある場合には、仕様を詰めてもいいでしょう。なぜなら、実質的に別プロジェクトなので、この仕様での失敗は、他の部分に波及しないからです。 短期的なゴールを積み重ねよう 基本的にモチベーションは、クリエイティブで夢が広がる仕様の作成時にチャージされ、実装時に消耗します。 したがって、仕様決定作業を何度か繰り返した方が、モチベーションが最後まで持続しやすいです。 仕様は最小限にする 仕様の決定自体も慣れが必要な作業です。マネージャーにとっても、一度に多くの仕様を決めようとしても難易度が高いです。 また、述べた通り、仕様の作成時には、メンバーが暴走しやすいので、スモールスタートが重要です。 さらに、プロジェクトが進むことでわかる情報もあります。例えば、「メンバーが失踪しそう」や「金で解決できそう」などです。これらの情報を織り込んで新しく仕様を作っていく方が精度が上がります。 雪だるま式に増やす 仕様は削るものではありません。仕様は増やすものです。 「あらかじめ削ってもいい仕様を決める」というやり方もありますが、あまり上手くいきません。具体例を挙げます。 当初の仕様:A→B→C(B,Cは削ってもいいよ~) 理想:A→B→Cの途中 で終了 現実:Aが実装出来ず、A'になり、B'C'の仕様策定作業発生。しかし、B'も思った通りに実装出来ずB''となり、C''の仕様策定作業発生。 上のように、思った通りに実装出来ないことの方が多いので、先の仕様を考えても無駄になることが多いのです。上の例では、B,C,B',C'の仕様の作成作業は完全に無駄になってしまいました。 それよりもAを決める。A'になる。B'を決める。B''になる、C''を決める…といった仕様決めの方法の方が無駄が減ります。 骨と身を分けて、とにかく完成させる 「骨」となる仕様は、例えば「戦闘システムの存在」や「RPGのメインクエスト」などが当たります。骨がないとゲームとして一応動くものが出来ない、という状況になります。 「身」となる仕様は、例えば「戦闘における必殺技」や「RPGのサブクエスト」などが当たります。身は、あればいいけどなくてもいい仕様です。 初期の仕様では出来るだけ「骨だけ」または「骨+身が1個ずつ」になるようにしましょう。 その理由は、「最低限遊べる」という状況がモチベーションアップに非常に有効だからです。 辛い作業の中から出てきたゲームは、どれだけ仕様が小さくても、「動く」というだけで感動出来ます。 身を1個入れる理由は、後に述べる「マネージャー的に楽なタスク」を増やすのに有効だからです。 プログラマならわかると思いますが、サブクエストが1個あれば、10個作るのはそんなに難しくないですよね。 逆に0から1を作ろうとすると、結構手間がかかる改修になってしまうので、ほぼ確実に入るであろう身の仕様に限っては1つだけ入れておくことをお勧めします。 人間関係面 一度作った仕様を消すと、それに積極的に関わっていたメンバーにとっては、自分の仕事を消されたかのように思い、モチベーションが一気に減ります。将来自分の入れたい仕様を入れるかもしれないという期待で、手元の仕事をするモチベーションが生まれます。 詳しく書かない 仕様書の詳細度についても、マネージャーの段階では詳しく書かないのが適切です。 仕様自体が雑なものなので、プログラムを書こうとする段階で仕様に疑問が出るのは当然です。 また、書いてみて初めて気づくことは大量にありますから、それを全部予想するのは難しいです。 ラフに仕様書を書く 仕様書に足りない部分があれば、仕様書に疑問を書き込む その部分に担当者が書き込む。重大なものがあれば全体グループで問題提起する という方式をとりましょう。比較的効率が良いと思われます。 出来るだけ仕様を簡潔にするための方法 金・素材の力を活用する UnityならAsset Storeがありますし、Mixamoでリグとかモーションとかを持ってきたり、テクスチャをtextures.comからとってきたりして、解決するようなタスクなら、解決してしまいましょう。 個人プロジェクトだと支出が嫌だというマネージャー・チームメンバーもいるかもしれませんが、時給1000円で10時間働いて得られる給料で買える素材と、自分が10時間で作れる素材を比較して考えるとよいと思います。未来の安心をお金で買うと考えれば安いと思います。限りあるモチベーションは、自分にしかできないタスクに使うと、クオリティ・独創性両方が上がっていきます。 タスクに関して適正な感覚を持った人間の意見を取り入れる これは仕方ないことなのですが、時には開発メンバーの中に「ここはリアルさを追求して仕様を複雑にしようぜ」とか「ゲームのアート面を追求しようぜ」とか言って突っ走ってしまう人が出てきます。そういうメンバーは理想に燃えているので「序盤は猛烈に仕事をしてくれて、途中から燃え尽きる」といったパターンに陥りがちです。仕様決めは楽しいので仕方ないです。 しかしマネージャーは、心を鬼にして適正なタスクを決めなければなりません。 おすすめの作戦は、まず複数回会議を開くことを伝えておき、最初の会議でキャラクターを判別して、穏健そうな人を集めて内々で協定を結んでおくことです。複数人で仕様に燃える人を説得すれば、そのモチベーションをすでに決まった仕様の実装に費やしてくれると思います。 定期的に仕様作成会議を開く 仕様を段階的に増やして決めるという方式をとった以上、仕様作成会議を定期的に開く必要があります。 スケジュール決定の方法ですが、前回決めた仕様のうちおおよそが決まったら次の仕様を決定するという方式がおすすめです。 時間で区切らない理由としては、たとえ時間で決めたとしても、基本計画は遅れるものだからです。 何回か会議をしていくうちに、仕様決定の経験値がたまっていくと思います。 おわりに アジャイル開発に近いような内容になりました。日々の変化に適応するための方法を考えるとアジャイル開発に収斂していくのかもしれませんね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UniTaskで簡単なProcessをサクッと実行して結果を文字列で得る

概要 macOS BigSur 11.4 Unity 2021.1.28f1 UniTask 2.2.4 Unityでもコマンド実行した結果を使いたいな〜ってときに使えるやつです 使用クラス ProcessStartInfo Process 具体例: Gitのハッシュ値を取得してTextに表示する 特に解説することはなかったので早速コードをドン CommitHashLabel.cs public class CommitHashLabel : MonoBehaviour { [SerializeField] private Text text; private void Start() => InitCommitHashAsync().Forget(); private async UniTaskVoid InitCommitHashAsync() { try { var hash = await GetCommitHashAsync(); text.text = hash; } catch (Exception e) { Console.WriteLine(e); } } private async UniTask<string> GetCommitHashAsync() { var processStartInfo = new ProcessStartInfo { FileName = "git", Arguments = "rev-parse --short HEAD", CreateNoWindow = false, StandardOutputEncoding = Encoding.UTF8, RedirectStandardOutput = true, UseShellExecute = false }; var process = Process.Start(processStartInfo); if (process == null) { throw new ArgumentException("Process cannot start."); } await UniTask.SwitchToThreadPool(); process.WaitForExit(); await UniTask.SwitchToMainThread(); return (await process.StandardOutput.ReadToEndAsync().AsUniTask()).Trim(); } } これで実行時に勝手にコミットハッシュを表示してくれます Startに書いていますがAwakeでやっても大丈夫だと思います Editor上でしか動作しないので使用の際には注意! 補足 ProcessStartInfo ProcessStartInfo.WorkingDirectory 実行場所の指定 指定がないとEnvironment.CurrentDirectoryが指定されます Unityのプロジェクトをgitで管理しているのであれば指定がなくても問題なく使用できると思います Process Process.WaitForExit これをメインスレッドで実行してしまうと処理が止まってしまうのでスレッドプールに移動してから呼ぶことで非同期っぽくしています Unityで.NET6が使えるようになったら WaitForExitAsyncとかいうゴキゲンなメソッドも使えるようになるみたいです 汎用的に使えるようにする ProcessStartInfoの作成とProcessの実行を行うクラスを作成します UniTaskProcessExecutor.cs public class UniTaskProcessExecutor { private readonly ProcessStartInfo processStartInfo; public UniTaskProcessExecutor(string filename, string arguments) { processStartInfo = new ProcessStartInfo { FileName = filename, Arguments = arguments, CreateNoWindow = false, StandardOutputEncoding = Encoding.UTF8, RedirectStandardOutput = true, UseShellExecute = false }; } public async UniTask<string> ExecuteAsync() { var process = Process.Start(processStartInfo); if (process == null) { throw new ArgumentException("Process cannot start."); } await UniTask.SwitchToThreadPool(); process.WaitForExit(); await UniTask.SwitchToMainThread(); return (await process.StandardOutput.ReadToEndAsync().AsUniTask()).Trim(); } } CommitHashLabel.cs public class CommitHashLabel : MonoBehaviour { [SerializeField] private Text text; private void Start() => InitCommitHashAsync().Forget(); private async UniTaskVoid InitCommitHashAsync() { try { var process = new UniTaskProcessExecutor("git", "rev-parse --short HEAD"); var hash = await process.ExecuteAsync(); text.text = hash; } catch (Exception e) { Console.WriteLine(e); } } } クラス名にUniTaskをつけてしまうと検索性が著しく落ちるので別の名前をつけたほうがいいです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCodeのインテリセンスが機能しなかったときに確認すること

PONOS Advent Calendar 2021 4日目の記事です。 昨日は@e73ryoさんの「Debug.Log()の全文をファイル出力し、で省略された内容をすぐに確認できるようにする」でした。 はじめに VisualStudioCode(以下VSCode)を使い始めて3年になりますが、いまだにインテリセンス(コード補完やコード整形など)が機能しなくなることが少なくありません。 検索すると同様の記事がいくつも見受けられますが、改めて自分なりにまとめていたものを共有させていただきます。どなたかのお役に立てたら幸いです。 チェックシート Unity側 PreferencesのExternalToolsに「VisualStudioCode」が指定されているか PackageManagerのVisualStudioCodeEditorのバージョンが適したものになっているか AssetsのOpen C# Projectから開いたことがあるか omnishap.jsonがUnityプロジェクト内に置かれているか VSCode側 コマンドパレットから「OmniSharp:Select Project」を実行してみたか コマンドパレットから「OmniSharp: Restart OmniSharp」を実行してみたか 設定の UseGlobalMono が always になっているか その他 Monoの最新版がインストールされているか アプリケーションやPC本体を再起動してみたか 詳細 Unityエディタ側 PreferencesのExternalToolsのExternalScriptEditorに「VisualStudioCode」を指定する Unityのバージョンによっては「Code」という選択肢の場合もあります。 PackageManagerのVisualStudioCodeEditorのバージョンを最新もしくは適したものにする [ 20xx.x verified ]と記されたバージョンが適しています。 Assetsの「Open C# Project」からVSCodeを開く 後述のVSCode側の設定が一通り終わった後、 VScodeのアプリケーションを終了の上でもう一度「Open C# Project」をしてみてください。 omnishap.jsonをUnityプロジェクト内に置く omnishap.jsonがAssetsと同じ階層に置かれていることを確認してください。 ※omishap.jsonに関しては割愛します。 VSCode側 コマンドパレットから「OmniSharp:Select Project」を実行する 通常はUnityエディタで「Open C# Project」したときに自動選択されるはずですが、何らかの原因により失敗している場合にお試しください。 正常時はVSCode左下に「{プロジェクト名}.sln」が表示されています。 コマンドパレットから「OmniSharp: Restart OmniSharp」を実行する おかしいなと思ったらとりあえずリスタートさせることにしています。 設定のUse Global MonoをAutoからalwaysに変更する デフォルトはautoになっていますがalwaysに変更してください。以前はautoで問題なかったと思うのですが、ここ最近alwaysにしないとエラーが解消しないという報告を受けるようになりました。 その他 Monoの最新版をインストールする アプリケーションやPC本体を再起動する 言うまでもないことですが、今回の件に限らず再起動しないと反映されないことなどが多々あるので。 Macの場合はウィンドウを閉じるだけは終了しません。Dockのアイコンを右クリックしてそれぞれのアプリケーションを終了させてください。 おまけ VSCodeのおすすめ設定 自動更新をOFFに VScode本体、インポート済みの拡張機能、Unityエディタのそれぞれのバージョンがあわないと噛み合わなくなることがあります。今現在安定動作しているのであれば自動更新をOFFにしておくほうが無難です。 設定の検索窓にupdateと打ち込んでから、いくつかの自動更新をOFFにしておきましょう。 コード整形とセーブのタイミング この辺は好みですが、自分の場合はVScodeからフォーカスを外した時にコード整形&セーブしています。 UserSettings>Text Editor>FormatOnSaveをONに。(ファイル保存時に自動整形する) UserSettings>Files>AutoSaveをonFocusChangeに。(VSCからフォーカスが外れた際に自動セーブする) 動作確認環境 Unity2019.4.29f1 / PackageManager:VisualStudioCodeEditor 1.2.4 VSCode 1.58.0 / 拡張機能 C# 1.23.0 / JapaneseLanguagePack 1.48.1 最後に 明日は@blockさんです!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】PostProcess トラブルシューティング

通常のカメラにはPostProcessが反映されるが、RenderTextureには反映されない。 RenderTextureのColorFormatが16bit未満の場合、PostProcessが反映されない。 R16G16B16A16_SFLOAT等に設定すること。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity Android 画面設定 ナビゲーションバーの表示

0.0 はじめに Unityで作ったアプリのデフォルト設定はナビゲーションバーが表示されません。ナビゲーションバーとは下に出てくる丸や三角や四角のボタンです。この設定では下からスワイプすることで表示はできますが、しばらくすると消えてしまいます。この記事では最初からナビゲーションバーを表示する方法、ナビゲーションバーを保持する方法を書いています。 1.0 ナビゲーションバー常時表示 下記を最初のシーン入れます。これでアプリが立ち上がったらすぐにナビゲーションバーが表示されます。 Test.cs void Awake(){ Screen.fullScreen = false; } 2.0 戻るボタンの有効化(◁ボタン) 戻るボタンは1.0を設定しただけでは有効になりません。下記を各シーンに入れると戻るボタンを有効にして、アプリを終了させることができるようになります。 Test.cs void Start () { Input.backButtonLeavesApp = true; }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SystemInfo.operatingSystemからバージョンを取得するときの注意(iPadOS15.1以降のiPad端末の挙動について)

PONOS Advent Calendar 2021の2日目の記事です。 昨日は@nissy_gpさんの「UnityのGC AllocateとWaitForSeconds」でした。 はじめに UnityのSystemInfo.operatingSystemをご存知でしょうか。 アプリの実行環境のOS情報を取得するプロパティであり、OS名とバージョンを「iOS 15.1」のようなフォーマットの文字列で返してくれます。 SystemInfo-operatingSystem - Unity スクリプトリファレンス 今回は、iPadOS 15.1以降のiPad端末でSystemInfo.operatingSystemを使用していて発生した問題について共有させていただきます。 なお、筆者の手元で今回確認した端末のOSバージョンがiPadOS 15.1でしたので、そちらのバージョンについてのみ記述しています。 iPadOS 15.0 ~ 15.0.2での動作については未確認ですが、同様の挙動をする可能性があります。 また、確認時のビルド環境はUnity 2019.4.32f1およびXcode 13.0です。 発生した問題 前提 SystemInfo.operatingSystemをiOS環境で呼ぶと、「iOS 15.1」のように「iOS」から始まる文字列を返してくれます。 これは、端末の種類がiPhoneであってもiPadであっても同様の挙動でした。 (ちなみに、iOS 10未満の場合は「iPhone OS」から始まる文字列を返していましたが、今回は特に触れません) 私の携わっていたプロジェクトでは、このSystemInfo.operatingSystemから取得できる文字列を利用して、 以下のようなコードでiOSのバージョンを取得して一部機能の利用可否を判定していました。 /// <summary> /// 端末のiOSのバージョンを取得。 /// </summary> /// <returns>iOSのバージョン。</returns> static Version GetiOSVersion() { var operatingSystem = SystemInfo.operatingSystem; // 「iOS」から始まる文字列が返ってくる前提で、「iOS」部分を削除してバージョンの部分のみを残す。 // "iOS 15.1" -> "15.1" var versionString = operatingSystem.Replace("iOS ", ""); // バージョンの文字列をSystem.Versionオブジェクトにパースする。 Version version; if (Version.TryParse(versionString, out version)) { return version; } return null; } #if UNITY_IOS var version = GetiOSVersion(); if(version == null) { return false; } return 13 <= version.majarVersion; // iOS 13以降であれば機能が利用できる。 #endif iPadOS 15.1で問題が発生 アプリのiOS 15対応を進めていたある日、 「iPadOS 15.1のiPad端末で検証しているが、該当機能が有効化されていない」という不具合報告が飛び込んできました。 「該当機能については手を入れていないはずなのに不思議だな…」と思いつつ調査を進めていくと、衝撃の事実が。 なんと、「iPadOS 15.1を搭載したiPad端末」においてSystemInfo.operatingSystemが 「iPadOS 15.1」のような「iPadOS」から始まる文字列を返していることが判明したのです…! 先ほど上で紹介したGetiOSVersion()メソッドはSystemInfo.operatingSystemの前半部分が「iOS」でないと、 バージョンの文字列を抽出することができないので、その後のSystem.Version.TryParse()に失敗します。 GetiOSVersion()メソッドがバージョン情報を返せなかったために、利用可能なバージョンかどうかの判定を行うことができず、 該当機能が「利用不可」として処理されてしまっていた、というわけです…。 iPadOS 15.1上のSystemInfo.operatingSystemの挙動に対応するため、GetiOSVersion()メソッドを修正することになりました。 iPadOSから始まる文字列に対応するための修正 修正方法としてすぐに思いついたのは、「iOS」と「iPadOS」の両方をReplace()で削除する方法でした。 // 「iOS」部分を削除してバージョン文字列の部分のみを残す。 var versionString = operatingSystem.Replace("iOS ", ""); // 「iPadOS」部分を削除してバージョン文字列の部分のみを残す。 versionString = operatingSystem.Replace("iPadOS ", ""); しかし、この修正の場合、今後のバージョンでまた前半の文字列が変化した場合に再度コードを修正する必要が生じてしまいます。 これ以上、前半の文字列の内容に振り回されたくはないため、正規表現でバージョン情報を取得する方法で修正することにしました。 /// <summary> /// 端末のiOSのバージョンを取得。 /// </summary> /// <returns>iOSのバージョン。</returns> static Version GetiOSVersion() { var operatingSystem = SystemInfo.operatingSystem; // 「数字」から始まり、「.(ピリオド)」と「数字」が連続する文字列を探し出す。 var regex = new System.Text.RegularExpressions.Regex("([0-9]+)(\\.[0-9]+)*"); var match = regex.Match(operatingSystemString); if (!match.Success) { return null; } Version version; if (Version.TryParse(match.Value, out version)) { return version; } return null; } これなら、前半の文字列が「iOS」でも「iPhoneOS」でも「iPadOS」でもバージョン情報を抽出することができます! まとめ SystemInfo.operatingSystemを利用してOSバージョンを判定している場合、 判定方法によっては新しいOSバージョンがリリースされたときに動作不備が発生することがありますので注意しましょう。 明日の担当も私@e73ryoです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rider for Unityで個人的にオススメする設定

RiderはVS CodeやAtomといったIDEと違い,プラグインをダウンロードしなくてもデフォルトで多数の機能が入っています。 ただ中には「個人的にはこれは要らなかった」と思う設定も多数あるので,気持ちよくRiderを使用する為には詳細な部分の設定までいじる必要があります。 しかし自分で一から検索をしていくのでは時間を多く使ってしまうので,本記事では私が行っている設定を公開します。 注意 Riderの設定画面を開くまでの動作は共通なので記事内では説明を省きます。 ※ MacではSettingsの部分がPreferenceとなっています。 設定 空白表示 Editor > General > Appearance Show whitespacesにチェックを入れると空白表示がされます。 設定理由 現在の階層がより分かり易くなる。 全角入力をした際に強調表示される。 アトリビュートの位置を変更 Editor > Code Style > C# > Line Breaks and Wrapping Arrangement of Attributes内の選択欄をNeverにすることで,アトリビュートを全て2行で表示するようにしています。 尚この際Keep existing arrangement of attributesの設定もオンにしてください。 この設定をしないと意識してアトリビュートの位置を変更した場合であっても,上記で設定したデフォルトの設定に位置がリセットされてしまいます。 項目の挙動の違い Never: どのようなコードでも行を分けて表示。 If owner is singleline: 複数行に渡るコードだった場合はアトリビュートを分けて表示,一行で書かれたコードだった場はシングルラインで表示。 Always: どのようなコードでも一行で表示。 設定理由 デフォルトの設定だとアトリビュートを多数使用した場合,ひたすら横に長くなってしまうのでオフ。 インデントの設定を変更 Editor > Code Style > C# > Tabs, Indents, Alignment このTabs, Indents, Alignmentの中でインデントを超細かく指定できます。 自分の場合はAlign Simlar Code in ColumnsのEnd commentsという設定にチェックを入れ,コメントを横並びにした際の終了位置を揃えています。 設定理由 コメントの開始位置がバラバラだと高低差によって目が疲れる。 varへの推奨表示をオフ Editor > Code Style > C# > Syntax Style 'var' Usage in Declarations項目の下記3つをDo not showに設定します。 設定理由 パッと見で型が分からないような書き方しててもvarに推奨されるので,可読性が著しく低下する。 privateの使用を強制しない Editor > Code Style > C# > Syntax Style ModifiresのPrefer explicit/implicit private modifier for type members項目から設定します。 左側の項目欄をImplicitにすると,変数を宣言した時にprivateが自動で追加されるのを防げます。 右側の項目欄をDo not showに設定すると,privateが使用されていなかった場合でも緑の波線を表示しないようにします。 自分の場合はアクセス範囲は必ず記述したいので左側の項目はExplicitに,他人のコードを見た時に波線びっしりは嫌なので右側の項目はDo not showに設定しています。 インレイヒント(引数名)を非表示にする Editor > Inlay Hints > General Default VisibilityをShow AlwaysからPush-to-Hintに設定することで,下記のような引数が表示されるインレイヒントという機能を無効にしています。 項目の動作の違い Show Always: インレイヒントを常に表示。 Push-to-Hint: 基本はインレイヒントを非表示。『Ctrl』キーを押している間のみインレイヒントを表示。 Never Show: インレイヒントを常に非表示。『Ctrl』キーを押しても無効。 設定理由 コードがひたすら横に長くなる。 引数の途中で改行を入れるとコードの開始位置がずれて見にくくなる。 開始位置を頑張って調整したとしても他のIDEやクラウド上ではずれて見える。 if文のnest表示をオフにする Editor > Inspection Settings > Inspection Severity > C# 検索欄にnestと入力し,Language Usage OpportunitiesのInvert 'if' statement to reduca nestingのチェックを外してください。 設定理由 無理に階層を浅くすることで,逆に見にくくなる場合が存在する。 readonlyの使用を強制しない Editor > Inspection Settings > Inspection Severity > C# 検索欄にreadonlyと入力し,Common Practices and Code Improvementsのチェックを全て外してください。 設定理由 拡張エディタやライブラリを使用している箇所でreadonlyを使用すると,想定していた挙動と違うといったことが発生する。 名前空間の階層が違うことによる警告表示をオフ Editor > Inspection Settings > Inspection Severity > C# 検索欄にfileと入力し,Namespace does not correspond to file locationのチェックを外してください。 設定理由 ファイルの階層とnamespaceの階層が綺麗に一致している人等そうおらん。 その他 今回は個人的にオススメする設定ということで記事を書いたので, 人によって意見が大きく割れそうな内容については記述していないです。 本記事で書かなかった内容については別の記事にて紹介するのでお待ちください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity 2021におけるパッケージ関連の変更について

はじめに Unityにおける「パッケージ」とは、さまざまな機能やアセットをまとめたものです。たとえば JSON関連の機能を提供する「JSONSerialize」パッケージ 2Dマップエディターの機能を提供する「2D Tilemap Editor」パッケージ IDEであるRiderとの統合機能を提供する「JetBrains Rider Editor」パッケージ などがあります。Unityはさまざまな用途に使われおり、コア機能・パッケージが提供する機能も多岐に渡ります。自分のプロジェクトに合わせて、適切なパッケージを選択し導入することが大切です。 そんなパッケージですが、Unity 2021.1で変更がありました。今まで検証済みパッケージだったいくつかのパッケージがコアパッケージに移行されました。また、パッケージの検証状態の名称とその意味・区分が変更されました。 「パッケージの検証状態の名称とその意味・区分の変更」は、今まで「プレビュー(Preview)パッケージ」というパッケージを使っていた人には非常に重要です。この変更を把握しないと、「もともと導入していたプレビュー(Preview)パッケージが見当たらない」というトラブルに見舞われる場合があります。 この投稿は、Unity 2020.3.19f1およびUnity 2021.2.0f1、そして2021年11月の情報を下に執筆しています。変更があったのはUnity 2021.1で、実際の動作検証は最新テックリリース版であるUnity 2021.2で行っていることに注意してください。 パッケージの種類 Unity 2021.1でのパッケージ関連の変更を説明する前に、まずはパッケージの種類をおさらいしましょう。 パッケージには次のようにいくつかの区分・種類があります。 Unityエディターに統合されプロジェクトに応じて有効・無効を設定するビルトインパッケージ Unityエディターにバンドルされているコアパッケージ Unity公式のパッケージ エンドユーザーが作成した再利用可能なコードやアセットをまとめたパッケージ ビルトインパッケージは次のようなものがあります。 JSON関連の機能を提供する「JSONSerialize」パッケージ Tilemap機能を提供する「Tilemap」パッケージ(エディターを含まない) 物理機能を提供する「Physics」パッケージ Unityエディターにバンドルされているコアパッケージは次のようなものがあります。 Sprite Editor機能を提供する「2D Sprite」パッケージ 2DマップのTilemapエディター機能を提供する「2D Tilemap Editor」パッケージ uGUI関連の「Unity UI」パッケージ Unity公式のパッケージは多くのパッケージがあります。ごく一部を取り上げると次のようなものがあります。 Android OSのログライブラリを司る「Android Logcat」パッケージ Burstコンパイラを提供する「Burst」パッケージ モバイルOSのAR機能を提供する「ARCore XR Plugin」パッケージ/「ARKit XR Plugin」パッケージ 新しい入力システムを司る「Input System」パッケージ ビルトインパッケージ・コアパッケージを除く、Unityが提供するパッケージでは、Unity 2020.3 LTSまで次のような名称がありました。 十分なテストがすんでいて実際のプロジェクトに導入可能な、検証済み(Verified)パッケージ 検証中であり技術調査・技術検証向けな、プレビュー(Preview)パッケージ Unity 2021.1から「検証済み(Verified)パッケージ」と「プレビュー(Preview)パッケージ」の名称と意味・区分が変更になりました。詳しくは、後述の「パッケージの名称変更」で説明します。 検証済みパッケージからコアパッケージへ 次のパッケージは、Unity 2020.3 LTSまでは検証済みパッケージでしたが、Unity 2021.1からコアパッケージになりました。 Core RP Library High Definition RP Shader Graph Universal RP Visual Effect Graph これらのパッケージは、Unity 2020.3 LTSまでは検証済みパッケージでした。そのためパッケージレジストリ(Unity公式のパッケージを保存・配信しているサーバー)からダウンロードされ、特定のディレクトリにキャッシュされ、プロジェクトに導入されました。 ところでUnity 2021.1からこれらのパッケージは、コアパッケージになったことで、Unityエディターの中にパッケージが同梱されるようになりました。たとえばMacでUnity Hubを使っている場合、「"{該当のUnityエディターバージョン}"/Unity/Contents/Resources/PackageManager/BuiltInPackages/」に、コアバッケージが同梱されています。 すでにコアパッケージだった次の3個のパッケージに加え、コアパッケージは計8個になりました。 2D Sprite 2D Tilemap Editor Unity UI パッケージの名称変更 Unityに統合されているビルトインパッケージとコアパッケージ以外にも、Unity公式のパッケージがあります。 Unity 2020.3 LTSからUnity 2021.1へのアップデートにおいて、それらの名称・意味・区分が変わりました。 Unity 2020.3 LTSまでの名称 まずはUnity 2020.3 LTSまでの名称と意味を確認します。 Unity 2020.3 LTSまではUnityに統合されているビルトインパッケージとコアパッケージ以外に、 「検証済みパッケージ(Verified Package)」 「プレビューパッケージ(Preview Package)」 というパッケージがありました。 「検証済み(Verified)」および「プレビュー(Preview)」は、実プロジェクトで利用可能かどうかの検証状態を表しています。「検証済み(Verified)パッケージ」は十分なテストがすんでいて実際のプロジェクトに導入可能なパッケージです。「プレビュー(Preview)パッケージ」は検証中であり技術調査・技術検証向けのパッケージです。 プレビュー(Preview)パッケージは、今後大きな仕様変更が入ったり、サポートが終わる可能性もあるパッケージです。また、実験的なパッケージも含んでいました。 執筆時点(2021年11月30日時点)、Unity 2020.3 LTSにおいて、検証済み(Verified)パッケージは多数あります。一部の例として次のようなものがあります。 Android Logcat Burst Input System 執筆時点(2021年11月30日時点)、Unity 2020.3 LTSにおいて、いくつかのプレビュー(Preview)パッケージが存在します。例としては次のものがあります。 2D IK 2D Tilemap Extras UI Builder 「検証済み(Verified)」と「プレビュー(Preview)」という、検証状態を示す名称は、一見すると良さそうです。ところが「プレビュー(Preview)」パッケージは、次の2つの状態の判別がつかないという問題がありました。 「近いうちに検証済み(Verified)パッケージになる予定で、そのうち実際のプロジェクトで使えるようになるパッケージ」 「あくまで実験的な機能としての提供で、いつまで経っても検証済み(Verified)パッケージとならない可能性もあるパッケージ」 利用側としては、「プレビュー(Preview)」状態のパッケージに対してどれくらい力をいれて試してよいか分からず、使いにくかったのです。 Unity 2021.1からの名称 「プレビュー(Preview)」という状態の分かり難さを解消するために、Unity 2021.1から「検証済み(Verified)」と「プレビュー(Preview)」という名称をやめ、新しいパッケージの名称と意味・区分を導入しました。それにより、パッケージ利用側がサポートされているパッケージの状態を明確に区別できるようになりました。 Unity 2021.1より、パッケージの検証状態は、次の名称・意味・区分になりました。(Unityに統合されているビルトインパッケージとコアパッケージを除く) リリース済み(Released) プレリリース(Pre-release) 実験的(Experimental) リリース候補(Release Candidates) 非推奨(Deprecated) それぞれの内容を紹介します。 リリース済み (Released) 「リリース済み(Released)」な状態は、Unity 2020.3 LTSまでの「検証済み(Verified)」に相当します。 リリース済み(Released)パッケージは、実際のプロジェクトにも、安心して導入できます。プロジェクトへの導入では、パッケージマネージャーウィンドウにおいて、何もせずとも導入候補パッケージとして出てきます。リリース済み(Released)パッケージの一覧は、公式ドキュメント「Released packages」から確認できます。 プレリリース(Pre-release) 「プレリリース(Pre-release)」な状態は、その年のUnity LTSリリースまでに安定した状態になり、リリース済み(Released)パッケージになることが期待されているパッケージです。 プレリリース(Pre-release)パッケージは、公式にサポートされていて、ロードマップの一部となっています。また、検証途中でもあるためパッケージへのフィードバックが求められている状態でもあります。プレリリース(Pre-release)パッケージの一覧は、公式ドキュメント「Pre-release packagess」から確認できます。 プレリリース(Pre-release)パッケージは、デフォルト設定では、パッケージマネージャーウィンドウの導入候補に出てきません。次の画像のように、「Enable Pre-release Packages」にチェックを入れることで、導入候補に出てきます。 実験的(Experimental) 「実験的(Experimental)」な状態は、あくまで実験的なパッケージの状態、手探り的なパッケージの状態です。 実験的(Experimental)パッケージは、最終的にリリースされずに、「非推奨(Deprecated)」となる可能性があることに注意してください。また、製品として十分にテストされておらず、ロードマップに含まれているわけではありません。誤って実験的(Experimental)パッケージを実プロジェクトへ導入することを防ぐため、Unityエディターのパッケージマネージャーウィンドウの導入候補の一覧で、実験的(Experimental)パッケージは表示されないようになっています。実験的(Experimental)パッケージの導入方法は、それぞれのパッケージのフォーラムなどを参照してください。 Unity 2020.3LTSにおいて、プレビュー(Preview)パッケージとして公開されていたパッケージは、原則すべて実験的(Experimental)パッケージになりました。ただし「2D Tilemap Extras」のように、プレビュー(Unity 2020.3 LTS)からリリース済み(Unity 2021.1)状態に移行し、プレビュー(Preview)な状態を脱したパッケージもあることに注意してください。 実験的(Experimental)パッケージの情報が欲しい場合は、ベータ版の各種情報チャンネル、そして「フォーラム」で情報を探してください。繰り返しになりますが、実験的(Experimental)パッケージは将来的にサポートが終了し、非推奨(Deprecated)となる可能性があることに十分に注意してください。 プレリリース(Pre-release)から実験的(Experimental)になったパッケージのいくつかは、公式ドキュメント「Adding a registry package by name」に記載されている方法で、Unity 2021.2でも導入できることを確認しました。ここでは実験的(Experimental)パッケージの「UI Builder」を例として、導入方法を紹介します。(執筆時点・2021年11月30日時点の情報) まず確認をします。次の画像は、Unity 2020.3 LTSにおいて、「Enable Peview Packages」にチェックを入れた状態のパッケージマネージャーウィンドウです。Unity 2020.3 LTSでは、「UI Builder」が導入候補に出ていることに注目してください。 次の画像は、Unity 2021.2 において、「Enable Pre-release Packages」にチェックを入れた状態のパッケージマネージャーウィンドウです。Unity 2021.2 では、「UI Builder」が導入候補として存在しないことに注目してください。これは実験的(Experimental)パッケージが、Unityエディターのパッケージマネージャーウィンドウの導入候補の一覧に表示されなくなったためです。 次にUnity 2021.2 において、UI Builderを導入する方法を示します。パッケージマネージャーウィンドウの左上の+ボタンを押下し、ドロップダウンから「Add Package by Name」を選択すると、次の画像のようにポップアップが出てきます。そこで上部に「com.unity.ui.builder」と入力し、右下のAddボタンを押下するとプロジェクトにUI Builderが導入できます。「com.unity.ui.builder」は、UI Builderのnameです。Unity 2020.3 LTSのドキュメントに記載されています。 UI Builderが導入できると、次のようにプロジェクトに導入されているパッケージ一覧に表示されます。 すべての「プレリリース(Pre-release)から実験的(Experimental)になったパッケージ」がこの方法で導入できるわけではないことに注意してください。 それ以外の状態 ここまで次のパッケージの状態を説明しました。 リリース済み(Released) プレリリース(Pre-release) 実験的(Experimental) この3つの状態に加え、次の2つの状態があります。 リリース候補(Release Candidates) 非推奨(Deprecated) 「リリース候補(Release Candidates)」な状態は、プレリリース(Pre-release)パッケージが、リリース済み(Released)になる準備ができた場合に遷移する状態です。 この状態になると、リリース済み(Released)パッケージ一覧に表示されます。ただし表示は「Released」ではなくて「Release Candidate」や「RC」という表示がされます。 非推奨(Deprecated)は、サポートが終わった状態です。「実験的(Experimental)」パッケージが、リリースされずにこの状態となる可能性があることに注意してください。 まとめ Unity 2021.1では、Unityパッケージ関連で変更がありました。 今まで検証済みパッケージだったいくつかのパッケージがコアパッケージに移行されました。「このパッケージは無くなったのかな」と思ったら、コアパッケージに移行した場合もあるので、注意してください。 また「パッケージの検証状態の名称とその内容」が変更されました。プレビュー(Preview)という、どう扱っていいか分かりずらい状態が、プレリリース(Pre-release)と実験的(Experimental)という区別しやすい状態に別れました。 Unity 2020.3 LTSでプレビュー(Preview)だったパッケージは、Unity 2021.1で実験的(Experimental)パッケージになったものもあります。実験的(Experimental)パッケージは、Unityエディターのパッケージマネージャーウィンドウの導入候補には出てきません。「あるプレビュー(Preview)だったパッケージは、Unity 2020.3 LTSでは、パッケージマネージャーウィンドウの導入候補に出てきた。しかしUnity 2021.1から実験的(Experimental)になったので、パッケージマネージャーウィンドウに出てこなくなった」という場合に注意してください。 Unityを用いた開発において、パッケージは必要不可欠です。今回の変更、そしてこの投稿の内容が、みなさんの開発の助けとなることを祈っております。 リンク集 次のドキュメントは、Unityにおけるパッケージマネジャーのコンセプトや用語解説があります。 Unity's Package Manager Concepts(Unity 2021.1) Unity's Package Manager Concepts(Unity 2020.3) 次の公式ブログは、Unity 2021.1から変更になったパッケージの名称・意味を解説しています。Q&Aが特に必見です。 Unity 2021.1 の新しいパッケージマネージャー体験 筆者がこの投稿の内容の一部を発表したセッション動画:「Unity 2021.1でのUnityパッケージの名称変更について」 補足 この投稿は、筆者が寄稿した「UniBook 13」の「Unity 2021.1におけるパッケージ関連の変更について」を、再編集したものです。 Unity 2021.2で動作確認し、また最新情報に合わせて内容を更新し、編集したものです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む