対応バージョンは、UniVCI v0.35以降です。
タルにソードを突き刺し、当たった場合はシードさんが飛び出るVCIです。
local localPlayer = vci.vc.room.GetLocalPlayer() -- ローカルプレイヤー以外では nil が返る local playerController = localPlayer.GetRoomPlayerController() local player_pos = localPlayer.GetPosition() local player_rot = localPlayer.GetRotation() --樽--刺さり剣の所有権としても使用 local barrel_root = vci.assets.GetTransform("barrel_root") --ボタン local button_reset = vci.assets.GetTransform("button_reset") local button_check = vci.assets.GetTransform("button_check") local button_bomb = vci.assets.GetTransform("button_bomb") local button_iambullet = vci.assets.GetTransform("button_iambullet") --持つ剣 local sward_root_ ={} local sward_model_ = {}--表示非表示切り替えモデル local sward_is_active_ = {} local sward_is_grab_ = {} local sward_reset_pos_ = {}--respawn local time_lastaction_sward_ = {} for i = 1,4 do-------------------------------------------運用によって変更 sward_root_[i] = vci.assets.GetTransform("sward_root_"..tostring(i)) sward_model_[i] = vci.assets.GetTransform("sward_model_"..tostring(i)) sward_is_active_[i] = true sward_is_grab_[i] = false --spawn sward_reset_pos_[i] = vci.assets.GetTransform("sward_reset_pos_"..tostring(i)) time_lastaction_sward_[i] = vci.me.Time.TotalMilliseconds end -------------------- --刺さってる剣 local hit_ ={}--root、座標判定対象 local hitsward_ = {}--表示非表示切り替えモデル local hitsward_is_active_ = {} --エフェクト local hit_effect_ = {} local flash_effect = vci.assets.GetEffekseerEmitter("flashEff") for i = 1, 20 do------------------------------------------運用によって変更 --ヒットダミー剣transform取得 hit_[i] = vci.assets.GetTransform("hit_"..tostring(i)) hitsward_[i] = vci.assets.GetTransform("hitsward_"..tostring(i)) hitsward_is_active_[i] = false --エフェクト hit_effect_[i] = vci.assets.GetEffekseerEmitter("effect_hit_"..tostring(i)) end --animationSE用 local s = vci.assets.GetTransform("sounds_root")--1 open 2 close local sounds_obj = s.GetAudioSources() --シードさん位置3D音声 s = vci.assets.GetTransform("se_seedsan")--1 open 2 close local se_seedsanpos = s.GetAudioSources() --ランダム math.randomseed(os.time())--シードリセット local bomb_index = nil --弾丸シードさん local bullet_seed = vci.assets.GetTransform("bullet_seed") local is_bullet_ready = false--モデルが樽にセットされているか local ShotPoint = vci.assets.GetTransform("ShotPoint") --弾丸ローカルアバター local is_bullet_local_ready = false--自身のローカルアバターが樽にセットされているか ---時間管理用 local time_base = vci.me.Time.TotalMilliseconds for i=1,#sward_root_ do time_lastaction_sward_[i] = vci.me.Time.TotalMilliseconds end local timespan = 3000--ミリ秒--手を離してから戻るまでの猶予 --------------------------------------------------------------------- --初期化 --一度目のみupdateから呼ばれる local is_firsttimedone = false function StartFirsttime() --持つ剣 for i = 1, #sward_root_ do --部屋に入ってきたタイミングで自分が所有権持ち、初期化を行う if sward_root_[i].IsMine == true then --持てる剣をすべて表示する vci.state.Set("IS_SWARD_ACTIVE_"..tostring(i), true) end end --刺さってる剣 for i = 1, #hit_ do --部屋に入ってきたタイミングで自分が所有権持ち、初期化を行う if hit_[i].IsMine == true then --刺さっている剣を非表示にする vci.state.Set("IS_HITDONE_"..tostring(i), false) end end --爆発初期位置 --部屋に入ってきたタイミングで自分が所有権持ち、初期化を行う if barrel_root.IsMine == true then --爆発位置ランダム bomb_index = math.random(#hit_) vci.state.Set("HIT_INDEX_BOMB",bomb_index) end end --持つ剣の表示状態の更新 function UpdateSwards() --所有権持ち以外は共有変数から状態を更新 for i = 1, #sward_root_ do if sward_root_[i].IsMine == true then --所有権持ちかつ一定時間たった時 if sward_is_grab_[i] == true then time_lastaction_sward_[i] = vci.me.Time.TotalMilliseconds end if time_base - time_lastaction_sward_[i] > timespan then --リスポーンへ移動処理 local pos_a = sward_root_[i].GetPosition() local pos_b = sward_reset_pos_[i].GetPosition() local rot_a = sward_root_[i].GetRotation() local rot_b = sward_reset_pos_[i].GetRotation() sward_root_[i].SetRotation(Quaternion.Lerp(rot_a,rot_b,0.1)) sward_root_[i].SetPosition(Vector3.Lerp(pos_a,pos_b,0.1)) end else--所有権ないとき local s_a = vci.state.Get("IS_SWARD_ACTIVE_"..tostring(i)) if s_a ~= nil then sward_is_active_[i] = s_a end end --共通、表示処理--nilも考慮 --ターゲットの一定距離内に近づいたら向きをターゲットに合わせる --表示非表示 if sward_is_active_[i] == true then sward_model_[i].SetActive(true) elseif sward_is_active_[i] == false then sward_model_[i].SetActive(false) end end --手持ち剣が初期位置に戻ったら表示状態にする for i=1,#sward_root_ do local distance = Vector3.Distance(sward_root_[i].GetPosition(),sward_reset_pos_[i].GetPosition()) if distance < 0.2 then sward_model_[i].SetActive(true) if sward_root_[i].IsMine == true then sward_model_[i].SetActive(true) sward_is_active_[i] = true vci.state.Set("IS_SWARD_ACTIVE_"..tostring(i), true) end end end end --刺さっている剣の表示状態の更新 function UpdateHits() --所有権持ち以外は共有変数から状態を更新 for i = 1, #hit_ do if barrel_root.IsMine == true then -- else--所有権なし --刺さっている剣 local h = vci.state.Get("IS_HITDONE_"..tostring(i)) if h ~= nil then hitsward_is_active_[i] = h end end --共通、表示処理--nilも考慮 if hitsward_is_active_[i] == true then hitsward_[i].SetActive(true) elseif hitsward_is_active_[i] == false then hitsward_[i].SetActive(false) end end end --衝突判定 function UpdateDistance() --剣ターゲットの範囲に入ったか for i=1,#hit_ do--全刺さり剣インデックス for j=1,#sward_root_ do--全手持ち剣インデックス local distance = Vector3.Distance(sward_root_[j].GetPosition(),hit_[i].GetPosition()) if distance < 0.1 and sward_root_[j].IsMine == true then--自身が所有権持ってる時しかクリアしない if hitsward_is_active_[i] == false then --まだクリアしてない if sward_is_active_[j] == true then--手持ち剣が消えてるときは処理しない --クリアしたときの処理 hitsward_is_active_[i] = true --クリア判定に sward_is_active_[j] = false--手持ち剣フラグオフ sward_model_[j].SetActive(false)--手持ち剣を見えなくする hitsward_[i].SetActive(true)--刺さり剣を表示 vci.state.Set("IS_SWARD_ACTIVE_"..tostring(j), false) vci.state.Set("IS_HITDONE_"..tostring(i), true) sounds_obj[3]._ALL_PlayOneShot(1)--効果音 vci.assets.HapticPulseForceToRightController(3000, 0.1) vci.assets.HapticPulseForceToLeftController(3000, 0.1) hit_effect_[i]._ALL_PlayOneShot() --爆発判定 if bomb_index == i then vci.message.Emit("HUTTOBASEEDSAN2", "bomb")--メッセージ送信 end end end end end end end function UpdateBombIndex() --爆発位置 if barrel_root.IsMine == true then -- else--所有権なし local b = vci.state.Get("HIT_INDEX_BOMB") if b ~= nil then bomb_index = b end end end function Reset() --刺さってる剣の状態リセット if barrel_root.IsMine == true then for i = 1, #hit_ do --刺さっている剣を非表示にする hitsward_[i].SetActive(false)--刺さってる剣を見えなくする hitsward_is_active_[i] = false --未クリア状態に vci.state.Set("IS_HITDONE_"..tostring(i), false) end end --乱数リセット --爆発位置ランダム if barrel_root.IsMine == true then bomb_index = math.random(#hit_) vci.state.Set("HIT_INDEX_BOMB",bomb_index) end --シードさんの位置リセット if bullet_seed.IsMine == true then bullet_seed.SetPosition(ShotPoint.GetPosition()) bullet_seed.SetRotation(ShotPoint.GetRotation()) bullet_seed.SetVelocity(Vector3.__new(0,0,0)) bullet_seed.SetAngularVelocity(Vector3.__new(0,0,0)) end end function BombEvent() --爆発した --メッセージで全員ローカル呼び出し flash_effect.PlayOneShot()------------------------ sounds_obj[1].PlayOneShot(1)--効果音 --弾が飛ぶかどうか if is_bullet_ready == true then --シードさんを飛ばす ShotBulletSEED() end if is_bullet_local_ready == true then ShotBulletLocal() end end function UpdateBullet() --弾丸シードさんが樽に入っているかどうか if bullet_seed.IsMine == true then local distance = Vector3.Distance(bullet_seed.GetPosition(),ShotPoint.GetPosition()) if distance < 0.5 then--範囲内にいる is_bullet_ready = true else is_bullet_ready = false end end end --シードさんを発射する場合 function ShotBulletSEED() se_seedsanpos[1].PlayOneShot(1)--効果音--ローカルで鳴らす --引っかからないようにやや上に移動させてから加速 if bullet_seed.IsMine == true then bullet_seed.SetPosition(ShotPoint.GetPosition()+ShotPoint.GetUp()) --bullet_seed.SetRotation(ShotPoint.GetRotation()) bullet_seed.SetVelocity(ShotPoint.GetUp()) --bullet_seed.SetAngularVelocity(Vector3.__new(0,0,0)) bullet_seed.AddForce(1200*ShotPoint.GetUp()) end end --ローカルアバターが樽に入っているかどうか-------gameAPI function UpdateBulletLocal() --各々ローカルで自分の位置について処理 local distance = Vector3.Distance(player_pos,ShotPoint.GetPosition()) if distance < 0.8 then--範囲内にいる is_bullet_local_ready = true else is_bullet_local_ready = false end end --ローカルアバターを発射する場合 function ShotBulletLocal() playerController.TeleportTo(ShotPoint.GetPosition()+ShotPoint.GetUp(), player_rot) --bullet_seed.SetRotation(ShotPoint.GetRotation()) playerController.SetVelocity(ShotPoint.GetUp()) --bullet_seed.SetAngularVelocity(Vector3.__new(0,0,0)) playerController.AddForce(1200*ShotPoint.GetUp(), vci.forceMode.Impulse) end --自分を弾にする function MyselfBullet() local nowseed_pos = ShotPoint.GetPosition() local nowseed_rot = ShotPoint.GetRotation() local nowlocalavaterpos = localPlayer.GetPosition() local nowlocalavaterrot = localPlayer.GetRotation() --シードさんの移動 if bullet_seed.IsMine == true then bullet_seed.SetPosition(nowlocalavaterpos+ShotPoint.GetUp()) bullet_seed.SetRotation(nowlocalavaterrot) --bullet_seed.SetRotation(ShotPoint.GetRotation()) bullet_seed.SetVelocity(Vector3.__new(0,0,0)) bullet_seed.AddForce(Vector3.__new(0,0,0)) end --ローカルアバターの移動 if button_iambullet.IsMine == true then playerController.TeleportTo(nowseed_pos+ShotPoint.GetUp(), player_rot) end end ---[SubItemの所有権&Use状態]アイテムをグラッブしてグリップボタンを押すと呼ばれる。 ---@param use string @押されたアイテムのSubItem名 function onUse(use) --リセットボタン if use == "button_reset" then vci.message.Emit("HUTTOBASEEDSAN2", "reset")--メッセージ送信 end --当たり位置チェックボタン if use == "button_check" then if bomb_index ~= nil then hit_effect_[bomb_index]._ALL_PlayOneShot() end end --自爆ボタン if use == "button_bomb" then vci.message.Emit("HUTTOBASEEDSAN2", "bomb")--メッセージ送信 end --自分が弾になるボタン if use == "button_iambullet" then vci.message.Emit("HUTTOBASEEDSAN2", "myselfbullet")--メッセージ送信 end end --メッセージが来たら起動-------------------------------------------------------------- function onMessage(sender, name, message) if name == "HUTTOBASEEDSAN2" then if message == "reset" then print("----------------Reset--------------------") Reset() end if message == "bomb" then print("----------------bomb--------------------") BombEvent() end if message == "myselfbullet" then print("----------------myselfbullet--------------------") MyselfBullet() end end end ------------------------------------------------------------------------------------ ---全ユーザーで毎フレーム呼ばれる function updateAll() time_base = vci.me.Time.TotalMilliseconds--現在時間の更新 --ローカルユーザの位置更新 player_pos = localPlayer.GetPosition() player_rot = localPlayer.GetRotation() --初期化処理 if is_firsttimedone == false then is_firsttimedone = true--完了フラグ StartFirsttime() end --所有権持ちのみ --全員呼ばれる UpdateDistance() UpdateSwards() UpdateHits() UpdateBombIndex() UpdateBullet() UpdateBulletLocal()--gameAPI end ---[SubItemの所有権&Grab状態]アイテムをGrabしたときに呼ばれる。 ---@param target string @GrabされたSubItem名 function onGrab(target) local t = string.sub(target,1,11) local i = tonumber(string.sub(target,12)) if t == "sward_root_" then if i ~= nil then sward_is_grab_[i] = true end end end ---[not SubItemの所有権&Grab状態]アイテムをUngrabしたときに呼ばれる。 ---@param target string @UngrabされたSubItem名 function onUngrab(target) local t = string.sub(target,1,11) local i = tonumber(string.sub(target,12)) if t == "sward_root_" then if i ~= nil then sward_is_grab_[i] = false end end end -- vciアイテムのメッセージを受け取る場合 vci.message.On("HUTTOBASEEDSAN2", onMessage)