Help with math.random() and Dictionary script

Hey, I’m currently trying to recreate a small project that Roblox themselves created. This project can be found on the “Raycasting” Creator Documentation. Raycasting | Documentation - Roblox Creator Hub

The top video on that page shows what I am trying to create. Where there are numerous platforms and orbs repeatedly move to different plates. Upon arriving at a plate, the plate is destroyed.

Issues:
[-] Every single time I run the game, the same positional value is selected. Then the output prints that positional value over and over again.math.random() should be selecting a new positional value but it doesn’t. And somehow, even when I stop running the game and try again, the same positional value is selected. Every test I run, the positional that is selected is “-236.31951904296875, 41.76299285888672, -369.3587646484375” All of the orbs move to this position every single time. This is the largest issue I have.

[-] Secondly, I cannot figure out how to prevent the orbs from moving to platforms that have already been destroyed by another orb. I’ve tried using table.remove() to remove position values from the “PositionsTable” however I can’t remove a Vector3() value…

[-] Lastly, the platform invisibility tween doesn’t start playing until the orb moves to the next platform. It should begin playing once the orb is above the platform, not after it leaves.

Any help is much appreciated, thank you!

In Studio:

Play test:


As you can see, they have all moved to the same exact position. This is the spot they move every single time I run the game.

Script:

-- // Declarations
local mainFolder = game.Workspace:WaitForChild("MiniGameFolder")

local sets = mainFolder.Sets.Set:GetChildren()
local orbs = mainFolder.Orbs:GetChildren()

local TweenService = game:GetService("TweenService")

local positionParts = {} --Has names of all parts named "PositionPart"
local positionsTable = {} --Has position coordinates

-- // Gets all the parts named "PositionPart" in the models

for i, v in pairs(sets) do
	if v.Name == "PositionPart" then
		table.insert(positionParts, v)
	end
end

-- // Gets all the position values of the parts named "PositionPart"

for i, v in pairs(positionParts) do
	local position = v.Position
	table.insert(positionsTable, position)
end

-- // Main loop

while true do
	for i, v in pairs(orbs) do
		--local randomPosition = math.random(1,#positionsTable) --Prints "1" if you do: print(randomPosition)
		--local chosenPosition = positionsTable[randomPosition] --Position value (Vector3)
		
		-- // Randomly select a position and have one of the "orbs" go to that position.
		
		local randomPositionDictionary = {randomPosition = math.random(1, #positionsTable)}
		local chosenPosition = positionsTable[randomPositionDictionary.randomPosition]
		print(chosenPosition)

		-- // Tween declarations

		local Info = TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
		local Goals = {Position = chosenPosition}
		local tween = TweenService:Create(v, Info, Goals)

		-- // Raycast Declarations

		local rayOrgin = v.Position
		local rayDirection = Vector3.new(0,-100,0)
		local raycastResult = workspace:Raycast(rayOrgin, rayDirection)

		-- // Raycasting/Tweening

		if raycastResult then
			local visibleTween = TweenService:Create(raycastResult.Instance, TweenInfo.new(3), {Transparency = 1})

			tween:Play()
			visibleTween:Play()

			wait(3)
		end
	end
end

Note:
The code below is a previous attempt at making the code work. I tried using tables but eventually switched over to dictionaries for math.random()

You can disregard all of this code as it isn’t part of the script. It is commented out.

--local randomPosition = math.random(1,#positionsTable) --Prints "1" if you do: print(randomPosition)
		--local chosenPosition = positionsTable[randomPosition] --Position value (Vector3) ```
1 Like

The best thing to do is work backwards with some print checks.
In the while true loop try:
print(#positionsTable)
If math.random() appears to return the same value each time this is most likely because it has only one option to choose from. i.e. the positionsTable has length 1 (or 0).
You may also need to check the naming of the parts and that they are named exactly as “PositionPart” as this would also lead to insufficient positions being added to the table.

pairs or ipairs

Also pairs is usually for key, value dictionaries, whereas ipairs is usually for integer, value arrays (not really much difference) but GetChildren() returns an array so would be more appropriate in this case.
However, having said that, as you are not using the key or integer in the code it is perfectly fine to use a blank value like:

for _, v in ipairs(positionsTable) do
  --some code
end
1 Like

Ah, I see the issue now. I did local sets = mainFolder.Sets.Set:GetChildren() which caused only 1 value to go into the table. I corrected this by changing that line to local sets = mainFolder.Sets:GetDescendants() Thanks for the help!

That solves the biggest issue with the code. The orbs now move to multiple platforms randomly. The other issues still remain though. Any idea how I should go about fixing the other two issues?

I managed to use table.remove() to make them not go to platforms that are already destroyed. I’d like platforms to regenerate after 15 seconds though. I tried achieving this by doing:

if raycastResult.Instance.Transparency == 1 then
	wait(15)
	raycastResult.Instance.Transparency = 0
end

The issue with this code is that the wait(15) puts the entire while loop on hold for 15 seconds. Meaning it waits 15 second before another orb moves and doesn’t select another position for another 15 seconds. This is a major problem.

if raycastResult.Instance.Transparency == 1 then
	task.spawn(function()
        task.wait(15)
	    raycastResult.Instance.Transparency = 0
    end)
end

If you use spawn() for this, it doesn’t halt the execution of the loop!

2 Likes

I was not aware of that. Thanks!

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