Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Ray will not go in the direction I want it to. How should I go about fixing it?

I am working on a project and I need to make a gun which shoots to the mouse direction (top down shooter style), the raycasting works... but the direction does not.

local UserInputService = game:GetService("UserInputService")
local Tool = script.Parent
local Mouse = game.Players.LocalPlayer:GetMouse()

function UpdateMouseIcon()
	if Mouse and not Tool.Parent:IsA("Backpack") then
		Mouse.Icon = "rbxasset://textures/GunCursor.png"
	end
end

function OnEquipped()
	ExpectingInput = true
	IsMouseDown = false
	UpdateMouseIcon()
end

function OnUnequipped()
	ExpectingInput = false
	IsMouseDown = false
	UpdateMouseIcon()
end

Tool.Equipped:Connect(OnEquipped)
Tool.Unequipped:Connect(OnUnequipped)

local function showRay(origin, direction)
	local midpoint = origin + direction/2

	local part = Instance.new("Part")
	part.Parent = workspace

	part.Anchored = true
	part.CFrame = CFrame.new(midpoint, origin)
	part.Size = Vector3.new(1,1,direction.magnitude)
	part.CanCollide = false
	return part
end

local function fire()
	local Origin = Vector3.new(Tool.Handle.Position.X, Tool.Handle.Position.Y, Tool.Handle.Position.Z) 
	local Direction = Mouse.Hit.p

	showRay(Origin, Direction)

	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {Tool.Handle.Parent}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local raycastResult = workspace:Raycast(Origin, Direction, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart then
			print(hitPart.Name)
		end
	end
end

UserInputService.InputBegan:Connect(function (input, gameHandledEvent)
	if gameHandledEvent or not ExpectingInput then
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseButton1 and Mouse ~= nil then
		fire()
	end
end)

Video of the issue

Notes: I am using a LocalScript for testing, I do not want to bother with remote events until I get it working. Using Vector3.new(Mouse.Hit.p.X, 0, Mouse.Hit.p.Z) does not change anything

Probably over complicating this, but yeah.

This is what I have currently, but I have tried a few other things, and all of them do the same thing. Any ideas? Examples would be helpful, considering I never do raycasting, this is my first attempt. Thanks!

2 answers

✓ Accepted answer

To calculate RaycastDirection, you do Destination - Origin

local UserInputService = game:GetService("UserInputService")
local Tool = script.Parent
local Mouse = game.Players.LocalPlayer:GetMouse()

function UpdateMouseIcon()
    if Mouse and not Tool.Parent:IsA("Backpack") then
        Mouse.Icon = "rbxasset://textures/GunCursor.png"
    end
end

function OnEquipped()
    ExpectingInput = true
    IsMouseDown = false
    UpdateMouseIcon()
end

function OnUnequipped()
    ExpectingInput = false
    IsMouseDown = false
    UpdateMouseIcon()
end

Tool.Equipped:Connect(OnEquipped)
Tool.Unequipped:Connect(OnUnequipped)

local function showRay(origin, direction)
    local midpoint = origin + direction/2

    local part = Instance.new("Part")
    part.Parent = workspace

    part.Anchored = true
    part.CFrame = CFrame.new(midpoint, origin)
    part.Size = Vector3.new(1,1,direction.magnitude)
    part.CanCollide = false
    return part
end

local function fire()
    local Origin = Vector3.new(Tool.Handle.Position.X, Tool.Handle.Position.Y, Tool.Handle.Position.Z) 
    local Direction = Mouse.Hit.p - Origin

    showRay(Origin, Direction)

    local raycastParams = RaycastParams.new()
    raycastParams.FilterDescendantsInstances = {Tool.Handle.Parent}
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    local raycastResult = workspace:Raycast(Origin, Direction, raycastParams)

    if raycastResult then
        local hitPart = raycastResult.Instance
        if hitPart then
            print(hitPart.Name)
        end
    end
end

UserInputService.InputBegan:Connect(function (input, gameHandledEvent)
    if gameHandledEvent or not ExpectingInput then
        return
    end

    if input.UserInputType == Enum.UserInputType.MouseButton1 and Mouse ~= nil then
        fire()
    end
end)

1 comment

0

In the case of what I am doing, this would not be the solution. The ray needs to travel pretty much exactly straight as its pretty much a 2d, 3d game. This would make it hard for the player to hit the enemy. Would work for other cases though. Might use in the future though.

Solved it: Solution was to make the ray come from the handle's LookVector. Simple solution, don't know how it took so long to get.

local UserInputService = game:GetService("UserInputService")
local Tool = script.Parent
local Mouse = game.Players.LocalPlayer:GetMouse()

function UpdateMouseIcon()
	if Mouse and not Tool.Parent:IsA("Backpack") then
		Mouse.Icon = "rbxasset://textures/GunCursor.png"
	end
end

function OnEquipped()
	ExpectingInput = true
	IsMouseDown = false
	UpdateMouseIcon()
end

function OnUnequipped()
	ExpectingInput = false
	IsMouseDown = false
	UpdateMouseIcon()
end

Tool.Equipped:Connect(OnEquipped)
Tool.Unequipped:Connect(OnUnequipped)

local function showRay(origin, direction)
	local midpoint = origin + direction/2

	local part = Instance.new("Part")
	part.Parent = workspace

	part.Anchored = true
	part.CFrame = CFrame.new(midpoint, origin)
	part.Size = Vector3.new(1,1,direction.magnitude)
	part.CanCollide = false
	return part
end

local function fireLaser()
	-- Set an origin and directional vector
	local Origin = Tool.Handle.Position
	local Direction = Tool.Handle.CFrame.LookVector * 100

	-- Build a "RaycastParams" object and cast the ray
	showRay(Origin, Direction)

	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {Tool.Handle.Parent}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local raycastResult = workspace:Raycast(Origin, Direction, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		-- Check if the part resides in a folder, that it's fully visible, and not locked
		if hitPart then
			print(hitPart.Name)
		end
	end
end

UserInputService.InputBegan:Connect(function (input, gameHandledEvent)
	if gameHandledEvent or not ExpectingInput then
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseButton1 and Mouse ~= nil then
		fireLaser()
	end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.