Flee the Facility hacking dial

how is this done? The dial rotates around the circle and you have to press E at the right time. How can I do this, and how does it check if we pressed E while the dial was at the correct place. I can script well, so you don’t have to spoonfeed me, just point me in the right direction, thanks :slight_smile:
image

7 Likes

I did something similar to this in my own game, and it’s really quite simple.

Firstly, setup a InputBegan Connection with an if statement inside checking that the KeyCode is Enum.KeyCode.E.

Secondly, you’ll want to start moving the dial - you may do this via Rotation or the changing of Position, I’d recommend the use of TweenService to tween the property.

Thirdly, inside your if statement in the InputBegan you should :Pause() the tween or stop however you’re moving the dial.

Finally, check that the dial is within the correct range via an if statement utilising the >= and <= operators.

2 Likes

I was more looking for the math behind it, how the dial is made, and how the correct range is calculated.

You have start time.
Calculate random point from 0-1, allow for some mistake.
You now have your click time range.
Decide for speed the dial should go by.

Value = TimePlayerTakesToClick/Speed

if Value > RndPoint±MistakeMargin and Value < RndPoint±MistakeMargin then they succeeded.

You can check the rotation of the dial and check if it is within the bounds of the white circle with a minimum and maximum angle.

FTF has a long, invisible line the size of the circle’s radius or diameter with the red line at the end of it. The line is rotated and it will simulate the red line following the path. You can use @evaera’s Radial Sprite Sheet Generator to make a random portion of the circle and then rotate it to a certain angle

If you have the white section of the circle and added a rotation, you can get the minimum and maximum angle and compare the red line’s rotation with them by doing: (i’m not sure if this math is right)

local offset = portionAngleSize / 2
local minimum = dialRotation - offset
local maximum = dialRotation + offset

You can compare the red line’s current rotation with the minimum and maximum variables:

if line.Rotation >= minimum and line.Rotation <= maximum then
   -- within the bounds of the white section
end

I tried by best at explaining this, lol

You could probably just set the anchorpoint of the red line to be at the center of the dial, and then just increase the rotation each frame

Here’s a code example (Pseudo Code):

local random = Random.new()
local start = random:NextInteger(1, 4) -- generates a number from 0.25 - 1 on an increment of 0.25
start = 0.25 * start
local errorMargin = start + 0.25
local SPEED = 2
local value = 0
local stepStart = tick()
local stepEnd = tick()
Connection = Heartbeat:Connect(function()
      stepEnd = tick()
      value = value + ((stepEnd - stepStart) * SPEED)) -- alpha value
      stepStart = tick()
end)

KeyEDown:Connect(function()
    if Connection then 
       Connection = Connection:Disconnect()
       value = math.floor(value) / value
       if value < errorMargin and value > start then
          successFunction()
       else
          makeLoudSound()
       end
    end
end)

Hi. You could use ImageLabel objects with images like these:
Background Range
By giving the “Range” image a random Rotation value, you would get the acceptable interval by just adding or substracting 45 degrees or math.pi/4 radians to its Rotation value (much like @Raretendoblox explained).

The red line could be another image or a Frame inside a Frame with certain offset (so you have less assets to load).

For instance, you can define the dial setup just with this:

-- define both variables
local line.Rotation = script.Parent.Line
local range = script.Parent.Range

range.Rotation = math.random(0, 360) -- or math.random(45, 315) in case you don't want the range to overtake the initial rotation

The rest,

local min_rot = range.Rotation - 45
local max_rot = range.Rotation + 45

game:GetService("UserInputService").InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.E then
			if line.Rotation >= min_rot and line.Rotation <= max_rot then
				-- :D
			else
				-- ;-;
			end
		end
	end
end)

while true do
	wait()
	line.Rotation = line.Rotation + 1
end

You could also use render stepped for the loop:

game:GetService("RunService").RenderStepped:connect(function()
	--"Loop"
end)

or, as @Uralic suggested, heartbeat is another good option.

2 Likes

everything is really nice, I will be able to use everything except the red line part and it’s all working. how do I make this red line? Everything else clicked and makes alot of sense, is working. I’ll probably have to just make a new image with the same resolution and position the red line at the correct place, but I’m wondering if you have a better way, thanks

Your red line could look like this:
red

This would be another option:


in which the “Line” frame is completely transparent and it’s simply used as a scaffold to center the line “detail” (it should be placed at position 0, 0, 0, 0 and resized to 1, 0, 1, 0). When you rotate the “Line” frame, all its children rotate too. Advantage: you don’t have to use another image asset. Disadvantage: you have to use more objects.

By the way, you can create your own images, customized and adapted to your game UI, or even find some in the Library, since they are very simple geometric forms.

2 Likes