コメントすると落ちてくるタライ

ExportMessageを使用した、スタジオで「たらい」または「タライ」とコメントするとタライが降ってくるサンプルVCIです。

サンプルデータ

https://virtualcast.jp/products/220a18dd3f7064ad9508e3a633bb66b94ab0ea6c89dbf998aa2017a6b5f4f9d7

taraicomment.zip

SubItem構成


T1~T16はgrabできるsubitemを0.01倍のサイズで配置


タライが落下しないように高さ20の所に透明なコライダーを設置(固定)

VCIは動的にアイテムを生成する事ができません。(19/5/24時点)
なので、出現時は遠くに置いておいて、移動して縮尺を戻す事で出現させるように見せます。

今回は高さ20の所に透明なコライダーを設置して、20.05の高さにタライ16個を並べておいてます。
下から上を見た時に見えないようにするため、出現時のタライの縮尺は0.01にしておきます。
subitemの名前はfor文で処理する際に楽な命名にしておきます。

VCIスクリプト

main.lua
-- 次に落下するタライ番号
local _TaraiNum = 1
 
--たらい / タライ というコメントで発火
function onMessage(sender, name, message)
 
    --コメント内容
    print(sender["name"].."「"..message.."」")
 
    --「たらい」or「タライ」を含むコメントであればtrue
    local tarai = false
    if string.find(message,"たらい") ~= nil then
        tarai = true
    end
    if string.find(message,"タライ") ~= nil then
        tarai = true
    end
 
    if tarai == true then
        print("たらいを落とします")
        local pos = Vector3.__new(0, 5, 0)
        TraraiFire(pos)
    end
end
vci.message.On('comment', onMessage)
 
--posの位置にタライを落とす
function TraraiFire(pos)
    local tarai = "T"..tostring(_TaraiNum)
    _TaraiNum = _TaraiNum + 1
    if _TaraiNum > 16 then
        _TaraiNum = 1
    end
    pos.y = pos.y + 0.5 * _TaraiNum
    vci.assets.GetTransform(tarai).SetLocalPosition(pos)
    vci.assets.GetTransform(tarai).SetLocalScale(Vector3.one)
    print("タライの落下位置 : "..tostring(pos))
end
 
-- デバッグ用
function onGrab(targe)
    if targe == "DebugSwitch" then
        print("デバッグ用スイッチ")
        local pos = Vector3.__new(0, 5, 0)
        TraraiFire(pos)
    end
end

VCIスクリプト(解説)

スクリプトはコメント受信部分、タライのループ処理部分に分かれています。

コメント受信部分

    --「たらい」or「タライ」を含むコメントであればtrue
    local tarai = false
    if string.find(message,"たらい") ~= nil then
        tarai = true
    end
    if string.find(message,"タライ") ~= nil then
        tarai = true
    end

ニコ生は同じコメントを連続して打つ事はできません。
なので、VCIでコメント連携する場合、ほぼ部分一致にする必要があります。
部分一致をする場合は string.find() という関数を使用すると、検索したい文字列が検索対象に含まれてるか判定できます。
ただし、このfind関数の戻り値は、見つかった場合number型、見つからなかった場合nilとなります。
どちらの型にも対応する為に、*find関数がnilでない時(検索できた時)にフラグを立てるようにします。

さらに複雑なパターンに対応したい場合は string型の検索方法まとめ を参考にしてください。

落下処理部分

function TraraiFire(pos)
    local tarai = "T"..tostring(_TaraiNum)
    _TaraiNum = _TaraiNum + 1
    if _TaraiNum > 16 then
        _TaraiNum = 1
    end
    pos.y = pos.y + 0.5 * _TaraiNum
    vci.assets.GetTransform(tarai).SetLocalPosition(pos)
    vci.assets.GetTransform(tarai).SetLocalScale(Vector3.one)
    print("タライの落下位置 : "..tostring(pos))
end

落下処理は特に工夫なくT1からT16まで順に落としてT1に戻るようにしています。割と自然です。
工夫した点は連続でコメントが来てもSubItemが重ならないようにする為 0.5 * _TaraiNum で高さをずらすようにしてる点です。

今回は落下位置をVCIの出現位置(x=0, z=0)にしていますが…

・ターゲット用のsubitemを作る
・落下前にプレイヤーの位置調べるsubitemを移動させて、プレイヤーに接触した場合その位置に落とす。

上記の方法で落とす場所も工夫する事ができます。