【Unity】Triggers モジュールについて
明けましておめでとうございます。もう2月ですが・・ ^_^;
今回は Particle System の Triggers モジュールについて調べてみました。
確認バージョンは 2019.1.0b2 です。
実装
Trigger モジュールは Colliders に設定したコライダーに対してパーティクルが接触した際の処理を設定することができます。
設定できる処理は以下になります。
項目 | 処理内容 |
---|---|
Ignore | 何もしない |
Kill | ParticleSystemが設定されているGameObjectを削除 |
Callback | スクリプトに通知 |
今回はこの中の Callback についてまとめてみました。
コールバックを設定するスクリプトを用意します。今回は ParticleTriggerTest.cs という名前で作成して Particle System と同じ GameObject にアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ParticleTriggerTest : MonoBehaviour { ParticleSystem m_particleSystem; List<ParticleSystem.Particle> m_enterList = new List<ParticleSystem.Particle>(); List<ParticleSystem.Particle> m_exitList = new List<ParticleSystem.Particle>(); void Start() { m_particleSystem = this.GetComponent<ParticleSystem>(); } /// <summary> /// . /// </summary> void OnParticleTrigger() { // 条件に一致するパーティクルを ParticleSystem から取得する. int numEnter = m_particleSystem.GetTriggerParticles( ParticleSystemTriggerEventType.Enter, m_enterList ); int numExit = m_particleSystem.GetTriggerParticles( ParticleSystemTriggerEventType.Exit, m_exitList ); // 取得したパーティクルの色を変更する. for( int idx=0 ; idx < numEnter ; idx++ ){ ParticleSystem.Particle p = m_enterList[ idx ]; p.startColor = Color.red; // 赤色. m_enterList[ idx ] = p; } for( int idx=0 ; idx < numExit ; idx++ ){ ParticleSystem.Particle p = m_exitList[ idx ]; p.startColor = Color.yellow; // 黄色. m_exitList[ idx ] = p; } // 変更したパーティクルを ParticleSystem に再設定. m_particleSystem.SetTriggerParticles( ParticleSystemTriggerEventType.Enter, m_enterList ); m_particleSystem.SetTriggerParticles( ParticleSystemTriggerEventType.Exit, m_exitList ); } }
- Triggersモジュールを使用すると OnParticleTrigger が呼び出されます。
- インスペクタで Callback に設定した条件(Outside, Inside, Exit, Enter)ごとのパーティクルを取得するには GetTriggerParticles を使います。
- 取得したパーティクルのパラメータに変更を加えたら SetTriggerParticles で変更内容を適用してあげます。
上記のサンプルスクリプトはパーティクルのカラーを Enter時に赤色、Exit時に黄色 に変えています。
気になる点
OnParticleTrigger が毎フレーム呼ばれる
Outside のパーティクルを取得するために毎フレーム呼び出しになっているようです。しかも Triggers モジュールのチェックが有効になるだけで呼ばれてしまうところにも注意が必要です。
GetTriggerParticles / SetTriggersParticles の負荷が高い
こちらは ParticleSystem.GetParticles/SetParticles と同様にパーティクルの情報に直接アクセスする事が出来ず、一度配列にコピーした後に変更を加えて、再度データを流し込む必要があるため負荷が高くなります。
Colliderの登録が面倒
インスペクタ上から Colliders にコライダーを登録する必要があるのですが、数が多いと大変です。ParticleSystem.trigger.SetCollider() を使えばコライダーを登録する事ができるので スクリプトから制御するのも手ですね。
まとめ
パフォーマンスの面で気になるところが多い印象でした。こちらのフォーラムにあるように今後の更新で JobSystem によるパフォーマンス改善が出来ないかUnityさんの方で色々と試しているようですね。表現の幅は広がりそうなのでとても楽しみです。^_^
参考
【Unity】VideoPlayerを使ってみた
最近、Unityでの動画再生について調べる必要があったので自身の備忘録としてまとめました。
VideoPlayer
Unityの動画再生はUnity5.6から追加された VideoPlayer コンポーネントを使う必要があります。Unity5.6より前は MovieTexture を使っていましたが Unity2018.3 から廃止されてしまったので VideoPlayer 一択となりました。
設定方法
VideoPlayerで動画の再生を確認するだけであれば割と簡単です。
動画ファイルをProjectビューに配置します。
Main Camera が設定されている GameObject に VideoPlayerコンポーネントを追加
VideoPlayerコンポーネンとの Video Clip に動画ファイルを設定
Unityエディタを再生
事前読込
VideoPlayer.Prepare() を使えばバッファへ動画データを事前に読込んでおくことができます。VideoPlayer.prepareComplete にコールバックを設定すれば読込完了を検出することができます。
void Start() { // VideoPlayerコンポーネント取得. videoPlayer = obj.GetComponent<VideoPlayer>(); // 即再生されるのを防ぐ. videoPlayer.playOnAwake = false; // パス or VideoClip を設定. videoPlayer.url = "Assets/Resources/testfile.mp4"; // videoPlayer.clip = videoClip; // 読込完了時のコールバックを設定. videoPlayer.prepareCompleted = OnCompletePrepare; // 読込開始. videoPlayer.Prepare(); } // 読込完了時のコールバック. void OnCompletePrepare() { // 読込が完了したら再生. videoPlayer.Play(); }
その他
あと動画に関する知識があまりに無かったので、その辺もメモしておきます ^_^;
コーデック
データ(映像、音声)の圧縮・変換と復元の方法です。COmpression/DEcompressionを縮めたもので映像と音声でコーデックがそれぞれ異なります。圧縮・変換を「エンコード」復元を「デコード」と言います。
映像コーデック
コーデック | 概要 |
---|---|
MPEG-4 | 第三世代携帯電話や携帯ゲーム機などモバイルで主流になりつつある |
H.264 | 低ビットレートで高画質を維持することができるため、動画配信サービスやiPhone,Androidなどのスマホに採用されている、現時点で最も主流な映像コーデック |
H.265 | H.264の後継、H.264よりも圧縮効率に優れているがエンコード時の負荷が高い、また、Unity2018.3時点ではVideoPlayerで再生サポートされていない(Unity2019.1aから公式サポートとのこと) |
WMV9 | マイクロソフトが開発、Windowsでの普及率は高い |
Divx | Divx, Inc がMPEG-4をベースに独自開発、DVDプレイヤー、カーナビなどのデジタル家電でよく利用される |
Xvid | フリーの映像コーデック、エンコードはDivxより速いと言われている、商業使用時はそのソフトのソースコードを公開する義務が発生するので殆ど使用されていない |
音声コーデック
コーデック | 概要 |
---|---|
MP3 | 最も使用されている音声コーデック |
AAC | MP3の後継、同程度のビットレートであればMP3より高い音声品質が実現、 |
AC3 | 5.1chの出力に対応、圧縮率が高い場合は他音声コーデックより音声品質が良い、DVD・Blu-ray等に使用される |
コンテナ(動画形式)
映像コーデック + 音声コーデックのセット、正式名称は「コンテナフォーマット」と言うそうです。コンテナごとに扱える映像コーデックと音声コーデックが決まっているので目的に応じたコンテナを選択する必要があります。以下に代表的なものをまとめてみました。
コンテナ | 映像コーデック | 音声コーデック | 拡張子 |
---|---|---|---|
MP4 | MPEG-4, H.264, H.265 | AAC, AC3, MP3 | .mp4, .m4a |
MOV | MPEG-4, H.264, MJEG | AAC, MP3, LPCM | .mov, .qt |
WMV | WMV9 | WMA,AAC,MP3 | .wmv |
AVI | MPEG-4, Divx, Xvid, H.264, H.265 | AAC, MP3 | .avi |
MP4 が割と一般的なのかなと思いました。iPhone,Android, 携帯ゲーム機などで広く使われていますし ^_^
また、iPhone, Androidの端末やOSバージョンで対応しているコーデックは以下ページで確認できます。
・iPhone
「Video Playback」「Audio Playback」参照
iPhone - Compare Models - Apple
・Android
Supported media formats | Android Developers
参考
【Unity】Shuriken Particle Unity2018
Unity2018以降で Shuriken Particle に追加された機能で個人的に気になったものを書いていきます。
確認バージョンは 2018.3.0f1 です。
- Ring Buffer Mode
- Orbital Velocity
- Shape : Rectangle
- Shape : MeshRenderer
- Texture Sheet Animation : FPS
- 所感
- 参考
Ring Buffer Mode
メインモジュールに追加された機能です。
パーティクル数が Max Particles 到達時の処理を設定します。
パラメータ
|
説明 |
---|---|
Disabled | Ring Buffer Mode を無効にします。上限値に達した場合、そのパーティクルの寿命(Start Lifetime)がきて上限値未満になるまで次のパーティクルは発生しなくなります。 |
Pause Until Replaced |
上限値に達した場合、古いパーティクルを即時削除して次のパーティクルを発生させます。 |
Loop Until Replaced |
Pause Until Replaced 同様に古いパーティクルを削除しますが、上限値に達するまで Loop Range で設定した値内でアニメーションをループ再生できます。 下の動画では Loop Range を 0.0 - 0.5 で設定した後に Color over Lifetime で 0.0 - 0.5 間は白→緑→白、0.5 - 1.0 間はαフェードを設定しています。 パーティクル発生中は緑色に発光し続けて、上限値に達して削除対象になった古いパーティクルはαフェードで徐々に消えています。 設定はこんな感じです。 注意点として、古いパーティクルが完全に消える前に次のパーティクルが発生するため一時的に Max Particles を超えたパーティクル数が発生します。 |
Orbital Velocity
Velocity over Lifetime モジュールに追加されたパラメータです。任意軸を中心に渦を巻くパーティクルの動きを設定できます。Orbital で軸を設定します。軸の中心はエミッターの位置になります。
(動画はパーティクルの動きを確認しやすくするためにTrailモジュールを使っています)
Offset パラメータで軸の中心を変更できます。エミッターの位置から離れるほど下の動画のように大きな渦になります。
Shape : Rectangle
Shape モジュールに追加されたパラメータです。テクスチャの色情報を元にパーティクルの発生開始位置を設定できます。
パラメータ | 説明 |
---|---|
Texture | テクスチャを設定します。対象テクスチャはRead/Writeを有効にする必要があります |
Clip Channel | クリップするRGBAチャンネルを設定します。選択したチャンネルでマスクして発生開始位置を調整します。 |
Clip Threshold | Clip Channel で設定したチャンネルの閾値を設定します。注意点として、Clip ChannelでAlphaを設定した場合は適切な閾値を設定しないと透明なパーティクル(下図)を生成して余計な描画負荷を引き起こします。 |
Color affects Particles | チェックを入れるとパーティクルがテクスチャのカラーの影響を受けます。 |
Alpha affects Particles | チェックを入れるとパーティクルがテクスチャのα値の影響を受けます。 |
Shape : MeshRenderer
こちらも Shape モジュールに追加された機能です。指定Mesh上からパーティクルを発生させます。
パラメータ | 説明 |
---|---|
Type | パーティクルの発生位置を設定します。 |
Mode | どのようにパーティクルを発生させるか設定します。Type を Vertex, Edge で設定可能 |
Spread | パーティクルの発生間隔を設定できます。Type を Edge で設定可能 |
Speed | 頂点間を移動する際の速度を設定できます。Type を Edge で設定可能 |
Mesh | Meshを設定します。対象メッシュは Read/Write を有効にしてください。 |
Texture Sheet Animation : FPS
Texture Sheet Animation モジュールの Time Mode に追加されたパラメータです。テクスチャアニメーションの FPS を設定できます。
所感
あと今回の機能はβ版で確認したので正式リリースでは仕様変更される可能性もありますが、色々とゲームの演出に使えそうな機能を追加しており表現の幅は広がりそうです。
参考
【Unite Tokyo 2018】パーティクル・マニアクス - YouTube
【CEDEC2018】 パーティクル新機能の紹介 - YouTube
【Unity】パーティクルのボリューム表現
煙や雲を表現する場合、パーティクルのビルボードを使って実装するのが一般的です。(真面目に煙や雲のポリゴンモデルを用意して描画すると負荷が凄い事になってしまうので・・・)
ただ、この方法は処理が軽くなるけど四角形ポリゴンにテクスチャを貼り付けてるだけなのでボリューム感が出ない事があります。
ライトの影響を受ければ立体感が出るはずなので単純に光源からの距離に応じて頂点単位で明るさを調整するシェーダーを適用してみました。
だいぶマシになりましたがもう少しボリューム感が欲しいです ^^;
最終的にフラグメントシェーダーでテクスチャのα値を雲の厚みとして扱うようにして明るさの調整をしてみました。
だいぶ良い感じになりました。
テクスチャのα値とは別で設定したい場合は専用のテクスチャを用意してそちらの値を参照するのが良さそうです。
プロジェクト一式はこちらにアップしました。
github.com
今回はなるべく低コストでモバイルでも動かせるものにしたかったので擬似表現になりましたが、多光源対応やより精度の高いボリューム表現をしたい場合はボリュームレンダリングを使うとかになると思います。
参考
【Unity】Unity2018.3からのPrefabワークフロー
Unity2018.3のβ版でPrefabのワークフローが色々と変更されました。今回はその中の Prefab Mode, Nested Prefab, Prefab Variant についてまとめてみました。
Prefab Mode
2018.3より前のバージョンでPrefabを編集する時は以下の流れが一般的でした。
- ProjectビューのPrefabをHierarchyビューにドラッグ&ドロップ
- Inspector/Sceneビュー上でPrefabを編集
- InspectorビューからApplyボタンを押して編集内容を保存
- Hierarchyビュー上からPrefabを削除
この流れだと以下の問題が起こりやすかったです。
・Applyボタンを押し忘れてPrefabの保存に失敗
・編集したPrefabの削除を忘れてシーンに残る
Prefab Mode はこういった問題を解決するためのものらしいです。
(Unityの公式ブログに書いてました)
Prefab Mode への移行方法は以下の3パターンがあります。
・Projectビューで対象Prefabをダブルクリック
・ProjectビューでPrefabを選択してInspectorビューの「Open Prefab」をクリック
・Hierarchyビュー上の対象Prefabの右側にある「>」をクリック
上記いずれかを実行すると以下のPrefab編集用の画面に移行します。
保存方法
Sceneビュー上部右端の「Auto Save」のチェックが有効なら編集内容は自動で保存されます。以前のように編集後に「Apply」ボタンを押す手間が無くなりました。
ただし、サイズの大きいPrefabを自動保存が有効な状態で編集すると動作が遅くなる場合があるので、その時は「Auto Save」のチェックを外します。手動で保存する場合は「Auto Save」の隣にある「Save」ボタンを押すか、または 「Ctrl + S」(Mac : Cmd + S) 保存できます。
環境設定
Prefab Modeでは 専用Sceneファイルを設定できます。 Edit > Project Settings > Editor > Prefab Editing Environments で設定できます。
例えば UI Environment にヘッダーとフッターのUIとCanvasを配置した Sceneファイルを設定しておけば、UI関連のPrefabを編集する際にそのSceneが読み込まれた状態で編集できます。これを上手く使えば、UIの編集をする際にヘッダーとフッターUIのPrefabも Hierarchyビューにドラッグ&ドロップして...という手間が省けますね
以下のようにスクリプトからも設定できます。
EditorSettings.prefabRegularEnvironment = customScene; EditorSettings.prefabUIEnvironment = customSceneUI;
2019/6/23 追記
UI Environment に Scene を設定しなかった場合、PrefabMode時に Canvasコンポーネントだけが接続されたオブジェクトがルートに配置されるため、実際のゲームSceneでCanvas Scaler を接続して解像度に応じたUIオブジェクトのスケール処理を行なっている場合、PrefabModeで編集した結果とゲーム画面とでレイアウトが一致しない現象が発生することがあります。この問題は ゲームSceneと同じ Canvas Scaler を設定した Scene を UI Environment に設定すれば回避できます。
終了方法
Prefab Mode を終了するには Hierarchyビューの「<」をクリックするか、Sceneビュー上部の「Scenes」をクリックします。
Nested Prefab
Prefabの中にPrefabを設定できる仕組みです。これの便利なところは例えば下図のようにある Prefab に Particle System が設定された別Prefab が3個配置されている状態から、Prefab Mode で Particle System のカラーを1つ編集するだけで他の2つにもその設定が適用されます。
今までのように個別で設定を行いたい場合は対象Prefabを右クリックして「Unpack Prefab」か「Unpack Prefab Completely」を選択します。2つの違いは選択したPrefabに対してのみ適用されるか、その子階層にあるPrefabにも適用されるかです。
ちなみにNestは「入れ子」という意味です ^_^
Prefab Variant
あるPrefabをベースにして異なるパラメータや、追加のコンポーネントを設定したPrefabを作成したい場合に使います。
作成方法はベースとなるPrefabを右クリック > Create > Prefab Variant で作成できます。
下図のようにPrefabアイコンに矢印が描かれたPrefabが作成されます。今回はパーティクルサイズが異なる Prefab を作ってみるので「PrefabParticle_Large」としておきます。
PrefabParticle_Large の Prefab Mode に移行して Start Size を変更します。ベースと異なる部分があるとInspectorの左端に青いラインが表示されます。
保存方法
Variant Prefabの保存方法は通常Prefabと同様ですが、ベースのPrefabに設定値を適用したい場合はInspectorビューからOverrides > Apply All to Base をクリックするか
Overrides > 変更したコンポーネントを選択して
下図のようにベースとの変更差分を確認しながら
対象パラメータ上で右クリック > Apply to Prefab XXXXX で適用する方法があります。
所感
Prefab Modeでの編集はとても便利で今まで起こっていた操作ミスが減りそうです。Nested Prefab と Prefab Variant はきちんと仕様を把握しておかないと編集した内容が他のSceneやPrefabに影響を及ぼす可能性があるので注意が必要かなぁと思いました。
参考
【Unity】Projectビューのお気に入り情報を抜き出してみる
前回に引き続き今回もProjectビューです。お気に入り情報を抜き出してファイルにエクスポート/インポートするエディタ拡張を作ってみました。
別PCのUnityエディタに自分のお気に入り情報をインポートしたい時くらいにしか使えない気がしますが内部処理を把握するのに良い勉強になりました ^^;
Unityのソースコードが公開されているのでそちらを参考にしました。調べたところSavedSearchFilter がお気に入り情報を管理してたのですが internal class だったのでリフレクションを使って参照しています・・ ^^; tsubakit1.hateblo.jp
【Unity】Projectビューについて
Unityエディタで開発をする上で大変お世話になるProjectビュー(Projectウインドウ?Projectブラウザ?) 色々と便利な機能があるのに私自身も知らない機能があったのでメモがてら書いていきます。
ショートカット
Windows | Mac | 操作 |
---|---|---|
Ctrl + D | Cmd + D | 選択中のアセットを複製 |
Delete | なし | 選択中のアセットを削除(ダイアログ確認あり) |
Delete + Shift | Delete + Cmd | 選択中アセットを削除(ダイアログ確認なし) |
F2 | Enter | 選択中のアセットの名前を変更 |
F | F | フォルダ内の選択したアセットを表示 |
Tab | Tab | 左側カラム(フォルダ一覧とFavorites)と右側カラムを |
自分が良く使うものだけ抜粋しました。
フィルタ機能
タイプ (t:)
Search by Type ボタンからアセットのタイプでフィルタリングします。
ラベル (l:)
Search by Label ボタンに設定されているラベルでフィルタリングします。
ちなみ以下のように任意のラベルを作成する事もできます。
アセットバンドル名 (b:)
その名の通りアセットバンドル名でフィルタリングします。
参照 (ref:)
これはほぼ使う機会がないのですが、パス or InstanceID 指定で参照するオブジェクトを検索します。Assets以下のアセット数が多くなると検索に物凄い時間がかかります。下手するとUnityエディタ固まります・・
例えば Assets/Scripts/Player.cs (InstanceID:12345)を参照するオブジェクトを検索する場合は「ref:Scripts/Player.cs」(Assets/を除く) または「ref:12345:」と入力します。
Scene内とかも検索する場合はこのスクリプト使ったほうが良いですね ^^;
ちなみに InstanceID は Object.GetInstanceID() で取得するか、下図のように Inspector > Debug に切り替えると確認できます。
お気に入り機能
検索結果に好きな名前を付けて左側カラムのFavoritesに保存できます。検索ファイル名 + フィルタといった複数条件も保存出来るので便利です。Unityエディタ単位での設定しか出来ず、プロジェクト単位での設定が出来ないのが懸念点ですが・・・