Invalid argument when getting dot product between an instance from a table and the player

Title. As part of my rail-grinding system I’m using these attachment nodes placed upon the rail. When the player touches the rail the script should get the 2 closest nodes to the player from the rail’s children, then get the dot products of those and the player in order to find which one the player is facing.

However, the script throws me an error when I try getting the dot products although I called the instances from the table correctly (Invalid argument #2 (Vector3 expected, got nil).

local player = game.Players.LocalPlayer
local character = player.Character

local RailFolder = workspace.Rails	

for _, Rail in RailFolder:GetChildren() do
	
	Rail.Touched:Connect(function(touch)
		
		for _, Node in Rail:GetChildren() do
			if Node.ClassName == "Attachment" then 
				
				local Distances = {} -- Setup table 
				
				Distances[#Distances + 1] = {Object = Node; Distance = player:DistanceFromCharacter(Node.Position)} -- Fill table with the node names, along with their distance from the player
				
				table.sort(Distances, function(a, b) -- Sort the table in terms of lowest distance from the player 
					return a.Distance < b.Distance
				end)
				
				local nearestNode = Distances[1] 
				local secondNearestNode = Distances[2]
				-- Get closest two nodes now that the table is sorted 
				local playerToNearestNodeDot = character.Head.CFrame.LookVector:Dot(nearestNode.Position)
				-- Get dot products of the closest two nodes. Error appears here
				local playerToSecondNearestNodeDot = character.Head.CFrame.LookVector:Dot(secondNearestNode.Position)
					
				print(playerToNearestNodeDot)
				print(playerToSecondNearestNodeDot)
				
				 
			end
		end
		
	end)
	
end

Calling the nodes outright then getting their dot products works normally with this put under the Touched event though.

        local endNode1 = Rail.EndNode1
		local endNode2 = Rail.EndNode2
		
		local playerToEndNode1Dot = character.Head.CFrame.LookVector:Dot(endNode1.Position)

		local playerToEndNode2Dot = character.Head.CFrame.LookVector:Dot(endNode2.Position)
		
		if playerToEndNode1Dot > playerToEndNode2Dot then 
			print("Player is facing toward EndNode1")
			
			
			
		else if playerToEndNode1Dot < playerToEndNode2Dot then
				print("Player is facing toward EndNode2")
			end
		end

This is also my first actual attempt to use tables, so sorry if I do something wrong.

Bump. Still haven’t been able to find a solution…

{Object = Node; Distance = player:DistanceFromCharacter(Node.Position)}

You’re creating a dictionary, with 2 keys: Object and Distance.
However, you are later trying to use another key, “Position”.

nearestNode.Position

This key doesn’t exist, so it just returns nil instead.

I believe you meant to do nearestNode.Object.Position and secondNearesetNode.Object.Position

1 Like

This was actually the solution I found yesterday, but thanks for the reply!

actually, now that I think about it, would I be able to make a third key for the dictionary by adding Position = Node.Position to the key collection or would that not work?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.