メインコンテンツまでスキップ

2026-08-06 Basis で Cilbox を使用したコンテンツ制作

Cilbox は、Basis にデフォルトで用意されているスクリプトシステムです。ワールド、プロップ、アバターなどのユーザー生成コンテンツにはスクリプトを含めることができ、それらは許可された型や関数へのアクセス権限が異なる、個別のサンドボックス内で実行されます。

セットアップ​

クラスは次のように [Cilboxable] としてマークされている必要があります:

[Cilboxable]
public class Pencil : MonoBehaviour {
// ...
  • Cilbox スクリプトを使用するシーンを利用するには、シーン内のどこかに Cilbox Scene Basis コンポーネントが 1 つ存在する必要があります。
    • Cilbox を使用して書かれたシーンスクリプトは、そのコンポーネントの外側に配置できます。
  • Cilbox スクリプトを使用するプロップを利用するには、プロップのルートに Cilbox Prop Basis コンポーネントを 1 つ置く必要があります。
  • Cilbox スクリプトを使用するアバターを利用するには、アバターのルートに Cilbox Avatar Basis コンポーネントを 1 つ置く必要があります。

これらのコンポーネントを個別に設定する必要はありません。

OnEnable が初回に呼ばれない​

Cilbox には、プロップが有効化された初回に OnEnable が呼び出されないという特有の挙動があるようです。

次のような回避策を講じる必要があるかもしれません:

private bool _isEnabled;
public void Start()
{
// ここで一回限りの初期化処理を行う。

WhenEnable();
}
public void OnEnable() { WhenEnable(); }
private void OnDisable() { _isEnabled = false; }
private void WhenEnable()
{
if (_isEnabled) return; // Cilbox の癖
_isEnabled = true;

// ここで OnEnable の処理を行う。
}

ネットワーク​

オブジェクトをネットワーク対応にするには、以下のいずれかを行います:

  • _networkShim = Basis.SafeUtil.MakeNetworkable(this) を呼び出す。
  • または、BasisNetworkShim コンポーネントを追加し、フィールドとして参照する。

オーナーシップの確認には _networkShim.IsLocalOwner() を使用します。

データの送受信:

  • パケットの送信には _networkShim.SendCustomNetworkEvent(bytes, ...) を使用します。
  • パケットの受信には、_networkShim.NetworkMessageReceived += OnNetworkMessageReceived を使用してイベントリスナーを登録します。

プロップはプレイヤーごとに読み込みタイミングが異なるため、パケットの送信を開始するために _networkShim.NetworkReady += OnNetworkReady を使用してネットワークの準備が整ったことを検出する必要があるかもしれません。

Basis Framework の作成者によると、他のプレイヤーがプロップをスポーンさせて所有している本人よりも早く読み込むことは不可能であるため、非オーナー側で OnNetworkReady がトリガーされたときは、ネットワークオーナーがパケットを受信する準備ができていると仮定して安全なはずです。 追記:これが事実かどうかは不明です。

UI ボタン​

公式の Canvas UI ドキュメントに従ってください。

クリック時にイベントをトリガーする UI ボタンを作成するには:

  • Unity UI の Button をフィールドとして参照し、
  • _eraseAllButton.onClick.AddListener(OnEraseAllClicked); のようにイベントリスナーを登録します。

ピックアップ(Pickup)​

ネットワーク同期されたピックアップのセットアップ方法については、公式の Interactable ドキュメントに従ってください。

ピックアップとドロップのイベントを検出するには:

  • BasisPickupInteractable コンポーネントをフィールドとして参照し、
  • pickup.OnInteractStartEvent.AddListener(OnPickup); や pickup.OnInteractEndEvent.AddListener(OnDrop); のようにイベントリスナーを登録します。
  • トリガーイベントには pickup.OnPickupUse.AddListener(OnPickupUse) を使用します。コールバックメソッドには、トリガーの押し始め、ホールド中、離したときを判別できる enum 値が渡されます。

ピックアップはコンポーネントのオーナーシップに影響しません。

  • ユーザーが同期されたピックアップを掴んだ場合、その同期ピックアップコンポーネントのみを所有します。
  • 同じ GameObject 上にある他のネットワークコンポーネントのオーナーシップは変更されません。

テレポーテーション​

シーンプロップは BasisLocalPlayer.Instance.Teleport(spawn.position, spawn.rotation) 関数を呼び出すことでプレイヤーをテレポートさせることができます。

ビルドのトラブルシューティング​

アップロード前のプロップがエディターでは動作するが、ビルドされた BEE ファイルを実際のアプリケーションで読み込むと動作しない場合は、プレイモード中に Unity エディター内で BEE ファイルを読み込み、エディター内で直接デバッグすることを検討してください。

この方法により、アップロード前のプロップがエディターで動作していたのは、Cilbox Prop ボックスコンポーネントが付着していなかったために、プロップ用のコンポーネントではなく Cilbox Scene ボックスコンポーネントを使用して実行されていたからであると判明したことがあります。

サポートされていないもの​

Array.Empty<HVRNPSCilBeacon>() を使用しないでください​

Privilege failed for System.Array.Empty generic argument 0 type HVR.NPS.ForCilbox.HVRNPSCilBeacon

CilboxException: Error: Could not find reference to: [mscorlib][System.Array][HVR.NPS.ForCilbox.HVRNPSCilBeacon[] Empty[HVRNPSCilBeacon]()] Type from:System.Array

ラムダ式を使用しないでください​

ArgumentException: Object of type 'Cilbox.CilboxHeapInstance' cannot be converted to type 'Cilbox.CilboxProxy'.

Vector4 から Vector3 への暗黙のキャストを使用しないでください​

  • 0 個の引数を持つ UnityEngine.Vector4 型のメソッド op_Implicit でエラーが発生しました。
  • AmbiguousMatchException: Ambiguous match found.

バグ

値の反転が正しく動作しない​

危険

最近のバージョンで修正されました。

var x = -someValue; における x の値が不正確になります。

  • Random.Range(-x, x) が期待される範囲を大幅に外れた値を返したときに発見されました。
  • -1 を掛けることで回避できます。

このバグは Cilbox リポジトリで修正されましたが、Basis Framework プロジェクトおよびクライアントに反映されるのは後日になる可能性があります。

サーバーの XML 設定でスケールが無視される​

XML 設定においてプロップのスケールが無視されます。