Problem with clock

I wanted to create a clock and change the hour “stick” to the position i gave in the table but it just gives me an error instead

Here’s the code for it

local screenColorModule = require(game.ReplicatedStorage.ColorCorrectionSettings)

local possibleHourPositions = {
	
	["1st"] = { 
		Position = -69.618, 8.446, 0.064,
		Orientation = -28.17, 180, 0
	},
	["2nd"] = {
		Position = -69.618, 7.827, 0.774,
		Orientation = -58.805, 180, 0
	},
	["3rd"] = {
		Position = -69.618, 6.726, 1.153,
		Orientation = 90, 0, 0
	},
	["4rd"] = {
		Position = -69.618, 7.796, -3.019,
		Orientation = -59.203, 0, 0
	},
	["5rd"] = {
		Position = -69.618, 5.617, -3.173,
		Orientation = -61.884, 180, 180
	},
	["6rd"] = {
		Position = -69.618, 4.527, -1.126,
		Orientation = 0, 0, 180
	},
	["TheEnd"] = {
		Position = -69.618, 9.127, -1.126,
		Orientation = 0,0,0
		
	}
	
}


script.Parent.hour.ClickDetector.MouseClick:Connect(function()
	local random = math.random(1,#possibleHourPositions) --where it happens
	for i,v in pairs(possibleHourPositions) do
		if random == i and i ~= "TheEnd" then
			script.Parent.hour.Position = Vector3.new(v.Position)
			script.Parent.hour.Orientation = Vector3.new(v.Orientation)
		else
			script.Parent.hour.Position = Vector3.new(v.Position)
			script.Parent.hour.Orientation = Vector3.new(v.Orientation)
			script.Parent.ding:Play()
			screenColorModule.ScreenColor(game.Lighting.MeteorEffect,Color3.new(1, 1, 1),3,0)
		end
	end
end)

(I know its not really a clock but it would really help if you find the solution to this mess)

3 Likes

Its because you are trying to get the number of keys of a Dictionary and that only works for Arrays.

An array:

local array = {
	{ 
		Position = {-69.618, 8.446, 0.064},
		Orientation = {-28.17, 180, 0}
	},
	{
		Position = {-69.618, 7.827, 0.774},
		Orientation = {-58.805, 180, 0}
	}
}


local randPos = array[math.random(1, #array)] -- #array gets the number of keys inside the array
warn(randPos)

When you do this:

local possibleHourPositions = {
	
	["1st"] = { 
		Position = -69.618, 8.446, 0.064,
		Orientation = -28.17, 180, 0
	},

You created a dicctionary with a custom index called “1st” so #possibleHourPositions wont return the number of keys in the array cause its a dictionary

1 Like

Alright give me some time to do that i’ll be right back.

2 Likes

It works but i didn’t exactly get what i wanted because now i get the “The End” everytime i click it also i had to change the code a bit

local screenColorModule = require(game.ReplicatedStorage.ColorCorrectionSettings)

local possibleHourPositions = {
	
	{ 
		Position = -69.618, 8.446, 0.064,
		Orientation = -28.17, 180, 0
	},
	{
		Position = -69.618, 7.827, 0.774,
		Orientation = -58.805, 180, 0
	},
	{
		Position = -69.618, 6.726, 1.153,
		Orientation = 90, 0, 0
	},
	{
		Position = -69.618, 7.796, -3.019,
		Orientation = -59.203, 0, 0
	},
	{
		Position = -69.618, 5.617, -3.173,
		Orientation = -61.884, 180, 180
	},
	{
		Position = -69.618, 4.527, -1.126,
		Orientation = 0, 0, 180
	},
	{
		Position = -69.618, 9.127, -1.126,
		Orientation = 0,0,0
		
	}
	
}


script.Parent.hour.ClickDetector.MouseClick:Connect(function()
	local random = possibleHourPositions[math.random(1, #possibleHourPositions)]
	for i,v in pairs(possibleHourPositions) do
		if 	random ~= 7 then
			script.Parent.hour.Position = Vector3.new(v.Position)
			script.Parent.hour.Orientation = Vector3.new(v.Orientation)
		else
			script.Parent.hour.Position = Vector3.new(v.Position)
			script.Parent.hour.Orientation = Vector3.new(v.Orientation)
			script.Parent.ding:Play()
			screenColorModule.ScreenColor(game.Lighting.MeteorEffect,Color3.new(1, 1, 1),3,0)
		end
	end
end)

1 Like

Well, because you want to use if statements to check when the loop is done, probably you want to go in “ipairs” instead of “pairs” to follow the right order of your table when you reach the 7th key perform stuff

script.Parent.hour.ClickDetector.MouseClick:Connect(function()
	local random = possibleHourPositions[math.random(1, #possibleHourPositions)]
	
	for i, v in ipairs(possibleHourPositions) do -- use ipairs if you want to follow the order of your array
		if 	random == #possibleHourPositions then -- when reaching the end

Oops… edit. I did not really read that last line. I meant “if random is equal to the last key” (7)… not different, I edited it

2 Likes

I get what you are doing, but, actually I think there are different approaches that you could try to make it more “elegant” like, using a Pi formula to rotate the “stick”, based on a table of “times” you desire. It really depends on what you are aiming for. Right now, what I see, is that you want some fixed times meaning some fixed positions of the clock arrow. And I guess that you want to “select a random time from the table” and from that time continue with the next times remaining until reaching the end. Which surely has many approaches that can be done to achieve that behavior

2 Likes

I wanted its position to be randomly set by the array you gave me not in order

for example: you click the clock and it gives you the position and orientation values in that index RANDOMLY not in order my goal is to make the player click the clock until that clock matches the position i wanted (the last index)

1 Like

Ok, Im starting to understand.

Mechanics:
Player clicks a something, script selects a random “time” from table, clock changes to that “time”
I player clicked enough to get the “last position time” of the table, something happens.
Correct?

1 Like

Exactly.
Im suprised that you can understand my terrible english

3 Likes

Mine is worst, dont worry. We can always understand :3

Seems easier, lets just follow the rules and goal. Whats your language btw? mine is spanish

3 Likes

Mine is turkish but just to clarify i didnt meant it by selecting it from the table completely random.

Screenshot_1
it either sets the position and orientation of that “clock” to that index, that index and that index (i hope you understood)

So…

If player clicks the button and randomly gets the 2nd key of the array. When clicking the button again player will get a total new random one? or the next one in order of the array?

exactly i want it to be totally new random one but i cant figure out how

1 Like

Cmon friend… you said You dont want it to be completely random…_

And later you say:

Aaaa xD

I didnt mean it like that

I actually thought you’d understand it as selecting the position from an another index and selecting the orientation from a different index

(because of my terrible english)

1 Like

As others mentioned, you can’t get the size of a dictionary using the # operator. Also, you don’t need to, since the keys aren’t numeric and thus you can’t index the dictionary using numbers like 1, 2, 3, etc.

Instead, you can iterate through the dictionary to fetch the keys and then select a random key for indexing:

local function getKeys(t: {[any]: any}): {}
	local keys = {}
	for key, _ in pairs(t) do table.insert(keys, key) end
	return keys
end

local keys = getKeys(possibleHourPositions)
local key = keys[math.random(1, #keys)] 
local rand = possibleHourPositions[key]

print(key, rand)

Although if you really want the number of elements in a dictionary, here’s a function that calculates it by simply iterating through it:

local function getAmount(t: {[any]: any}): number
	local num = 0
	for k, v in pairs(t) do num += 1 end
	return num
end

print(getAmount(possibleHourPositions))
1 Like

Look, I would do it in a very simple way like this.

In your array, insert a Key inside any of the Keys you want it to be the “choosen one”. I added “TheKey = true”…

Then, everytime the player clicks the button, you select a totally new random one, and check if that key has the value “TheKey” if the key has the value you know its the right one to finish the mechanics.

This is just a copy/paste code to run in command bar to simulate player clicking the button and after some tries player got the right key to finish the loop:

local possibleHourPositions = {

	{ 
		Position = -69.618, 8.446, 0.064,
		Orientation = -28.17, 180, 0
	},
	{
		Position = -69.618, 7.827, 0.774,
		Orientation = -58.805, 180, 0
	},
	{
		Position = -69.618, 6.726, 1.153,
		Orientation = 90, 0, 0
	},
	{
		Position = -69.618, 7.796, -3.019,
		Orientation = -59.203, 0, 0
	},
	{
		Position = -69.618, 5.617, -3.173,
		Orientation = -61.884, 180, 180
	},
	{
		Position = -69.618, 4.527, -1.126,
		Orientation = 0, 0, 180
	},
	{
		Position = -69.618, 9.127, -1.126,
		Orientation = 0,0,0,
		TheKey = true
	}

}


local function SimulateClick()
	--script.Parent.hour.ClickDetector.MouseClick:Connect(function()
	local random = possibleHourPositions[math.random(1, #possibleHourPositions)]

	--script.Parent.hour.Position = Vector3.new(v.Position)
	--script.Parent.hour.Orientation = Vector3.new(v.Orientation)
	--script.Parent.ding:Play()
	--screenColorModule.ScreenColor(game.Lighting.MeteorEffect,Color3.new(1, 1, 1),3,0)

	if random["TheKey"] then
		warn("player got the special key")
		return true
	end

	--end)
end

while true do
	warn("doing check")
	if SimulateClick() then
		break
	end
	wait(1)
end

And do not apologize for your english. Its perfect. Just, try to be very clear about the exact mechanics you desire for your system since your first post. The only hard thing about solving issues its not the programming syntax, the real issue is to understand what is your goal

thats correct but whats the point of array if you cant even change the position of it (no for loop :frowning: )

The only reason for using the loop is that you want somehow follow an order of your array, otherwise would be completely useless. Cause you can have a value inside the table that points out which is the desired key.

If the goal is to:

Player activates button, a random key/time is selected, and next click of button will select a random time BETWEEN the remaining keys (thats why you would use a loop)…
Otherwise…
If you always want to select a new key from the array, no matter the last one/position. Literally player only needs to continue clicking until reaching the “special key” which stops the mechanics. Then a loop is totally useless and resource consuming that is not needed