Getting "nil" From ObjectValue Code

I am working on a Path Finding system using A*. I know it has been done before, but I this was a personal challenge for me to figure out and get working. However, I was working on a system of a “PathMap” which shows the nodes and connections. I’m using ObjectValues as a descendant of one node with the value of the ObjectValue being the other node to connect to. The following code is what I am currently using:

----- Create Connections -----
for _, node in pairs(dataMap:GetChildren()) do
    --- This loop goes through all the connections to other nodes from "A" (All the B's from A)
    for _, connection in pairs( node:GetChildren()) do
	    if node == connection.Value then
		    for _, allNodes in pairs(pathMap:GetChildren()) do
			    if allNodes.Name == node.Name then
				    allNodes.Color = Color3.fromRGB(42, 195, 200)
			    end
		    end
	    elseif node ~= connection.Value then
        	local hold = connection.Value
		    local newConnection = Instance.new("Part")
		    newConnection.Name = "Connector"
		    newConnection.Anchored = true
        	newConnection.TopSurface, newConnection.BottomSurface = Enum.SurfaceType.Smooth, Enum.SurfaceType.Smooth
		    newConnection.Color = Color3.fromRGB(151, 0, 0)
            ---This hold.Value is my problem
		    newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - hold.Value).magnitude)
		    newConnection.CFrame = CFrame.new(node.Value:Lerp(hold.Value, 0.5), hold.Value)
		    newConnection.Transparency = 0.65
		    newConnection.Parent = pathMap
	    end
    end
end
-----

Referring to the “hold.Value” comment in the code, the error has only happened twice and I don’t know why it happens. The only error code says something about unable to interpret nil from Value. That’s not the exact error message, but it tells me that the hold.Value is nil.
I know that it at least connects to the Object (node) because it never has given an error at local hold = connection.Value.

If I get the error again I was get a screenshot or picture of it and upload it, but I’ve been trying for about half an hour and got nothing (I haven’t even changed the code). It will work 99.9% of the time, but I would rather fix the error than risk it. I have also checked the “dataMap” folder and each node in the folder to make sure that there are no nil ObjectValues. Last mention, I know the node.Value is not the problem (from the same error line). The nodes are Vector3Values and I also checked each node to make sure there is a Vector3 value.

[This code was copy and pasted so if there is an error from my own programming then that may have caused it, but I haven’t seen any problems and don’t have any errors from syntax]

2 Likes

if node == connection.Value then --line 5
Just checking, do you have nodes which go back to themselves?

Let me keep looking some more.

And just to make sure I have this straight, I read that nodes are ObjectValues and connections are Vector3 values?

The only nodes that go back on themselves as objects are tested in that line, so yes. I haven’t had a problem with it yet (so at all as of now). When they go back on themselves it’s because they are connected to no other nodes, which this is already tested for and done in another function.
Replying to this, the nodes are the Vector3Values that the .Value is the Vector3 position of the node in the world. The ObjectValues are the connections. For example, in Node A, a descendant would be an ObjectValue with the .Value being Node B. (Note Node A could be connected to more than 1 [B, C, D, …]). The ObjectValue refers back to the Vector3 of Node B where the Vector3.Value is the position of the node in world.

Being connected to more than 1 node isn’t a problem. There is an ObjectValue for each node that is connected under Node A.
The image below is what happens when I create the nodes into data. 4 and 5 don’t have Connections because they are already connected under 1, 2, or 3. There are no repeated connections. (The numbered instances are the Vector3 and the children are the ObjectValues)
devForumPF

if node == connection.Value then
This is comparing a Vector3 to an ObjectValue, or do the ObjectValues point to the Vector3 values?

I should not be doing this this late…

Node in that case is just the object. Node comes from the dataMap:GetChildren() in line 2. It’s the object 1, 2, 3, etc. node.Value refers to the actual Vector3 value (which is the x,y,z). It’s comparing the node object to the object in connection.Value.

I’m sorry, I am tired and I will look at this again tomorrow. Please message me if I forget.

Isn’t the problem just that you’re accessing Value twice?

The variable hold is defined as connection.Value, yet later when you use the variable hold you also use hold.Value, meaning that this is getting evaluated to connection.Value.Value which is nil. I think you either meant to use the hold variable alone or use connection.Value. Example fixes here:

newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - hold).magnitude)
newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - connection.Value).magnitude)

If you need to see what specifically changed:

First sample:
newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - hold.Value).magnitude)

Second sample:
newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - connection.Value).magnitude)

connection.Value would be referencing the Vector3 object, but not it’s actual value

I looked at the code again, and I could not see anything wrong. Perhaps just doing
hold = connection.Value.Value would be better, but I’m guessing it won’t change much. Let me know if you get the error you’re looking for. Also note that perhaps something is nil because things are still loading into the game.

Right, like imalex stated, hold.Value is the value of a Vector3. ‘hold = connection.Value’ refers to an object value. So connection.Value.Value or the current code I have gives a Vector3Value. I know the code works because it has before, the issue is I’ve had it error three times and didn’t think to get a grab of the error code before posting this and I haven’t been able to recreate the problem with no code changes. When I get home I will post a link to a game where I uploaded the code showing it working. I’m just unsure what’s causing that error.

I’ll try that. I’m going to also try doing ‘hold = connection.Value.Name’ then do a obj = :FindFirstChild(hold) in the dataMap and then in the size and CFrame code do obj.Value.

Also make sure that you wait for everything to load. I’m not sure if that FindFirstChild will make any difference, but I don’t know too much about the error you had.

So should I try implementing WaitForChild() where the FindFirstChild’s are or should I just wait for the dataMap at the beginning?

Alright, I ended up finding the error. I ended up changing the code to the following couple lines:

--- Line 5 from Original Code ---
if node.Name == connection.Value.Name then
--- Line 12 and New Line 13 ---
local hold = connection.Value.Name
local holdObj = dataMap:FindFirstChild(hold)
--- Lines 19 and 20 From Original ---
newConnection.Size = Vector3.new(0.45, 0.45, (node.Value - holdObj.Value).magnitude)
newConnection.CFrame = CFrame.new(node.Value:Lerp(holdObj.Value, 0.5), holdObj.Value)

— Why did I change it? —
I was trying to see if maybe it was an issue with how the code was set up, this was pointed out by @imalex4. I wanted to try changing the code to find the object in the folder.

—What was the problem? —
I ended up getting an error code saying that the .Name (the error was from the code above line 5) saying that it was nil. I was confused and ended up cloning the dataMap into the workspace (dataMap is in ServerStorage). When looking through it and the editingMap, I realized that the connections were not updating.

— Solution —
When I realized the connections were not updating after a node was deleted, I realized that was probably the issue. To explain, if you have Nodes 1-5 and delete node 3, nodes 4 and 5 become the new 3 and 4 (respective in order). The issue was the connections to the old node 5 (now 4) where not changing to 4 instead of 5. Realizing this, I added the following code:

function mapEditor:updateConnections(removedNumber)
	for _, connection in pairs(game:GetService("Workspace"):FindFirstChild("EditingMapFolder"):GetChildren()) do
		if connection.Name == "NodeConnection" then
			for _, node in pairs(connection:GetChildren()) do
				if tonumber(node.Value) >= removedNumber then
					node.Value = tostring(tonumber(node.Value) - 1)
				end
			end
		end
	end
end

This function updates the connections to all nodes above the “removedNumber” (i.e. changing all node connections greater than the removed to the value - 1 like changing nodes 4 and 5 to nodes 3 and 4).

Thanks for the help @imalex4 and @colbert2677. I’m going to give Alex the solution for (below quote) as it was what made me change the code and led to my error in the code. Thanks!

[EDIT]
I think I will make a cool creations post later to post the place there.

1 Like