3D Throttle Lever

Hey, I was wondering if anybody knew how @Widgeon and the air x team accomplished their very interactive cockpit, mainly their 3d throttle slider type thing:

https://gyazo.com/b7abcd5aeb1fe8fc3de202e4984e0661

if anyone knows it would be greatly appreciated for you to explain it to me!

cheers in advance :slight_smile:

4 Likes

Possibly not the best solution, but here you go:

We’re going to be using CFrames, so try to make sure you have at least a little bit of understanding on how it works (if not, just think of it like Position and Orientation had a baby)

Get the script

Now, we’re going to be using this CFrameValue.txt (394 Bytes) script I made to get something I’ma call a “RelativeCFrame”. Too complicated for me to explain, so just think of it as magic for now.

Step 1: Getting the “Closed” and “Open” CFrame

Don’t want to get into too much detail here, so just do as I say:

  1. Make sure your lever is in the “Closed” position
  2. Select your “lever” part in the Explorer
  3. Select the part your lever rotates/orientates itself around, the “Base”
  4. Run the script above in the command bar

After this, you should have selected a CFrameValue. Name it “ClosedCFrame”
Do this again BUT for step 1 make sure the level is in the “Open” position instead, and name the CFrameValue to “OpenCFrame”

Step 2: SCRIPTING!

Now mostly due to the fact that it is currently almost 1 AM and for you to understand this easily I will be explaining this in a nutshell:

We’re going to be using the CFrames we stored in our Values and mapping them onto the part it orientates around the “Base”.

First, we get our CFrameValues, parts, and BaseCFrame

local ClosedCFrame  -- change this to where you put it
local OpenCFrame -- change this to where you put it

local Lever -- the lever part
local Base -- the base part
local BaseCFrame = Base.CFrame

Finally, when we want to set the Lever in an Open or Closed position, we can do so like this:

-- Open
Lever.CFrame = BaseCFrame * OpenCFrame.Value

-- Closed
Lever.CFrame = BaseCFrame * ClosedCFrame.Value

You can also use Lerp to Tween it smoothly, however I’ll leave that up you to do, lemme know if you need help, good luck!

1 Like

Obviously you’d need to create a HUD using a ScreenGui | Roblox Creator Documentation. For the actual 3d positioning of the throttle in this situation I’d use a PrismaticConstraint | Roblox Creator Documentation and tween the SlidingBallConstraint | Roblox Creator Documentation property to edit how far it’s extended. You can read Roblox’s Physics | Roblox Creator Documentation article to learn more.

1 Like

Actually, you’re probably better off using this solution, in my awake-for-18-hours state I forgot about physical constraints :sweat_smile:

1 Like

sorry i wasnt clear xd
my goal was to use the mouse to slide it

sorry i wasnt clear xd
my goal was to use the mouse to slide it

What do you mean by that, exactly?

so like a mouse slider basically. I grab the part with the mouse and can move it along one axis with certain limits obviously.

Sorry I never replied. I was doing other stuff for awhile but I’m back now. I’ve run into this problem before when creating a light dimmer and eventually solved it. However, that was awhile ago and I currently do not have access to my computer (being repaired) so I can’t check to see what the solution was that I came up with. However, I think I did something along the lines of using a local script in StarterPlayerScripts to detect the player input using UserInputService and the current part they had their mouse or finger on. Then I believe I used a debounce to detect whether or not they were clicking/dragging on the slider brick to enable the brick to slide up and down on the y-axis depending on the 3D height of the cursor where the player was clicking/touching. Of course I used math.clamp to limit the height the dimmer switch could go. PM me if you need more help.

how are you checking if the mouse is clicking the part?

Is it not better to use motort6d’s and welds? They have far better stability than those constraints.

How do you make red background in--Open and --Close

Well this one was a bit more complicated because UserInputService | Roblox Creator Documentation just gives you a lot of input options to choose from and then leaves you to figure things out on your own. I don’t actually remember what I did, and as previously mentioned, am not able to check what I did. Before I provide an example I must make a disclaimer that the code I provided is untested and may or may not work.

Local Script

local userInputService = game:GetService("UserInputService")

local player = game:GetService("Players").LocalPlayer -- the clients player instance
local camera = workspace.CurrentCamera -- the clients camera instance
local dimmer = workspace.DimmerSwitch -- the instance we use for the dimmer
local highlighter = Instance.new("SelectionBox")

local highlightSwitch = true -- whether or not we highlight the dimmer while adjusting it
local useDistance = 20 -- the max distance the dimmer can be used from

local params = RaycastParams.new() -- the parameters for our raycast
params.FilterType = Enum.RaycastFilterType.Blacklist
params.IgnoreWater = true


-- returns the RaycastResult if there is one
local function getCursorInfo(x, y)
	params.FilterDescendantsInstances = {player.Character} -- we are defining this variable to use the player’s current character

	local cameraRay = camera:ScreenPointToRay(x, y)

	return workspace:Raycast(cameraRay.Origin, cameraRay.Direction * leverDistance, params) -- returns the RaycastResult or nil if there is none
end

local adjustingDimmer = false
userInputService.InputBegan:Connect(function(inputObject, gameProcessed)
	if not gameProcessed and inputObject.UserInputType == Enum.UserInputType.MouseButton1 or inputObject.UserInputType == Enum.UserInputType.Touch then
		local result = getCursorInfo(inputObject.Position.X, inputObject.Position.Y)

		if result and not adjustingDimmer and result.Instance == dimmer or result.Instance:FindFirstAncestor(dimmer) then
			if highlightSwitch then
				highlighter.Parent = workspace
				highlighter.Adornee = dimmer
			else
				highlighter.Adornee = nil
			end

			adjustingDimmer = userInputService.InputEnded:Connect(function(input)
				adjustingDimmer:Disconnect()
				adjustingDimmer = false

				highlighter.Adornee = nil
			end)

			-- your code for adjusting the dimmer or lever or whatever. I forgot how I implemented this for the dimmer and am not willing to try without trial and error. I believe I used the InputObject.Delta property for this though. I can’t be sure though.
		end
	end
end)

Note:
You should put the local script in StarterPlayerScripts | Roblox Creator Documentation. Also, as previously mentioned, this code is untested and may have execution errors, formatting errors, or just plain not work for a reason currently unfathomable to me. Once I am able to actually test this I will post a working example for you and/or others in the future who need this.

1 Like

ty bro, im in school rn but ill let you know how it goes in a few hours or so

Alright, so I created a dimmer, but I’m on my phone right now and won’t be able to access my computer for about a week (vacation) and forgot to post it while I was on my computer. Sorry for the delay.

np bro, ty and lmk when u can :smiley:

Not really sure, I didn’t mean to do it on purpose

Alright, so after getting back I looked at my code and fixed a few things I missed to optimize it better. I’m also improving the design a bit because I’m a perfectionist. It should be completely done tomorrow.

1 Like

I ended up completely re-doing my old system for dragging the dimmer. It can now be used in any orientation you see fit and it performs better.

Anyways, here’s the dimmer on it’s own:

and here is an example using it:

i managed to use this and implement it into my own system so cheers lad :smiley:

1 Like