====== Beat saber-ish game ====== === Example data === https://virtualcast.jp/products/2e733969d3ecdd31feb5e06c876470c440e77922c5b2d1b050609f811ac2761d local scene = 0 -- 0:ready 1:game 2:end local HIDE_POSITION = Vector3.__new(-1000,-1000,-1000) -- ready local BtnStart = vci.assets.GetTransform("BtnStart") local Title = vci.assets.GetTransform("Title") local BtnStartPos = BtnStart.GetLocalPosition() local TitlePos = Title.GetLocalPosition() -- end local BtnTitle = vci.assets.GetTransform("BtnTitle") local Result = vci.assets.GetTransform("Result") local saber_numbers_100 = vci.assets.GetTransform("saber_numbers_100") local saber_numbers_10 = vci.assets.GetTransform("saber_numbers_10") local saber_numbers_1 = vci.assets.GetTransform("saber_numbers_1") local saber_numbers_percent = vci.assets.GetTransform("saber_numbers_percent") local BtnTitlePos = BtnTitle.GetLocalPosition() local ResultPos = Result.GetLocalPosition() local saber_numbers_100Pos = saber_numbers_100.GetLocalPosition() local saber_numbers_10Pos = saber_numbers_10.GetLocalPosition() local saber_numbers_1Pos = saber_numbers_1.GetLocalPosition() local saber_numbers_percentPos = saber_numbers_percent.GetLocalPosition() -- game local saber = vci.assets.GetTransform("saber") local notes = {} local current_note = 0 local current_stage_note_index = 1 --index of stage_note currently showing local show_notes = {} local notesDieList = {} local notesColorAlphaList = {} local score = 0 local noteTimer = vci.me.Time.TotalSeconds for i = 1,9 do notes[i] = vci.assets.GetTransform("note"..tostring(i)) notesDieList[i] = 0 notesColorAlphaList[i] = 1 end local green = Color.__new(0,1,0,0.5) local red = Color.__new(1,0,0,0.5) local invisible = Color.__new(0,0,0,0) local noteAppearPos = Vector3.__new(0,2,30) local noteAppearPosList = {} noteAppearPosList[1] = Vector3.__new(-0.5,0,0) noteAppearPosList[2] = Vector3.__new(0,0,0) noteAppearPosList[3] = Vector3.__new(0.5,0,0) local noteSpeed = Vector3.__new(0,0,-0.1) -- List of time spans to the next note (second) local stage1_notes = { 1, 1, 0.5, 1, 1, 1.5, 1.5, 0.5, 0.5, 0.5, 1.5, 1.5, 0.5, 0.5, 0.5, 1.5, 1.5, 0.5, 0.5, 0.5, 1.5, 1.5, 0.5, 0.5, 0.5 } local current_notes = {} current_notes = {unpack(stage1_notes)} -- Hide the objects of specified scene number function hideSceneObject(sceneNumber) if sceneNumber == 0 then -- 0:ready BtnStart.SetLocalPosition(HIDE_POSITION) Title.SetLocalPosition(HIDE_POSITION) elseif sceneNumber == 1 then -- 1:game for i = 1,9 do vci.assets.GetTransform("note"..tostring(i)).SetLocalPosition(noteAppearPos + noteAppearPosList[math.random(1,3)]) vci.assets._ALL_SetMaterialColorFromName("note"..tostring(i), invisible) end elseif sceneNumber == 2 then -- 2:end BtnTitle.SetLocalPosition(HIDE_POSITION) Result.SetLocalPosition(HIDE_POSITION) saber_numbers_100.SetLocalPosition(HIDE_POSITION) saber_numbers_10.SetLocalPosition(HIDE_POSITION) saber_numbers_1.SetLocalPosition(HIDE_POSITION) saber_numbers_percent.SetLocalPosition(HIDE_POSITION) end end -- Change textures function SetTextureOffset( _count, _materialName ) local offset = Vector2.zero -- y shift local Yshift = math.floor(_count / 4) offset.y = -(1/4) * Yshift -- x shift local Xshift = _count % 4 offset.x = (1/4) * Xshift vci.assets._ALL_SetMaterialTextureOffsetFromName(_materialName, offset) end -- Score setup function setupScore( _score ) if _score >= 100 then SetTextureOffset(1, "saber_numbers_100") SetTextureOffset(0, "saber_numbers_10") SetTextureOffset(0, "saber_numbers_1") elseif _score >= 10 then SetTextureOffset(15, "saber_numbers_100") local str10 = string.sub(tostring(_score), 1,1) SetTextureOffset(tonumber(str10), "saber_numbers_10") local str1 = string.sub(tostring(_score), 2) SetTextureOffset(tonumber(str1), "saber_numbers_1") else local str1 = string.sub(tostring(_score), 1) SetTextureOffset(15, "saber_numbers_100") SetTextureOffset(15, "saber_numbers_10") SetTextureOffset(tonumber(str1), "saber_numbers_1") end SetTextureOffset(10, "saber_numbers_percent") end -- Scene setup function setupScene( sceneNumber ) if sceneNumber == 0 then -- 0:ready hideSceneObject( 1 ) hideSceneObject( 2 ) BtnStart.SetLocalPosition(BtnStartPos) Title.SetLocalPosition(TitlePos) elseif sceneNumber == 1 then -- 1:game score = 0 current_notes = {unpack(stage1_notes)} current_stage_note_index = 1 hideSceneObject( 0 ) hideSceneObject( 2 ) elseif sceneNumber == 2 then -- 2:end hideSceneObject( 0 ) hideSceneObject( 1 ) local resultScore = math.floor(score / #current_notes * 100) print("resultScore is "..tostring(resultScore)) setupScore(resultScore) BtnTitle.SetLocalPosition(BtnTitlePos) Result.SetLocalPosition(ResultPos) saber_numbers_100.SetLocalPosition(saber_numbers_100Pos) saber_numbers_10.SetLocalPosition(saber_numbers_10Pos) saber_numbers_1.SetLocalPosition(saber_numbers_1Pos) saber_numbers_percent.SetLocalPosition(saber_numbers_percentPos) end scene = sceneNumber end function updateAll() if scene == 1 then if current_stage_note_index <= #current_notes then if vci.me.Time.TotalSeconds - noteTimer > current_notes[current_stage_note_index] then --print(current_stage_note_index) noteTimer = vci.me.Time.TotalSeconds -- refresh noteTimer -- if current_note < 9 then current_note = current_note + 1 else current_note = 1 end table.insert(show_notes, current_note) -- add to the end of show_notes -- local noteLength = #show_notes notes[show_notes[noteLength]].SetLocalPosition(noteAppearPos + noteAppearPosList[math.random(1,3)]) vci.assets._ALL_SetMaterialColorFromName("note"..tostring(show_notes[noteLength]), green) -- current_stage_note_index = current_stage_note_index + 1 end end if #show_notes > 0 then for key, value in pairs(show_notes) do if notesDieList[value] < 1 then notes[value].SetLocalPosition(notes[value].GetLocalPosition() + noteSpeed) else -- Cut notesColorAlphaList[value] = notesColorAlphaList[value] - 0.05 if notesColorAlphaList[value] > 0 then -- Fade-out processing after being cut local color = red * Color.__new(1,1,1,notesColorAlphaList[value]) vci.assets._ALL_SetMaterialColorFromName("note"..tostring(value), color) else -- Rest notes[value].SetLocalPosition(noteAppearPos + noteAppearPosList[math.random(1,3)]) vci.assets._ALL_SetMaterialColorFromName("note"..tostring(value), invisible) notesColorAlphaList[value] = 1 notesDieList[value] = 0 -- Remove from show_notes table.remove(show_notes, key) -- add to the end of show_notes if #show_notes == 0 then setupScene(2) end end end if notes[value].GetLocalPosition().z <= -3 then -- Reset missed notes notes[value].SetLocalPosition(noteAppearPos + noteAppearPosList[math.random(1,3)]) vci.assets._ALL_SetMaterialColorFromName("note"..tostring(value), invisible) -- Remove from show_notes table.remove(show_notes, key) -- add to the end of show_notes if #show_notes == 0 then setupScene(2) end end end end end end function onTriggerEnter(item,hit) -- ready if item == "saber" and hit == "BtnStart" then setupScene(1) end -- game for i = 1,9 do local note_name = "note"..tostring(i) if item == "saber" and hit == note_name then -- Cut score = score + 1 --print("score is "..tostring(score)) notesDieList[i] = 1 vci.assets._ALL_SetMaterialColorFromName(note_name, red) -- Play sound vci.assets._ALL_PlayAudioFromName("shot-struck1") end end -- end if item == "saber" and hit == "BtnTitle" then setupScene(0) end end setupScene(0)