'Beam' does not go in the direction I want it to?

I’ve been working on a fishing system. When a player clicks, it casts the line to where the mouse was clicked. The issue is the casted ray goes to the other direction instead of where the mouse clicks. Here is photo of what happens

Photo


Video on what happens
https://i.imgur.com/82OkuLo.mp4

As you can see, the white translucent ‘string’ that appears follows the green line instead of what I expected, which was the yellow line. The yellow line is the direction and position of where it is supposed to go when water is clicked.

How would I go about to make it so that it would go in the direction of the mouse and not some other direction?

Current code:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character
local head = character:FindFirstChild("Head")
local humanoid = character:WaitForChild("Humanoid")

local animWield = script.Parent.Animation
local wieldRod = humanoid:LoadAnimation(animWield)

local animThrow = script.Parent.Animation2
local throwRod = humanoid:LoadAnimation(animThrow)

local animIdle = script.Parent.Animation3
local idleRod = humanoid:LoadAnimation(animIdle)

local animReel = script.Parent.Animation4
local reedRod = humanoid:LoadAnimation(animReel)

local isFishing = false
local caught = false
local count = 0
local waitBeforeReel = false
local topPart = script.Parent.Top

rodRay = Ray.new(topPart.Position + Vector3.new(0, 10, 0), Vector3.new(0,-10,0)*100)
stringRay = Ray.new(topPart.CFrame.p, (mouse.Hit.p -topPart.CFrame.p).unit * 300)

local part, position = workspace:FindPartOnRay(stringRay, player.Character, true, false)
local objecthit, hitposition, normal, material = workspace:FindPartOnRay(rodRay, topPart, true,false)

function createString()
	stringPart = Instance.new("Part")
	--properties
	stringPart.Name = "StringPart"
	stringPart.BrickColor = BrickColor.new("White")
	stringPart.FormFactor = "Custom"
	stringPart.Material = "SmoothPlastic"
	stringPart.Transparency = 0.5
	stringPart.Anchored = true
	stringPart.Locked = true
	stringPart.CanCollide = false
	stringPart.Parent = workspace
	--calculate length of the part
	local distance = (topPart.CFrame.p - position).magnitude
	stringPart.Size = Vector3.new(0.3, 0.3, distance)
	stringPart.CFrame = CFrame.new(topPart.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)

end

script.Parent.Activated:Connect(function()
	if objecthit.Name == "Terrain"  and isFishing == false and count == 0 then --checks if the clicked area was a terrain region
		waitBeforeReel = true --prevents the player from reeling
			print("water")
			count = 1
			isFishing = true
			game.ReplicatedStorage.changeStats:FireServer(0,humanoid.WalkSpeed)
			wieldRod:Stop()
			throwRod:Play()
			wait(1)
			createString()
			idleRod:Play()
            humanoid.WalkSpeed = 12
			print("caged")
			local timing = math.random(10,90) --timing before the fish comes
			print(tostring(timing))
			wait(5)
			waitBeforeReel = false --allowing the reel anytime(if player wants to quit)
			wait(timing)
			print("fishing...")
			--planning to write some function here later
	end
				if isFishing == true and count == 1 and caught == false and waitBeforeReel == false then --if the player wants to quit fishing
				idleRod:Stop()
				wait(0.1)
				reedRod:Play()
				wait(2)
				wieldRod:Play()
				isFishing = false
				count = 0
				humanoid.WalkSpeed = 12
				workspace:FindFirstChild("StringPart"):Destroy() --destroys the 'beam'
				end
				
end)
2 Likes

Try with this:

stringRay = Ray.new(topPart.CFrame.p, (mouse.Hit.p - topPart.CFrame.p).unit * 10) 
local part, position = workspace:FindPartOnRay(stringRay, player.Character, false, false)

else try this:

stringRay = Ray.new(topPart.CFrame.p, (mouse.Hit.p - topPart.CFrame.p).unit * 10) 
local part, position = workspace:FindPartOnRay(stringRay, player.Character, false, true)
1 Like

You’re defining and reusing multiple variables from outside of your functions, so they’re never refreshed.

rodRay = Ray.new(topPart.Position + Vector3.new(0, 10, 0), Vector3.new(0,-10,0)*100)
stringRay = Ray.new(topPart.CFrame.p, (mouse.Hit.p -topPart.CFrame.p).unit * 300)

local part, position = workspace:FindPartOnRay(stringRay, player.Character, true, false)
local objecthit, hitposition, normal, material = workspace:FindPartOnRay(rodRay, topPart, true,false)

should go inside the function as so:

function createString()
	rodRay = Ray.new(topPart.Position + Vector3.new(0, 10, 0), Vector3.new(0,-10,0)*100)
	stringRay = Ray.new(topPart.CFrame.p, (mouse.Hit.p -topPart.CFrame.p).unit * 300)
	local part, position = workspace:FindPartOnRay(stringRay, player.Character, true, false)
	local objecthit, hitposition, normal, material = workspace:FindPartOnRay(rodRay, topPart, true,false)
	stringPart = Instance.new("Part")
	--properties
	stringPart.Name = "StringPart"
	stringPart.BrickColor = BrickColor.new("White")
	stringPart.FormFactor = "Custom"
	stringPart.Material = "SmoothPlastic"
	stringPart.Transparency = 0.5
	stringPart.Anchored = true
	stringPart.Locked = true
	stringPart.CanCollide = false
	stringPart.Parent = workspace
	--calculate length of the part
	local distance = (topPart.CFrame.p - position).magnitude
	stringPart.Size = Vector3.new(0.3, 0.3, distance)
	stringPart.CFrame = CFrame.new(topPart.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)
end

Let me know if this works!

5 Likes

I made it work after shifting a little here and there. I do have a question though, how would I make it so that it only works in Terrain Water and not any other terrain material

I’ve tried using Enum.Material.Water but it doesn’t seem to detect well. All it detects is ‘Grass’

3 Likes

Update on situation

So right now I got everything set up correctly for the beam. I was working on the RNG for the fishes and ‘Quit Fishing’ button so if the player is too bored he won’t be stuck there. The issue is if the player has quitted ‘Fishing Mode’, he will not be able to cast the line again and it would just be mindless clicking.

Updated casting code as of now:

script.Parent.Activated:Connect(function() --cast line
	local objecthit, hitposition, normal, material = workspace:FindPartOnRay(rodRay, topPart, true,false)
	if objecthit.Name == "Terrain"  and isFishing == false and count == 0 then
		humanoid.WalkSpeed = 0
		print(material)
		waitBeforeReel = true
			count = 1
			isFishing = true
			wieldRod:Stop()
			throwRod:Play()
			idleRod:Play()
			wait(0.2)
			createString()
			script.Parent.water_splash:Play()
			humanoid.WalkSpeed = 0
			wait(5)
			waitBeforeReel = false
			exitGUI.Parent = playerGui
			game.ReplicatedStorage.changeStats:FireServer(idleRod,wieldRod,count,isFishing)
			repeat RNGFish() until caught == true -- repeats the function UNTIL output prints that the player successfully 'caught' a fish
			if caught == true then --therefore, if the player 'catches' a fish,
				selectFish() -- player's caught fish RNG function
			end
			end
end)
2 Likes