9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VCIAdvent Calendar 2022

Day 24

ルーム来訪者に、すべてVCIが読み込まれるまで待たせるVCI

Last updated at Posted at 2022-12-23

ルームでVCIが全部読み込まれるまで、待ってて欲しい!

ルームでは、ロケーションを含めて、複数のVCIで構成されていると思います。
Vキャスでは、すべてのアイテムが読み込まれる前から、ルームに入ることができるので、

  • モデルの一部が読み込まれる前の、景観が悪い状態で散策されてしまう
  • 本来、コライダーがある場所を突破されてしまう
  • イベントのトリガーを踏んだ際に、連携するアイテムがないため、エラーが発生してしまう

などといった事が発生してしまいます。
これらを防ぐために、自分の作ったルームでは↓のような、通せんぼをする看板とコライダーを設置しています。
ここでは、どのようにこちらのVCIを実装したか、ご紹介します。
ダウンロード (4).gif

読み込みを待っている間も楽しんで欲しい!

Vキャスのいい点の一つとして、ロケーションが読み込まれれば、ルームに入れる点が挙げられます!
(ミクランドとかでも思いましたけど、待ち時間を最小限にして、ロケーションを楽しめるっていいですよね!)
このいい点が先ほど挙げた、問題に繋がってしまうのですが、このVキャスのいい点を活かしたロケーションの構成にしていきたいと思います!
まず、ロケーション自体をリスポーン地点を中心に構成し、読み込みを待つアイテムVCIが見えないような構造にしておきます。
今回は、このような袋小路を作って、ここをリスポーン地点として、待ってもらいます。
スクリーンショット (61).png
さらに袋小路の先は、道が曲がるようにして、ロードしているアイテムVCI(この先にある建物)が見えないようにしました。
スクリーンショット (62).png

待っていただいている間に楽しんでもらうために、雰囲気に合うBGMも用意します。
今回はフリーBGMを使うと、「あ、この曲は、あの動画で使われてるBGMだ」というような、違うところに意識が取られてしまう恐れがあったため、有償BGMを使用しました。
Audiostock様のこちらのBGMを使わせて頂いてます。

続いて、待っていただいている間、風景も楽しんでもらうため、亞希乃さん作の素敵な星空も用意しました。
これで、建物の間から見える星空がいい感じになりました!

これで、待っている間に楽しんで頂ける風景と音楽の用意できました!
2022122401154829_シャボンの国_小山内シノブ.jpg

VCIの読み込みに対応して、通せんぼするVCI

冒頭でご紹介したこちらのVCIは、リスポーン位置から少し離れた位置にあり、限りなく軽くしてあるので、ルームに入った瞬間にいち早くロードさせ、通せんぼする仕組みとなっています。
厳密には、こちらのVCIは2つのアイテムで構成されていて、「通せんぼするコライダーVCI」と「コライダーが機能しているかどうかを表すエフェクトVCI」となってます。
これは、前者のVCIをなるべく早くロードして、確実に通せんぼするためです。
ダウンロード (4).gif
さらに、確実に狙い通りの位置で、来訪者を通せんぼできるよう、messageで移動位置情報を飛ばして、移動させるようにします!
こんな感じのやり取りを、VCI同士でやらせて移動させます。
Nekoyama_nae (idolD) (2).png
実際のスクリプトは以下のような感じで、「通せんぼVCI」のvci.message.Emit("EntranceBlockTransformPlz", ...)が上図①、「ロケーションVCI」のfunction blockTransformReturn ...が上図②、「通せんぼVCI」のfunction blockTransform ...が上図③に対応してて動いてます。
ロード関係は、他者の環境は関係なく、自分の環境(ロードされたか、されないか)が重要となるため、ローカルで処理されるように、自分の名前も一緒に飛ばして、自分から送られたメッセージのみをトリガーとして、処理されるようにしています。
「エフェクトVCI」は「通せんぼVCI」と同様に、移動させ、エフェクト再生のスクリプトを追加するだけでOKです。
(ルームは位置情報が記録されるので、毎回スクリプトで移動を実行する必要はありませんが、念のため毎回実行するようにしています。)

通せんぼVCI
local block = vci.assets.GetTransform("Block")--”Block”は通せんぼするSubItem
local blockPos = Vector3.zero
local blockRot = Quaternion.identity

local transformFlag = false
--入場制限のブロックの位置情報取得
function blockTransform(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message[1] then
        blockPos.x = message[2]
        blockPos.y = message[3]
        blockPos.z = message[4]
        blockRot.x = message[5]
        blockRot.y = message[6]
        blockRot.z = message[7]
        blockRot.w = message[8]
        block.SetPosition(blockPos)
        block.SetRotation(blockRot)
        transformFlag = true
    end
end
vci.message.On("EntranceBlockTransformReturn", blockTransform)

function updateAll()
    if transformFlag == false then
        vci.message.Emit("EntranceBlockTransformPlz", vci.studio.GetLocalAvatar().GetName())
    end
end
ロケーションVCI
local entranceBlockPos = vci.assets.GetTransform("EntranceBlockPos")--"EntranceBlockPos"は通せんぼVCIの位置情報の空オブジェクト
--入場制限のブロックの位置情報
function blockTransformReturn(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message then
        vci.message.Emit("EntranceBlockTransformReturn", {
            vci.studio.GetLocalAvatar().GetName(),
            entranceBlockPos.GetPosition().x,
            entranceBlockPos.GetPosition().y,
            entranceBlockPos.GetPosition().z,
            entranceBlockPos.GetRotation().x,
            entranceBlockPos.GetRotation().y,
            entranceBlockPos.GetRotation().z,
            entranceBlockPos.GetRotation().w
        })
    end
end
vci.message.On("EntranceBlockTransformPlz", blockTransformReturn)

続いて、ルーム内アイテムがすべてロードされたことを確認し、通せんぼを解除する工程になります。
ここでは、新たに「管制VCI」が出てきて、VCIの状況を確認したり、「通せんぼVCI」に通せんぼの解除をお願いしたりします。
adcale2.png
adcale3.png
上記のイラストをスクリプトにすると以下のような感じとなり、「管制VCI」の vci.message.Emit("BovoloInitializeCheck",...が上図①、「アイテムVCI」のfunction initialize(...が上図②、「管制VCI」のvci.message.Emit("ALLVCISetOK",...が上図③、「通せんぼVCI」のblock.SetActive(false)が上図④に対応して動いてます。
上図にはありませんが、その後、「通せんぼVCI」からvci.message.Emit("BlockOFF",...を出して、「管制VCI」からの③を停止させてます。
(「エフェクトVCI」は、ほとんど「通せんぼVCI」と一緒なので、省略)
「アイテムVCI」は、読み込みが完了しない限り、上図②が動かないので、すべてのアイテムVCIが読み込まれて、すべての上図②が実行されることで、すべてのアイテム読み込み→通せんぼの解除、となります。

管制VCI
--他のVCIの初期化フラグ
local initialFlag = false
local initialize1 = false
local initialize2 = false
local entranceFlag = false
local effectFlag = true
local blockFlag = true

--他のVCIの初期化チェック
function initializeCheck(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message then
        if "Bovolo1InitializeOK" == name then
            initialize1 = true
        end
        if "Bovolo2InitializeOK" == name then
            initialize2 = true
        end
    end
end
vci.message.On("Bovolo1InitializeOK", initializeCheck)
vci.message.On("Bovolo2InitializeOK", initializeCheck)

--入場可否チェック
function entranceCheck(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message then
        if "EffectOFF" == name then
            effectFlag = false
        end
        if "BlockOFF" == name then
            blockFlag = false
        end
    end
end
vci.message.On("EffectOFF", entranceCheck)
vci.message.On("BlockOFF", entranceCheck)

function updateAll()
    if initialFlag == false then
        vci.message.Emit("BovoloInitializeCheck", vci.studio.GetLocalAvatar().GetName())
        if initialize1 == true and initialize2 == true then
            initialFlag = true
        end
    elseif initialFlag == true and entranceFlag == false then
        vci.message.Emit("ALLVCISetOK", vci.studio.GetLocalAvatar().GetName())
        if effectFlag == false and blockFlag == false then
            entranceFlag = true
        end
    end
end
アイテムVCI
--VCIの読み込み判断関数、ローカルで実行
function initialize(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message then
        vci.message.Emit("Bovolo1InitializeOK", vci.studio.GetLocalAvatar().GetName())
    end
end
vci.message.On("BovoloInitializeCheck", initialize)
通せんぼVCI
function blockStop(sender, name, message)
    if vci.studio.GetLocalAvatar().GetName() == message then
        block.SetActive(false)
        vci.message.Emit("BlockOFF", vci.studio.GetLocalAvatar().GetName())
    end
end
vci.message.On("ALLVCISetOK", blockStop)

おわりに

これで、すべてのアイテムが読み込まれまで、待ってもらうような準備が整いました。
よろしければ、みなさんもこんな感じの”待機場所”をルームに作ってもませんか?

実は、「エフェクトVCI」のほうでも少し一工夫があるのですが、それはまた別の機会がありましたら、ご紹介します!

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?