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

How do i make this raycast to cast in the right direction? [UPDATE]

Hello. So i'm new to raycasting, and i'm having a problem with it. You see, i have an AI and i want him to jump if there's a part in front of him. And i would like to use raycasting. Though i'm not really sure on how do i make a ray that starts somewhere near the torso and ends somewhere in front of the torso. Kinda of like this photo: http://prnt.sc/8llfmp

Though i wasn't successful. The ray wasn't appearing in the front of the torso.

Here's what i got:

local rayStart = script.Parent.Torso.Position - Vector3.new(0,3,0)
local rayLook = rayStart+script.Parent.Torso.CFrame.lookVector
local ray, pos = Ray.new(rayStart,(rayLook-rayStart).unit)
local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)

UPDATE: In my script, i created a part that's welded on the character and positioned on the position i wanted. With that, i could shoot the ray without making some bizarre math. Though, i have testing your answers and for some reason the ray is being casted from the part and it goes to the center of the world. I have checked if the part is in the right position and it is and it's also rotated in the correct rotation. Help?

Entire script (Raycasting line: 66):

-------------
--Variables--
-------------

local TC = script.Parent.Configuration.TeamColor.Value
local humanoid = script.Parent.Humanoid
local Pathfinding = game:GetService("PathfindingService")
local target = script.Parent.Target
local torso = script.Parent.Torso

---------------------
--Instance Creation--
---------------------

local rayPart = Instance.new("Part",script.Parent)
rayPart.Transparency = 1
rayPart.Size = Vector3.new(1,1,1)
rayPart.Position = Vector3.new(torso.Position.X,torso.Position.Y-2,torso.Position.Z+1)
rayPart.CanCollide = false
rayPart.Rotation = torso.Rotation
local weld = Instance.new("Weld")
weld.Part0 = torso
weld.Part1 = rayPart
weld.C0 =  CFrame.new()
weld.C1 = rayPart.CFrame:inverse() * torso.CFrame
weld.Parent = torso

-------------
--Functions--
-------------

--Move to Spawn Points
function MoveToSpawnPoint(s)
	--Creates variables and path
	local PF = Pathfinding:ComputeSmoothPathAsync(script.Parent.Torso.Position,s.Position,512)
	local points = PF:GetPointCoordinates()
	
	--visualizePath(points)	
	
	--Moves through the path
	local distance;
	local br = false
	for i = 1,#points do
		wait(0)
		
		--Breakes to:
		--Recreate the path or;
		--To move to an enemy if exists
		if br or target.Value ~= nil then break end
		
		--Move to the created points
		local count = 0
		repeat
			--Turns br(break) to true if needed
			count=count+1
			if count>20 or target.Value ~= nil then
				br = true
				break
			end
			--Move through the path
			if script.Parent == nil or script.Parent:FindFirstChild("Torso") == nil then
				return
			end
			humanoid:MoveTo(points[math.min(#points,i+1)],nil)
					
			local start = rayPart.Position
			local finish = (start-rayPart.CFrame.lookVector).unit*15
			local ray = Ray.new(start,finish)
			local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)
			
			local beam = Instance.new("Part", workspace)
			beam.BrickColor = BrickColor.new("Bright red")
			beam.FormFactor = "Custom"
			beam.Material = "Neon"
			beam.Transparency = 0.25
			beam.Anchored = true
			beam.Locked = true
			beam.CanCollide = false
	 
			local distance = (start - finish).magnitude
			beam.Size = Vector3.new(0.3, 0.3, distance)
			beam.CFrame = CFrame.new(start, finish) * CFrame.new(0, 0, -distance / 2)
		
			if points[i].Y>script.Parent.Torso.Position.Y+2.5 or partOnRay~=nil then
				humanoid.Jump = true
			end
			
			distance=(points[i]*Vector3.new(1,0,1)-script.Parent.Torso.Position*Vector3.new(1,0,1)).magnitude
			wait()
		until distance<5
	end
end

--Move to Enemy
function MoveToEnemy()
	if target.Value == nil then return end
	
	if (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude >=10 then
		--Creates variables and path
		local PF = Pathfinding:ComputeRawPathAsync(script.Parent.Torso.Position,target.Value.Torso.Position,50)
		local points = PF:GetPointCoordinates()
		local distance;
		local br = false
		
		--Move through path
		for i = 1,#points do
			wait(0)
			--Breakes to:
			--Recreate the path; 
			--Move to a spawnpoint when the target doesn't exist or;
			--Move to the enemy without pathfinding
			if br or target.Value == nil then break end
			
			--Move to created points
			local count = 0
			repeat
				--Turns br(break) to true if needed
				count=count+1
				if target.Value == nil then 
					br = true
					break
				end
				if count>20 or (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude <10 then
					br = true
					break
				end
				
				--Move through the path
				humanoid:MoveTo(points[math.min(#points,i+1)],nil)
				if script.Parent == nil or script.Parent:FindFirstChild("Torso") == nil then
					return
				end
				if points[i].Y>script.Parent.Torso.Position.Y+2.5 then
					humanoid.Jump = true
				end
				
				distance=(points[i]*Vector3.new(1,0,1)-script.Parent.Torso.Position*Vector3.new(1,0,1)).magnitude
				wait()
			until distance<5 
		end
	end
	--Move to the enemy without pathfinding if he's close
	if target.Value ~= nil then
		if (script.Parent.Torso.Position-target.Value.Torso.Position).magnitude <10 and target.Value.Humanoid.Health>0 then
			humanoid:MoveTo(target.Value.Torso.Position)
		end
	end
end

-------------
--Task Area--
-------------

while wait(0) do
	--Move to target if it exists
	if script.Parent.Target.Value then
		MoveToEnemy()
	--If theres not any enemy close, then go to the spawn points
	elseif script.Parent.Target.Value == nil and script.Parent.Spawn.Value ~= nil then
		MoveToSpawnPoint(script.Parent.Spawn.Value)
	end
end

3 answers

You're firing a ray below the AI, try firing it in the direction of the torso's lookvector, which is the direction it's facing.

script.Parent:WaitForChild("Torso") --Make sure it works on server mode
while wait() do --A loop
	local rayStart = Ray.new( --A new ray
		script.Parent.Torso.Position, --Orifin
		script.Parent.Torso.CFrame.lookVector*15 --Direction
	)

	local hit,position,normal = game.Workspace:FindPartOnRay(rayStart,script.Parent) --The second paremeter tells it to ignore the AI
	if hit then --if hit isn't nil
		print("The AI has seen an object...") inform the user the AI has seen an object
		if (position - script.Parent.Torso.Position).magnitude <7 then --If the magnitude is low
			print("The AI is close to an object") --inform the user the AI is close
			return --End the function
		end
	end
end

You didn't really offer much code but I can give you some references: Raycasting Magnitude While loop

8 comments

0

That photo is the way i wanted my ray to be like. Though i used the script and the ray starts at the AI and goes to the center of the world

0

Elaborate?

0

http://prnt.sc/8llfmp. I want my ray to look like this (Without the part. Thats were i want my ray to start and to finish).

0

I don't know what that means but if you want it to go to the center then make the direction Vector3.new(0,0,0)

0

NO. See that gray part. Thats what i want my RAY to START and FINISH.

0

@Drahsid5 The main problem with this is that you've mistaken the return value of lookVector. Subtracting the torso's position is irrelevant once you have the direction the torso is facing. With this code, you're essentially basing the direction of the ray on its position from the origin, which doesn't really fit the context.

0

@Legojoker did I? Maybe I'm too used to using m.hit

0

Try out my new code

local tors = script.Parent:WaitForChild("Torso")

-- Make sure the torso in the AI model is rotated to have the front synchronize with the front of the model.

while true do
	wait(1)
	local testRay = Ray.new(tors.Position, tors.CFrame.lookVector*3) -- Change the 3 to your preferred checking distance.
	local potObj, potPosi = game.Workspace:FindPartOnRay(testRay, script.Parent)
	
	if potObj then
		print("AI is "..(potPosi-tors.Position).magnitude.." studs away from an obstacle.")
	end
end

Make sure your model is oriented correctly, this is the most IMPORTANT aspect since lookVector shoots out from the FRONT face of your model. You can use trigonometry to offset the lookVector, but it shouldn't be necessary for your purposes.

The first argument of Ray.new() is the original position, or the position that the ray is being casted from. The second one is the unit vector that it is being directed towards, multiplied by the number of studs you want it to look. lookVector gives you a unit vector automatically (very convenient) so you can use this, multiply it by your checking distance (I chose 3 studs), and then search for an object and the position of ray disturbance. potPosi is the point the ray made contact with the object, not the potObj's actual position.

I figured it out!

local start = rayPart.Position
local finish = (rayPart.CFrame.lookVector).unit*3
local ray = Ray.new(start,finish)
local partOnRay = game.Workspace:FindPartOnRay(ray,script.Parent)

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