Line Drawing
このアドオンは、途中参加者からも見られる3D描画を作成するための、DataSyncHelpersアドオンの使用方法を示します。
機能
このアドオンでは、いくつかのLineRenderer
で構成される3D描画を作成します。
デモシーンでは、描画が完了した後にその描画を掴んだり動かしたりすることができます。
これらの描画を編集できるのは、1ユーザーのみです。複数ユーザーで編集したい場合は、TextureDrawingアドオンをご覧ください。
このアドオンは、特定の使用方法(掴み、自動的な描画など)を想定しない基本的な実装と、掴める物(実際のペン)に依存した例の基本的なドロワーを提供しています。
基本原理
描画点の同期
ドロワー(NetworkLineDrawer
)は、NetworkLineDrawing
コンポーネントが付いたネットワークオブジェクトをスポーンします。
そして、NetworkLineDrawing
に追加の線と点を保存するようにリクエストします。この線と点は、複数の点を同時に通信できるようにリングバッファ構造で保持された上で、ネットワークを通して共有されます。このデータ構造は、FusionのストリーミングAPIで全体の描画を受信することで、途中参加者にも共有されます。
ロスレスのリングバッファのロジックの詳細は、DataSyncHelpersアドオンのRingBufferLossLessSyncBehaviourクラスをご覧ください。
描画の実装
NetworkLineDrawing
は、LineDrawing
に実際のLineRenderer
の作成と設定を行わせます。
NetworkLineDrawing
は上記のロジックを、Render
内で適用します。
状態権限者(描画するユーザー)は、追加されたすべての描画点を即時に描画します。
リモートユーザーは、2ティック間の点の数と補間係数から点の数を補間して、表示する点の数を決定します。
これはNetworkBehaviour
のTryGetSnapshotsBuffers
メソッド(ネットワークバッファを参照)で行われ、「from」「to」データとその間の補間係数を提供しています。
C#
if (lastDrawnPoint < (drawingPoints.Count - 1))
{
if (Object.HasStateAuthority || drawPointsOnProxiesAsSoonAsAvailable) {
DrawAllPoints();
}
else
{
bool proxyDrawingAuthorized = lossRanges.Count == 0;
// Find the from and to state of the drawing data (byte array),
// find the entry count in each state (from drawing point count, to drawing point count),
// and interpolate the current max point to draw with the interpolation alpha (between from and to point count)
if (proxyDrawingAuthorized && TryGetSnapshotsBuffers(out var fromBuffer, out var toBuffer, out var alpha))
{
var reader = GetArrayReader<byte>(nameof(Data));
var toData = reader.Read(toBuffer);
var fromData = reader.Read(fromBuffer);
RingBuffer.PositionInfo fromPositionInfo = RingBuffer.PositionInfo.ExtractPositionInfo(fromData);
var fromGlobalByteIndex = fromPositionInfo.totalData - 1;
RingBuffer.PositionInfo toPositionInfo = RingBuffer.PositionInfo.ExtractPositionInfo(toData);
var toGlobalByteIndex = toPositionInfo.totalData - 1;
var fromGlobalIndex = RingBuffer.EntryIndexAtDataSourcePosition<LineDrawingPoint>(fromGlobalByteIndex);
var toGlobalIndex = RingBuffer.EntryIndexAtDataSourcePosition<LineDrawingPoint>(toGlobalByteIndex);
var currentIndex = (int)Mathf.Lerp(fromGlobalIndex, toGlobalIndex, alpha);
DrawPointsUpTo(currentIndex);
}
}
}
Finished handler
描画が完了すると、IsFinished
ネットワーク変数が、すべてのユーザーに同期されます。
描画完了時に掴むためのハンドルを表示できるように、NetworkLineDrawing
はfinishedHandler
ゲームオブジェクトを持ち、これは描画完了時にのみ有効になります。
ゲームオブジェクトがINetworkLineDrawingListener
を実装したコンポーネントを持っている場合、DrawingFinished
コールバックをトリガーすることが可能で、例えば実際の描画にハンドルの位置と回転を合わせることができます。
NetworkLineDrawer API
NetworkLineDrawer
自体は何も描画を行いません。他のコンポーネントやサブクラスからメソッドが呼ばれて、描画を作成します。
StartDrawing
:NetworkRunner
からNetworkLineDrawing
コンポーネントを持つdrawingPrefab
プレハブをスポーンするStopDrawing
:現在の描画を停止するStartLine(Color color)
:指定の色で線を開始する(この線は変更できません)AddPoint([Color color], float pressure)
:点を追加する(新しく作成される線の色を変更する)StopLine()
:次に追加した点から新しい線を開始することを強制する
LineDrawingPointデータ構造
描画点(LineDrawingPoint
)は2つの情報を持ちます。描画の原点から相対的なローカル位置と、圧力レベル(その点の位置の線の幅のカスタマイズ)です。
また、このデータ構造は特別なケースとして、新しい線の開始を記述するために使用されます。NEW_LINE_PRESSURE
(-1)の値は新しい線を表します。このケースでは、位置のVector3
には、始点のRGB値が含まれます。
依存関係
デモ
デモシーンはAssets\Photon\FusionAddons\LineDrawing\Demo\
フォルダーにあります。
DemoLineDrawingMeta
デモシーンをテストする場合は、Meta Packagesがプロジェクトにインストールされている必要があります。
あるいは、Meta Packagesを含むMeta XR integrationプロジェクトを使用して、直接テストすることもできます。
ダウンロード
このアドオンの最新バージョンは、無料のXR アドオンのプロジェクトに含まれています。
対応するトポロジー
- 共有モード
更新履歴
- Version 2.0.3: Allow to change inputs for NetworkGrabbableLineDrawer
- Version 2.0.2: Add check to only support MetaGrabbableLineDrawer if the Meta interaction SDK is installed
- Version 2.0.1: Add drawing interpolation
- Version 2.0.0: First release