====== アイテムの状態を同期する ======
SubItem (VCISubItemコンポーネントがアタッチされたオブジェクト) の位置・回転・拡大/縮小は自動で (強制的に) 同期されますが、SubItemのそれ以外の値、およびSubItemではないオブジェクトの位置・回転・拡大/縮小は自動では同期されません。
例えばスイッチのオン・オフ、カウンターなどを同期したい場合の方法を説明します。
例として、onUse(SubItemをつかんでいる状態で[[virtualcast:controller:item_operation#アイテムの使用| 使用]])でスイッチをオン・オフします。\\
オフの時にマテリアル0番の色が白、オンの時にマテリアル0番の色が赤にします。
=== サンプルデータ ===
{{ :vci:tips:sync_test.zip |}}
===== 方法1: _ALL_ 関数を使う ======
_ALL_ 関数で全ユーザーで同時に命令を実行します。
isRed = false
function onUse()
isRed = not isRed -- true, falseを反転させる
if isRed then
vci.assets._ALL_SetMaterialColorFromIndex(0, Color.__new(1, 0, 0, 1)) -- Red
else
vci.assets._ALL_SetMaterialColorFromIndex(0, Color.__new(1, 1, 1, 1)) -- white
end
end
簡単ですが、マテリアルの色を変えるのが投げっぱなしなので以下の場合にうまくいきません。
* 途中から凸してきたユーザーでは赤くならない
* 別のユーザーがアイテムをUseしたとき (色を制御する変数が、以前にUseしていたユーザーの中にあるので伝わらない)
===== 方法2: アイテム内同期変数を使う =====
[[https://developer.virtualcast.jp/vci-docs/api/classes/ExportState/index.html|ExportState]] を使います。\\
アイテム内同期変数を介することで、**全ユーザーで命令を実行する**ように書き換えます。
if vci.assets.isMine then
-- アイテム呼び出しユーザーでだけ初期化します
vci.state.Set('isRed', false) -- 初期値。何もしないと nil になる
end
function onUse()
local isRed = vci.state.Get('isRed') -- true, false を得ます。local
vci.state.Set('isRed', not isRed) -- 状態を変化させるだけでここでは色を変えません
end
function updateAll() -- 全ユーザーで実行したいので updateAll を使います
local isRed = vci.state.Get('isRed') -- 状態を得ます。アイテム内同期変数は全ユーザーで同期(同じ)になります。local
if isRed then
vci.assets.SetMaterialColorFromIndex(0, Color.__new(1, 0, 0, 1)) -- Red
else
vci.assets.SetMaterialColorFromIndex(0, Color.__new(1, 1, 1, 1)) -- white
end
end
===== 使い分け =====
* _ALL_ は短い効果音を鳴らすなど状態を共有する必要が無い、投げっぱなし・使い捨てでOKな場合に向いています
* アイテム内同期変数はそれ以外の全般に対応できます
===== SubItem以外の位置・回転・拡大/縮小の同期 =====
[[vci:tips:nonsync]] を参照。