VRゲームの作成(3)

コントローラーから弾を発射するというプログラムを作成してみます。弾が当たったパーツは消去するという単純なものです。

準備

  1. Workspace に Folder を追加します。
  2. 名前を TouchParts に変更します。
  3. このフォルダの中に、Part を複数個作成します。
  4. Part は空中に浮かせ、AnchoredをONにしてもいいでしょう。(この辺りは自由です)

RemoveEvent の追加

弾はサーバー側で表示移動したいので、クライアントからサーバーのプログラムを実行する RemoteEvent を使います。

  1. ReplicatedStorage に RemoteEvent を追加します。
  2. 名前を ShootEvent に変更します。

サーバー側のプログラム

クライアントから RemoteEvent で呼ばれるイベントです。球体のパーツ(弾)を作成し、LinearVelocity を使って移動させます。

  1. ServerScriptService に Script を追加します。
  2. 名前を EventScript に変更します。
  3. 以下のプログラムを入力します。
local Debris = game:GetService("Debris")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local changePartEvent = ReplicatedStorage.ChangePartEvent
local shootEvent = ReplicatedStorage.ShootEvent

shootEvent.OnServerEvent:Connect(function(player,cframe,velocity)
    local part = Instance.new("Part",workspace)
    part.Material = Enum.Material.Neon
    part.Shape = Enum.PartType.Ball
    part.CFrame = cframe
    part.Size = Vector3.new(1,1,1)
    part.BrickColor = BrickColor.new("White")
    part.Material = Enum.Material.Neon
    part.CanCollide = false

    local attachment = Instance.new("Attachment", part)
    local linearVelocity = Instance.new("LinearVelocity", attachment)
    linearVelocity.Attachment0 = attachment
    linearVelocity.VectorVelocity = velocity
    linearVelocity.MaxForce = math.huge

    part.Touched:Connect(function(hit)
        if hit.Parent.Name == "TouchParts" then
            hit:Destroy()    -- 当たったパーツを消す
            part:Destroy()   -- 弾を消す
        end
    end)
    Debris:AddItem(part,2)
end)

クライアント側のプログラム

  1. StarterPlayer の StarterPlayerScripts に LocalScript を追加します。
  2. 名前を VRgun とします。
  3. 以下のプログラムを入力します。
local VRService = game:GetService("VRService")
local HapticService = game:GetService("HapticService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local mouse = Players.LocalPlayer:GetMouse()

local rightHand

local function onInputBegan(input, processed)
    if input.KeyCode == Enum.KeyCode.ButtonR2 then
        local position = mouse.Hit.Position
        local velocity = (position - rightHand.Position).Unit * 300
        local handOffset = rightHand.Rotation + rightHand.Position * workspace.CurrentCamera.HeadScale
        local cframe = workspace.CurrentCamera.CFrame * handOffset
        ReplicatedStorage.ShootEvent:FireServer(cframe,velocity)  -- RemoteEvent の実行
    end
end

local function track(Type, Value)
    if Type == Enum.UserCFrame.RightHand then
        rightHand = VRService:GetUserCFrame(Enum.UserCFrame.RightHand)
    end
end

UserInputService.InputBegan:Connect(onInputBegan)
VRService.UserCFrameChanged:Connect(track)

コメントを残す