So I have a part that spins depending on where the mouse is.
I need to make it so It only spins if the mouse is moving and not so it is always spinning.
-- services
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Text = script.Parent.TextLabel -- display text
local middlePoX = 712
local middlePoY = 400
local turnXLeft = 612
local turnXRight = 812
local testPart = workspace.Part
RunService.RenderStepped:Connect(function()
local mouseLocation = UserInputService:GetMouseLocation()
Text.Text = mouseLocation.X .. " " .. mouseLocation.Y
local x = mouseLocation.X
local y = mouseLocation.Y
local xTurnAmount = x / 5
local yTurnAmount = y / 5
print(xTurnAmount)
if x > turnXRight then -- turn to the right
local cframe = CFrame.Angles(-xTurnAmount,0,0)
testPart.CFrame = cframe -- set the cframe
elseif x < turnXLeft then -- turn to the left
local cframe = CFrame.Angles(xTurnAmount,0,0)
testPart.CFrame = cframe -- set the cframe
end
task.wait()
end)
-- services
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Text = script.Parent.TextLabel -- display text
local middlePoX = 712
local middlePoY = 400
local turnXLeft = 612
local turnXRight = 812
local testPart = workspace.Part
local Coroutine = coroutine.create(function()
while task.wait() do
local mouseLocation = UserInputService:GetMouseLocation()
Text.Text = mouseLocation.X .. " " .. mouseLocation.Y
local x = mouseLocation.X
local y = mouseLocation.Y
local xTurnAmount = x / 5
local yTurnAmount = y / 5
print(xTurnAmount)
if x > turnXRight then -- turn to the right
local cframe = CFrame.Angles(-xTurnAmount,0,0)
testPart.CFrame = cframe -- set the cframe
elseif x < turnXLeft then -- turn to the left
local cframe = CFrame.Angles(xTurnAmount,0,0)
testPart.CFrame = cframe -- set the cframe
end
end
end)
UserInputService.InputBegan:Connect(function(Type)
if Type == Enum.UserInputType.MouseMovement then
Coroutine.resume()
end
end)
UserInputService.InputEnded:Connect(function(Type)
if Type == Enum.UserInputType.MouseMovement then
Coroutine.yield()
end
end)
Coroutines are a way to yeild and resume functions without having to call a new one. The code given above pauses the loop if the mouse isn’t moving, and resumes it once it starts.
Also if you want to find if the mouse is moving, you can use:
local MouseDelta = UserInputService:GetMouseDelta()
This describes how far the mouse has moved in pixels as a vector2
This code should hopefully be more efficient as it uses a movement event instead of a frame updater:
local UIS = game:GetService("UserInputService")
local oldPos = UIS:GetMouseLocation()
local function GetMouseDelta()
local curPos = UIS:GetMouseLocation()
local delta = curPos - oldPos
oldPos = curPos
return delta
end
local part = workspace.Part
UIS.InputChanged:Connect(function(input, gp)
if input.UserInputType == Enum.UserInputType.MouseMovement then
local delta = GetMouseDelta()
part.CFrame *= CFrame.Angles(0, math.rad(delta.X), 0) --// remove the * from *= to make it non-cumulative
end
end)
You may need to move math.rad(delta.X) to a different CFrame.Angles(0,0,0) slot depending on how you want it to rotate.
Here you go. All that happens is we grab the mouse delta and put it into a CFrame value.
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Text = script.Parent.TextLabel -- display text
local testPart = workspace.Part
RunService.RenderStepped:Connect(function()
local MouseDelta = UserInputService:GetMouseDelta()--mouse movement in pixels, returns vector2
Text.Text = MouseDelta.X .. " " .. MouseDelta.Y
local xTurnAmount = MouseDelta.X / 5 --adjusts the mouseDelta to your liking
local yTurnAmount = MouseDelta.Y / 5
print(xTurnAmount, yTurnAmount)
local testPart.CFrame = CFrame.Angles(-yTurnAmount, xTurnAmount, 0) --remember that CFrame angles sometimes are not applied in x,y,z order, but in this case that does not matter
task.wait()
end)
Do note that if the mouse it not moving, the delta is 0 and therefore the “angle” is set back to 0,0,0. To change that simply change:
Ok after doing this yes it works so thank you. but I relized I need something else.
Do you know how I would make it so the testpart points upwards is the direction of the mouse X position?
That way if I move my mouse to the side the part is then pointed up towards it
CFrame has a handy dandy thing called “lookat” that does exactly what you want
local UserInputService = game:GetService("UserInputService")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local RunService = game:GetService("RunService")
local Text = script.Parent.TextLabel -- display text
local testPart = workspace.Part
RunService.RenderStepped:Connect(function()
local MousePos = Mouse.Hit.Position
local PointingAt = MousePos - testPart.CFrame.Position
testPart.CFrame = CFrame.lookAt(testPart.CFrame.Position, PointingAt)
task.wait()
end)
Ok so there is one problem with this. It is pointing off into the distance. Where as I need it to point directly up towards the mouse like in the video. How would I do this?
Most airplane simulators use the physics engine to calculate rotation and position. In that game, the mouse is used to add forces onto the aircraft to make it steer where you want to. Unfortunatly i don’t have a solution for that.
also I saw an error so please change PointingAt to:
local PointingAt = MousePos - testPart.CFrame.Position