Raycasting problem!

So Im trying to create wallrun script, and im detecting walls with raycast. It seems to work with old deprecated way, but not with Raycast.

Attempt to index nil with ‘Instance’

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local PrimaryPart = Character.PrimaryPart
local RunService = game:GetService("RunService")
local Climb = false
local Hold = false
local Side = "none"

local BodyGyro = Instance.new("BodyGyro", PrimaryPart)
BodyGyro.D = 100
BodyGyro.P = 10000
BodyGyro.MaxTorque = Vector3.new(0,0,0)
BodyGyro.Name = "Rotate"
local BodyVelocity = Instance.new("BodyVelocity",PrimaryPart)
BodyVelocity.MaxForce = Vector3.new(0,0,0)
BodyVelocity.Name = "Velocity"

local function RayCast(Origin,Direction)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {Character}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local rayCastResult = workspace:Raycast(Origin,Direction,raycastParams)
	
	if rayCastResult then
		return rayCastResult
	end	
end


local function LeftRay()
	local a=PrimaryPart.Position
	local b=PrimaryPart.CFrame.RightVector*3
	return RayCast(a,b)
end
local function RightRay()
	local a=PrimaryPart.Position
	local b=PrimaryPart.CFrame.RightVector*-3
	return RayCast(a,b)
end

local function WallRun()
	
	local LRay = LeftRay()
	local RRay = RightRay()
	
	local Part1,Part2 = LRay.Instance,RRay.Instance --this part gives error
	
	local Cross1 = Vector3.new(0,1,0):Cross(LRay.Normal)
	local Cross2 = Vector3.new(0,1,0):Cross(RRay.Normal)
       --things will be added later...
end)

RunService.RenderStepped:Connect(function()
	WallRun()
end)

image

What exactly is on line 50 - is this the full code? The stack trace indicates something on line 95 - which is what I also need to see.

If possible, please post the full code with the issue - up until line 95 with enough context, if possible.

Uh I did cut it a bit, but that’s full code

code without any edits
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local PrimaryPart = Character.PrimaryPart
local RunService = game:GetService("RunService")
local Climb = false
local Hold = false
local Side = "none"

local BodyGyro = Instance.new("BodyGyro", PrimaryPart)
BodyGyro.D = 100
BodyGyro.P = 10000
BodyGyro.MaxTorque = Vector3.new(0,0,0)
BodyGyro.Name = "Rotate"
local BodyVelocity = Instance.new("BodyVelocity",PrimaryPart)
BodyVelocity.MaxForce = Vector3.new(0,0,0)
BodyVelocity.Name = "Velocity"

local function RayCast(Origin,Direction)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {Character}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	local rayCastResult = workspace:Raycast(Origin,Direction,raycastParams)
	
	if rayCastResult then
		return rayCastResult
	end	
end


local function LeftRay()
	local a=PrimaryPart.Position
	local b=PrimaryPart.CFrame.RightVector*3
	return RayCast(a,b)
end
local function RightRay()
	local a=PrimaryPart.Position
	local b=PrimaryPart.CFrame.RightVector*-3
	return RayCast(a,b)
end

local function WallRun()
	
	local LRay = LeftRay()
	local RRay = RightRay()
	
	local Part1,Part2 = LRay.Instance,RRay.Instance
	
	local Cross1 = Vector3.new(0,1,0):Cross(LRay.Normal)
	local Cross2 = Vector3.new(0,1,0):Cross(RRay.Normal)
	
	if LRay or RRay then
		
		if Part1 then
			local PRC = Vector3.new(PrimaryPart.Position.X+Cross1.X,PrimaryPart.Position.Y,PrimaryPart.Position.Z + Cross1.z)
			PrimaryPart.CFrame = CFrame.new(PrimaryPart.CFrame.Position,PRC)
		elseif Part2 then
			local PRC = Vector3.new(PrimaryPart.Position.X-Cross1.X,PrimaryPart.Position.Y,PrimaryPart.Position.Z - Cross1.z)
			PrimaryPart.CFrame = CFrame.new(PrimaryPart.CFrame.Position,PRC)
		end
		
		Hold = true
		Climb = true
		
		if Hold then
			BodyGyro.CFrame = PrimaryPart.CFrame
			BodyGyro.MaxTorque = Vector3.new(1,1,1) * math.huge
			BodyVelocity.MaxForce = Vector3.new(1,1,1) * math.huge
			Hold = false
			if Part1 then
				BodyVelocity.Velocity = Cross1 * 5
				Side = "Right"
			elseif Part2 then
				BodyVelocity.Velocity = -Cross2 * 5
				Side = "Left"
			end

		end
		
	elseif Climb and not Part1 and not Part2 and not Hold then
		BodyGyro.MaxTorque = Vector3.new(0,0,0)
		BodyVelocity.MaxForce = Vector3.new(0,0,0)
		Climb = false
		Side = "none"
	end
	
	
end


RunService.RenderStepped:Connect(function()
	WallRun()
end)

WorldRoot:Raycast() can return nil if no part was found according to the documentation, check to see if the RaycastResult is nil before doing anything on it.

Ways the Instance property can be nil is if you’re not next to a part or a part isn’t below you, and it’s just the void of the world - that can cause Instance to be nil. If it shouldn’t be nil, try checking if you’re casting in the direction you need to go - try checking the direction parameter to make sure it is going in the direction you expect it to.

It seems okay other than that - just try checking if RRay and LRay are nil before doing anything further with them, and debugging to see if the results is in line with what you expect with the method I suggested above, too.

1 Like