Make a gun for VR usages

Hello!

So I am creating a VR shooter and I was wondering if there was any way to fix this.

I want the gun to start working when it is held (In VR). The way I will do this is by setting a BoolValue inside the gun to true whenever it is being held. Then, when the right trigger (Oculus) is pushed down, a script checks if the value is True, then it runs the firing code.

For testing purposes, I am using the Classic Hyperlaser code. However I have my own for later use.

Main script
Tool = script.Parent
Handle = Tool:WaitForChild("Handle")

Players = game:GetService("Players")
Debris = game:GetService("Debris")

Speed = 1000
Duration = 7

NozzleOffset = Vector3.new(0, 0.4, -1.1)

Sounds = {
	Fire = Handle:WaitForChild("Fire"),
	Reload = Handle:WaitForChild("Reload"),
	HitFade = Handle:WaitForChild("HitFade")
}

PointLight = Handle:WaitForChild("PointLight")

ServerControl = (Tool:FindFirstChild("ServerControl") or Instance.new("RemoteFunction"))
ServerControl.Name = "ServerControl"
ServerControl.Parent = Tool

ClientControl = (Tool:FindFirstChild("ClientControl") or Instance.new("RemoteFunction"))
ClientControl.Name = "ClientControl"
ClientControl.Parent = Tool

ServerControl.OnServerInvoke = (function(player, Mode, Value, arg)
    if player ~= Player or Humanoid.Health == 0 or not Tool.Enabled then --What if I replace "Tool.Enabled" with the BoolValue Value?
	    return
	end
	if Mode == "Click" and Value then
	    Activated(arg)
    end
end)

function InvokeClient(Mode, Value)
	pcall(function()
		ClientControl:InvokeClient(Player, Mode, Value)
	end)
end

function TagHumanoid(humanoid, player)
	local Creator_Tag = Instance.new("ObjectValue")
	Creator_Tag.Name = "creator"
	Creator_Tag.Value = player
	Debris:AddItem(Creator_Tag, 2)
	Creator_Tag.Parent = humanoid
end

function UntagHumanoid(humanoid)
	for i, v in pairs(humanoid:GetChildren()) do
		if v:IsA("ObjectValue") and v.Name == "creator" then
			v:Destroy()
		end
	end
end

function FindCharacterAncestor(Parent)
	if Parent and Parent ~= game:GetService("Workspace") then
		local humanoid = Parent:FindFirstChild("Humanoid")
		if humanoid then
			return Parent, humanoid
		else
			return FindCharacterAncestor(Parent.Parent)
		end
	end
	return nil
end

function GetTransparentsRecursive(Parent, PartsTable)
	local PartsTable = (PartsTable or {})
	for i, v in pairs(Parent:GetChildren()) do
		local TransparencyExists = false
		pcall(function()
			local Transparency = v["Transparency"]
			if Transparency then
				TransparencyExists = true
			end
		end)
		if TransparencyExists then
			table.insert(PartsTable, v)
		end
		GetTransparentsRecursive(v, PartsTable)
	end
	return PartsTable
end

function SelectionBoxify(Object)
	local SelectionBox = Instance.new("SelectionBox")
	SelectionBox.Transparency = 1
	SelectionBox.Adornee = Object
	SelectionBox.Color = BrickColor.new("Toothpaste")
	SelectionBox.Parent = Object
	return SelectionBox
end

local function Light(Object)
	local Light = PointLight:Clone()
	Light.Range = (Light.Range + 2)
	Light.Parent = Object
end

function FadeOutObjects(Objects, FadeIncrement)
	repeat
		local LastObject = nil
		for i, v in pairs(Objects) do
			v.Transparency = (v.Transparency + FadeIncrement)
			LastObject = v
		end
		wait()
	until LastObject.Transparency >= 1 or not LastObject
end

function Dematerialize(character, humanoid, FirstPart)
	if not character or not humanoid then
		return
	end

	humanoid.WalkSpeed = 0

	local Parts = {}

	for i, v in pairs(character:GetChildren()) do
    	if v:IsA("BasePart") then
			v.Anchored = true
			table.insert(Parts, v)
		elseif v:IsA("LocalScript") or v:IsA("Script") then
			v:Destroy()
		end
	end

	local SelectionBoxes = {}

	local FirstSelectionBox = SelectionBoxify(FirstPart)
	Light(FirstPart)
	wait(0.05)

	for i, v in pairs(Parts) do
		if v ~= FirstPart then
			table.insert(SelectionBoxes, SelectionBoxify(v))
			Light(v)
		end
	end

	local ObjectsWithTransparency = GetTransparentsRecursive(character)
	FadeOutObjects(ObjectsWithTransparency, 0.1)

	wait(0.5)

	character:BreakJoints()
	humanoid.Health = 0

	Debris:AddItem(character, 2)

	local FadeIncrement = 0.05
	Delay(0.2, function()
		FadeOutObjects({FirstSelectionBox}, FadeIncrement)
		if character and character.Parent then
			character:Destroy()
		end
	end)
	FadeOutObjects(SelectionBoxes, FadeIncrement)
end

function Touched(Projectile, Hit)
	if not Hit or not Hit.Parent then
		return
	end
	local character, humanoid = FindCharacterAncestor(Hit)
	if character and humanoid and character ~= Character then
		local ForceFieldExists = false
		for i, v in pairs(character:GetChildren()) do
			if v:IsA("ForceField") then
				ForceFieldExists = true
    		end
    	end
    	if not ForceFieldExists then
			if Projectile then
    			local HitFadeSound = Projectile:FindFirstChild(Sounds.HitFade.Name)
				local torso = humanoid.Torso
				if HitFadeSound and torso then
					HitFadeSound.Parent = torso
					HitFadeSound:Play()
				end
			end
			Dematerialize(character, humanoid, Hit)
		end
		if Projectile and Projectile.Parent then
			Projectile:Destroy()
		end
	end
end

function Equipped()
	Character = Tool.Parent
	Player = Players:GetPlayerFromCharacter(Character)
	Humanoid = Character:FindFirstChild("Humanoid")
	if not Player or not Humanoid or Humanoid.Health == 0 then
		return
	end
end

function Activated(target)
	if Tool.Enabled and Humanoid.Health > 0 then
    	Tool.Enabled = false

    	InvokeClient("PlaySound", Sounds.Fire)

	local HandleCFrame = Handle.CFrame
	local FiringPoint = HandleCFrame.p + HandleCFrame:vectorToWorldSpace(NozzleOffset)
	local ShotCFrame = CFrame.new(FiringPoint, target)

	local LaserShotClone = BaseShot:Clone()
	LaserShotClone.CFrame = ShotCFrame + (ShotCFrame.lookVector * (BaseShot.Size.Z / 2))
	local BodyVelocity = Instance.new("BodyVelocity")
	BodyVelocity.velocity = ShotCFrame.lookVector * Speed
	BodyVelocity.Parent = LaserShotClone
	LaserShotClone.Touched:connect(function(Hit)
		if not Hit or not Hit.Parent then
			return
		end
		Touched(LaserShotClone, Hit)
	end)
	Debris:AddItem(LaserShotClone, Duration)
	LaserShotClone.Parent = game:GetService("Workspace")

	wait(0.6) -- FireSound length

	InvokeClient("PlaySound", Sounds.Reload)
	
	wait(0.75) -- ReloadSound length

	Tool.Enabled = true
end
end

function Unequipped()

end

BaseShot = Instance.new("Part")
BaseShot.Name = "Effect"
BaseShot.BrickColor = BrickColor.new("Toothpaste")
BaseShot.Material = Enum.Material.Plastic
BaseShot.Shape = Enum.PartType.Block
BaseShot.TopSurface = Enum.SurfaceType.Smooth
BaseShot.BottomSurface = Enum.SurfaceType.Smooth
BaseShot.FormFactor = Enum.FormFactor.Custom
BaseShot.Size = Vector3.new(0.01, 0.01, 3)
BaseShot.CanCollide = false
BaseShot.Locked = true
SelectionBoxify(BaseShot)
Light(BaseShot)`
ToolScript
Tool = script.Parent

Handle = Tool:WaitForChild("Handle")
Players = game:GetService("Players")

ServerControl = Tool:WaitForChild("ServerControl")
ClientControl = Tool:WaitForChild("ClientControl")

ClientControl.OnClientInvoke = (function(Mode, Value)
    if Mode == "PlaySound" and Value then
        Value:Play()
    end
end)

function InvokeServer(Mode, Value, arg)
    pcall(function()
        ServerControl:InvokeServer(Mode, Value, arg)
    end)
end

function Equipped(Mouse)
    Character = Tool.Parent
    Player = Players:GetPlayerFromCharacter(Character)
    Humanoid = Character:FindFirstChild("Humanoid")
    if not Player or not Humanoid or Humanoid.Health == 0 then
        return
    end

Mouse.Button1Down:connect(function()
    InvokeServer("Click", true, Mouse.Hit.p)
    end)
end

local function Unequipped()

end

Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)
Explorer Screenshot

Annotation 2020-08-01 140848

Well actually, I want it so that when the gun is physically held (like, in VR).

I am going to set up a script that detects when the gun is “held” in VR and will set the BoolValue to true.

As for the New Topic question:

First, click here:

then from that page, there will be this button:

click that and create your draft!

(Make sure you are scrolled all the way up the page)

Thanks a lot. I’m new to devforum. As for your question idk if there is a way to sense stuff on VR. If there is it’s probably a built-in function. Thanks for the help!

1 Like

That could be the problem from the looks of it if a bool value is set locally then it can not be read from the server.

Looking at the code it looks like you are using mouse.button1down, to get when the r2 is held do something similar to.

Input = game:GetService("InputService")

Input.OnInputEnded:Connect(function(io)
    if io.Keycode == Enum.Keycode.R2 then
        -- Trigger
    end
end)
2 Likes

Yeah. I do understand that!

In my vr handler, two spheres are your hands. If the spheres come into contact with a part that is able to be carried AND the r1 (or l1) button is pressed, the part’s network owner is set to the player and it is “welded” to the sphere until the r1 or l1 button is unpressed.

What I want to know is, is there any way to make a script activate and set a boolValue to true when the r1 or l1 button is pressed on a part. When that happens, it allows the r2 trigger to activate the gun.

I want to do this so the gun doesn’t fire when it is not being held.

Yea there is, as long as it’s not being read from the server then you can set it via a .touched:connect() event.

What I recommend is using an object value to set the weapons model once it is welded so it know what weapon to shoot.

2 Likes

Thanks for helping me out. I’ll try that when I can.