ResoniteにResonite Linkが実装されたので検証しました
Resonite Linkとは
WebSocketを使ってResoniteを操作することができます
下記の例はBoxを作っています
Resonite Linkは2026/1/13時点ではベータリリースです
今後仕様が変わる可能性はあります
Resonite Linkの有効化
セッション > Resoniteリンクを有効化 をクリックしてください

Resoniteリンクを有効化するとポートナンバーが表示されます
この例では39593になります

ポートナンバーは毎回変化します
コードを書く
websockexを使います
defmodule ResoniteRedRect.MixProject do
use Mix.Project
# 省略
defp deps do
[
+ {:websockex, "~> 0.4.3"}
]
end
# 省略
end
Boxを作るソース
defmodule Rect01 do
use WebSockex
require Logger
@port 39593
@host "127.0.0.1"
def start_link(_opts \\ []) do
WebSockex.start_link("ws://#{@host}:#{@port}", __MODULE__, :no_state,
extra_headers: [
{"Host", "#{@host}:#{@port}"}
]
)
end
def handle_connect(_conn, state) do
Logger.info("ResoniteLinkに接続成功!")
{:ok, state}
end
def start() do
{:ok, pid} = start_link()
add_slot(pid)
add_box_mesh(pid)
add_pbs_metallic(pid)
add_mesh_renderer(pid)
update_mesh_renderer(pid)
update_mesh_renderer(pid)
end
def send_text(msg, pid) do
WebSockex.cast(pid, {:send_text, msg})
#Process.sleep(1000)
end
def add_slot(pid) do
"""
{
"$type" : "addSlot",
"data" : {
"id" : "ymn_1",
"parent" : {
"$type" : "reference",
"targetId" : "Root"
},
"name" : {
"$type" : "string",
"value" : "YMN_Box"
},
"position" : {
"$type" : "float3",
"value" : {
"x" : 0,
"y" : 1.5,
"z" : 10
}
}
}
}
"""
|> send_text(pid)
end
def add_box_mesh(pid) do
"""
{
"$type" : "addComponent",
"containerSlotId" : "ymn_1",
"data" : {
"id" : "ymn_2",
"componentType" : "[FrooxEngine]FrooxEngine.BoxMesh"
}
}
"""
|> send_text(pid)
end
def add_pbs_metallic(pid) do
"""
{
"$type" : "addComponent",
"containerSlotId" : "ymn_1",
"data" : {
"id" : "ymn_3",
"componentType" : "[FrooxEngine]FrooxEngine.PBS_Metallic"
}
}
"""
|> send_text(pid)
end
def add_mesh_renderer(pid) do
"""
{
"$type" : "addComponent",
"containerSlotId" : "ymn_1",
"data" : {
"id" : "ymn_4",
"componentType" : "[FrooxEngine]FrooxEngine.MeshRenderer",
"members": {
"Mesh": {
"$type": "reference",
"targetId": "ymn_2"
}
}
}
}
"""
|> send_text(pid)
end
def update_mesh_renderer(pid) do
"""
{
"$type" : "updateComponent",
"data" : {
"id" : "ymn_4",
"members" : {
"Materials": {
"$type": "list",
"elements": [
{
"$type": "reference",
"targetId": "ymn_3"
}
]
}
}
}
}
"""
|> send_text(pid)
end
# キャスト(非同期送信)の処理
def handle_cast({:send_text, msg}, state) do
{:reply, {:text, msg}, state}
end
def handle_frame({:text, msg}, state) do
Logger.info("受信データ: #{msg}")
{:ok, state}
end
end
コード説明
-
@port39593- Resonite Linkの有効化時のナンバーを書く
-
@host"127.0.0.1"- Resoniteの起動したアドレスを書く
-
def start_link
- WebSocketでResoniteに接続する
-
def handle_connect
- 接続が成功するとこの関数が呼ばれる
-
def start
- 実際に実行する為の関数
-
def send_text
- Resoniteに送信する関数
-
def add_slot
- Resoniteにスロットを追加する
-
$type" : "addSlot"はスロットを追加コマンド -
"id" : "ymn_1"はこのResonite Linkの有効化時のみ有効なID- 今後出てくるIDを同様の意味になります
- 一旦Resonite Linkが切れるとIDは再使用できません
- このサンプルではIDを取得する方法は書きません
- 手間がかかるので省略
- このサンプルではIDを取得する方法は書きません
-
|> send_text(pid)- Resoniteに送信
- pidはstart_link()時のpidを使う
-
def add_box_mesh
- この関数はBoxMesh(長方形)コンポーネントを追加
-
$type" : "addComponent"はコンポーネントを追加コマンド -
"containerSlotId" : "ymn_1"- スロットのIDを定義します
-
"componentType" : "[FrooxEngine]FrooxEngine.BoxMesh"- コンポーネントの種類を定義
- ここではBoxMeshを定義
-
def add_pbs_metallic
- PBS_Metallic(色)コンポーネントを追加
-
def add_mesh_renderer
- MeshRendererコンポーネントを追加
- membersのMeshでBoxMeshと定義
- add_box_meshで作ったID ymn_2をtargetIdにする
-
def update_mesh_renderer
- MeshRendererコンポーネントの内容を更新する関数です
-
$type" : "updateComponent"はコンポーネントを更新するコマンド - membersのMaterialsでPBS_Metallicと定義
実行方法
ライブラリ取得
$ mix deps.get
iex起動
$ iex -S mix
iex上で実行
iex(1)> Rect01.start()
補足 ResoniteでBoxを作る為の知識
前提 スロットの中にコンポーネントを入れます
今回の例は
- スロット
- BoxMeshコンポーネント
- PBS_Metallicコンポーネント
- MeshRendererコンポーネント
- BoxMesh関連付け
- PBS_Metallic関連付け
このような構成になります
ハマりポイント
MeshRendererコンポーネントでPBS_Metallicは2回定義しない動作しませんでした
原因はまだ把握してません
知っていたらコメントお願いします
ソース