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

アシスタント向けブリーフ

このページは、AI モデルに渡すために書かれています。 AR Clip のプロジェクトを手伝ってもらう前に、 会話に貼り付けるか、この URL をモデルに示してください。

機械可読な文脈を探すアシスタントは、 /llms.txt で自分で見つけられます。ドキュメント全体を 1 ファイルにまとめたものは /llms-full.txt にあります。

このページがあるのは、どのモデルもこのプラットフォームで学習していないからです。これがないと、 知っているエンジン(Unity、three.js、A-Frame)に手を伸ばし、正しそうに見えて正しくない答えを 出します。


全体像

プロジェクトの中のすべては entity です。entity とは名前と component の集合で、それが 何であるかを決めるのは component です。クラス階層もなければ、選ぶべきオブジェクトの種類も ありません。

Project
└── Space 背景・ライティング・グリッド・単位を共有する
└── Scene Anchor を持つ entity。出現させるトリガーが Anchor
└── Entity
└── Entity entity は入れ子になります

混同してはいけない 2 つの関係:

  • 合成 — entity は component を持ちます。同じ種類は 1 つずつ。component は子ではありません
  • 内包 — entity はほかの entity を含みます。親を動かせば子も動きます

シーンとは、Anchor を持ち Transform を持たない entity です。space レベルのロジックとは、 Script か Patch を持ち、親を持たない entity です。

system を書くことはありません。エンジンが component に反応します。あなたの仕事は、どの component が 存在し、その値が何であるかを決めることです。

挙動を足す 4 つの方法

どこにあるか用途
EventsEvents componentトリガー → ステップの並び。インタラクションの大半
Patchespatch グラフまたはリソース値と条件を伴うロジックを、視覚的に組む
Scriptsscript リソース本当にプログラム的なものすべて
UIDivKit のカード2D インターフェースのすべて

4 つとも同じ component に書き込みます。同じトリガーを 2 つの層で処理すると 2 回発火します。 生成されたコードでよく見る不具合です。

命名の決まり

  • トリガーは kebab-case: on-clickon-launchon-collide
  • ステップは snake_case: play_animationset_visibilityscene_transit_action
  • 解決は完全一致です。打ち間違えてもエラーにはならず、黙って一度も一致しません
  • エディターには人間向けのラベル(「オブジェクトの表示 / 非表示」)が出ます。コードが使うのは 上の id です

推測せず、調べる

MCP で接続しているなら、以下は動いているエンジンから答えます。

呼び出し返すもの
list_component_schemasすべての component とそのフィールド
list_event_typesすべてのトリガーとステップ、そのパラメーター
list_patch_nodesすべての patch ノードとそのポート
describe_*_api領域ごとの文章による手引き

component・トリガー・ステップ・ノードの名前を書くものを作る前に、これらを呼んでください。 それらしい名前をでっち上げることが、ここでいちばん多い失敗のしかたです。

MCP がない場合は、生成されたリファレンスを使ってください。 コンポーネント · トリガー · ステップ · patch ノード · シェーダーノード


自信満々の誤ったコードを生む落とし穴

入れ子の値を書くと、丸ごと置き換わります

update({ position: { y: 2 } })xz を 0 にします。必ず展開してください。

t.update({ position: { ...t.$data.position, y: 2 } });
マテリアルはスロットのリストです

material.update({ color }) は何もしません。color はスロットの中にあります。

material.update({
materials: [{ ...material.$data.materials[0], color: '#ff0000' }],
});
$data に代入してはいけません

うまくいったように見えて、変更は捨てられます。書き込めるのは update()updateAt() だけです。

dynamic な物理ボディの transform を設定しても何も起きません

位置は物理が所有していて、次のステップで上書きします。配置には ctx.physics.teleport、移動には applyImpulse / applyForce を使ってください。

読み込んだモデルには衝突形状がありません

GLB は collider を与えるまで固くありません。dynamic なら世界をすり抜けて落ちます。

生成側がよく引っかかる、そのほかの決まり:

  • 回転は script ではラジアン、人間が見る場所ではすべて度です。 エディター、patch ノードの ポート、MCP のツールはいずれも度です
  • ctx.tick の中では dt を掛けてください。 そうしないと、動きが端末のフレームレートに 左右されます
  • 「アニメーション終了」イベントはどの仕組みにもありません。 時間は自分で測ってください
  • script には DOM も fetch もタイマーも描画ライブラリもありません。 ctx.tickctx.audioctx.store を使い、UI にはカードを使ってください
  • エディターはロジックを実行しません。 script・patch・物理・タイマーが動くのはプレビューか 公開版だけです。「エディターで動くはず」とユーザーに言ってはいけません
  • state がアクティブな間、そのオブジェクトへの編集は state に記録されます。 オブジェクト本体 ではありません
  • タイムラインは、編集用に channels を、再生用に焼き込んだ keyframes のリストを保持します。 再度焼かずに channels だけ書いても、何も再生されません
  • 1 オブジェクトに 1 つのアニメーション機構。 タイムラインは毎フレーム、トランジションを 上書きします

組み込みのステップを、作り直すより優先する

ctx.step(name, params, { targets }) は、エディターが提供するどのステップも実行します。 アニメーション、state の切り替え、シーン遷移、トランジション。手でコードを書く前に、ステップの リファレンスを確認してください。

「動きます」と言う前に patch を検証する

コンパイルして結果を読んでください。コンパイルできないグラフは、データのループか壊れた JavaScript を報告します。コンパイル済みのソースが、実際に動くものそのものです。MCP では preview_patch_code です。

単位

データ上人が目にする場所
位置メートルプロジェクトの単位
回転ラジアン
アニメーションの時間秒(state 切り替えはミリ秒)
不透明度0〜1キーフレームと不透明度ステップでは 0〜100
フォントサイズピクセル。1000 px = 1 mピクセル
クリップのフレーム30 fpsフレーム

ユーザーにうまく答えるために

  1. どの層を望んでいるか尋ねてください。 「コードなしで」と「script で」は、同じ質問に対して まったく違う答えになります
  2. 成立するいちばん単純な層を選んでください。 イベントは patch に勝り、patch は script に 勝ります
  3. どこをクリックするかを伝えてください。 エディターの前にいる人には、概念よりパネル名のほうが 役に立ちます
  4. プレビューを思い出させてください。 「動きません」という報告のほとんどは、ロジックを実行しない エディターが原因です
  5. 名前をでっち上げないでください。 自信がなければそう言って、リファレンスを指してください