Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

how do I make my model rotate when button pushed?

So I have this script but it doesn't work their is no errors or warnings or output I have clicked it multiple times but it doesn't work. I have put the click detector in the button and the script in the click detector I don't know what else to do. please help me.

function onClicked()
	print("Working")
	local p = game.Workspace.Spinner.moving
	local cf = CFrame.Angles(0, 0,math.rad(10))
	for i = 1, 200 do
	p.CFrame = p.CFrame * cf
	wait(1)
	end
end
script.Parent.ClickDetector.MouseClick:connect(onClicked)

1 comment

0

hmm... ill see if i can come up with something...

1 answer

✓ Accepted answer

I've managed to make something that works well with your script and its "plug in play" meaning you simply put your model in the Spinner group and the script takes care of the rest. If you want to control where it rotates from just update the Model.PrimaryPart and the position from your spinner part, But this is optional as i've included a PrimaryPart Finder.

The primary part Finder works out the centre of your model and sets the closest Part to that point as Model.PrimaryPart. If the Model.PrimaryPart is set it simply returns/welds everything to that part!, Cool huh?

The only downside is everything in the model will be frozen/welded to that Primary part.

Edit: Changed the code to include a Timer set to 60 secs and a way of easily changing the rotation direction and how much it rotates by. Like in your example you had it rotating by 10 rotation points. You can now change that by adjusting the SpinStep

I've also included a relatively simple way of resetting the rotation back to how it was when you first started. Though I wouldn't be surprised if it doesn't break lol. It was an afterthought lol xD

The Updated Code:

local DoReset = true -- switch this to false if you don't need to reset the rotation!.

--// this value accepts X,Y And Z also -X,-Y and -Z (Also lowercase also works!)
local SpinRotation = "z"

--// this is how much to rotate in the chosen direction, Bigger this number the more it "jumps"
local SpinStep = 10

--// how long to rotate for
local RotationTime = 60 -- in seconds!

--// set this to your main Spinner Group Name that can be found in your workspace!
local SpinnerGroup = workspace:FindFirstChild("Spinner")
if(SpinnerGroup == nil) then error("Spinner Group is nil! and cannot be found!") end

--// Set this to the Axel (the bit that rotates) inside that Spinner Group!
local Axel = SpinnerGroup:FindFirstChild("moving")
if(Axel == nil) then error("Axel is nil! and cannot be found!") end

--// this next bit is to hook up any Model objects put inside the Spinner group and work on it as we rotate!
--// if you offset each of the models from your spinner it should rotate it from that point!
--// this should be automatic!
--[[
	Example on workflow:
	Explorer Structure:
	
	Workspace
	|¬ Camera
	|¬ Terrain
	|¬ Spinner  		<-- This is your main Group for this Script!
	   |--¬ <Model that needs to be rotated>
	   |--¬ spinner 	<-- the Bit that actualy rotates
	     
	|¬ <Other Stuff in Workspace>
	
	....
	
	|¬ Players
	|¬ Lighting 
	|¬ <etc....>
]]

local ModelsToRotate = (function()
	local Models = {}
	local ModelObjs = SpinnerGroup:GetChildren()
	--// main function for retieving the Primary part of a model if it isnt set! if it is then it simply returns it!
	local getPrimaryPartfrom = function(mod)
		local PP = mod.PrimaryPart
		--// If model primarypart is nil then set it to the closest middle part...
		local ModelCenter = Vector3.new()
		local ModelParts = {} 
		local X,Y,Z = 0,0,0 
		if(PP == nil) then
			local Parts = mod:GetDescendants()
			local Num = 0
			--// get the positions of each and EVERY part inside the model... 
			for k,v in pairs(Parts) do
				if(v:IsA("BasePart") == true) then
					local Pos = v.Position
					--// Add them to the semi-global X,Y and Z
					X = X + Pos.X
					Y = Y + Pos.Y
					Z = Z + Pos.Z
					Num = Num + 1
					--// reference the part in Table for later use...
					ModelParts[#ModelParts+1] = v
				end
			end
			--// work out the average or mean of each axis 
			X = X/Num
			Y = Y/Num
			Z = Z/Num
			--// set the model center to a Vector3 Point
			ModelCenter = Vector3.new(X,Y,Z)
		end
		--// The following code works out the closest part to the ModelCenter point set above!
		local Dist = math.huge
		for k,v in pairs(ModelParts) do
			local dist = (ModelCenter - v.Position).magnitude
			if(dist < Dist) then
				Dist = dist
				PP = v
			end 
		end
		--// return the Closest Part to the model centre
		return PP
	end
	--// make up the Global callback table [Models] into something we can use to rotate the models with!
	for k,model in pairs(ModelObjs) do
		if(model:IsA("Model") == true) then
			local PPart = getPrimaryPartfrom(model) 
			Models[#Models+1] ={
				Model = model,
				PrimaryPart = PPart
			}
			model.PrimaryPart = PPart
		end
	end
	--// return the callback table!
	return Models
end)()

--// rig each model ready for moving and rotation NOTE: if the model has constaints it will freeze them!
for k,mod in pairs(ModelsToRotate) do
	local Model = mod.Model
	local BasePart = mod.PrimaryPart
	local Parts = Model:GetDescendants()
	for k,part in pairs(Parts) do
		if(part:IsA("BasePart")== true) then
			local Weld = Instance.new("WeldConstraint",BasePart)
			Weld.Part0 = BasePart
			Weld.Part1 = part
			if(part.Anchored == true) then
				part.Anchored = false
			end
		end
	end
	--// weld each model PrimaryPart to the Axel
	local MainWeld = Instance.new("WeldConstraint",BasePart)
	MainWeld.Part0 = Axel
	MainWeld.Part1 = BasePart
end


--// Function for getting the current orintation of our Axel and return it as RotX, RotY, RotZ 
local function getOrientation(CF)
	local sx, sy, sz, m00, m01, m02, m10, m11, m12, m20, m21, m22 = CF:components()
	local Y = math.atan2(m02, m22)*(180/math.pi)+180
	local X = math.asin(-m12)*(180/math.pi)+180
	local Z = math.atan2(m10, m11)*(180/math.pi)+180
	return Vector3.new(X,Y,Z)
end




--// these are internal don't touch unless you know what you're doing!
local t = 0
local Clicked = false
local SwitchedOff = false
local ClickDB = false
local oldsecs = 0
local OriginalRot = getOrientation(Axel.CFrame)

--// main Function for switching the rotation Axes and Applying the Rotation Step!
--// Shouldn't need to touch this, Unless i messed up someplace... lol
function SetAngles(newRot)
	if(newRot == nil) then newRot = SpinRotation end
	--print(newRot)
	newRot = string.lower(newRot)
	if(newRot == "x") then 	return CFrame.Angles(math.rad(SpinStep),0,0)	end
	if(newRot == "-x") then return CFrame.Angles(-math.rad(SpinStep),0,0)	end
	if(newRot == "y") then 	return CFrame.Angles(0,math.rad(SpinStep),0)	end
	if(newRot == "-y") then return CFrame.Angles(0,-math.rad(SpinStep),0)	end
	if(newRot == "z") then 	return CFrame.Angles(0,0,math.rad(SpinStep))	end
	if(newRot == "-z") then return CFrame.Angles(0,0,-math.rad(SpinStep))	end

end
--// a function for rounding off a Vector
local function math_floor(V3)
	return Vector3.new(math.floor(V3.X)+0.5,math.floor(V3.Y)+0.5,math.floor(V3.Z)+0.5)
end

--// this is optinal if you don't need color just remove this bit
script.Parent.Color = Color3.fromRGB(0,255,0)

--// main hookup for our ClickDetector
script.Parent.ClickDetector.MouseClick:connect(function(player)
	Clicked = not Clicked
	if(Clicked == true) then
		--// remove this Color Changer if not using color and leave this blank
		script.Parent.Color = Color3.fromRGB(255,255,0)
	else
		SwitchedOff = true
		--// remove this Color Changer if not using color but leave the above SwitchedOff = true as its needed!
		script.Parent.Color = Color3.fromRGB(255,0,0)
	end
	--// main loop for rotating our object(s)
	while Clicked == true and SwitchedOff == false do
		--// if user has clicked the button again while we're rotating then stop or reverse to starting point (If set!)
		if(Clicked == false) then break	end
		
		--// What our target is in mili-seconds!
		local GetTo = RotationTime * 30
		--// the actual time in seconds!
		local secs = math.floor((t /30)+0.5)
		
		-- ####################################################
		--//This bit is optional!
		--// only print out the time when the above changes!
		if(secs ~= oldsecs) then
			print("Seconds Running: "..secs)
		end
		--// change check
		oldsecs = secs
		-- ####################################################

		local cf = SetAngles()
		Axel.CFrame = Axel.CFrame * cf
		
		--// if the time equals the RotationTime then break out of this loop
		if(t <= GetTo) then	t = t +1 else Clicked = false t = 0 break end
		wait()
	end
	--// if User has canceled rotation before the above time has been reached then stop (or return to starting point!)
	if(SwitchedOff == true and Clicked == false) then
		if(DoReset == true) then
			while SwitchedOff == true do
				local bHasDash = SpinRotation:find("-") ~= nil
				local ReverseDir = bHasDash == true and SpinRotation:sub(2,2) or "-"..SpinRotation
				local cf = SetAngles(ReverseDir)
				local MyRot = getOrientation(Axel.CFrame)
				if(math_floor(MyRot) ~= math_floor(OriginalRot)) then
					Axel.CFrame = Axel.CFrame * cf
				else
					SwitchedOff = false
				end
				wait()
			end	
		end
		SwitchedOff = false
	end
	t = 0
	wait(1)
	--// optional Color stuff!
	script.Parent.Color = Color3.fromRGB(0,255,0)

	print("Done!")
end)

How to use: Simply move your models that you want to rotate inside the Spinner Group and the script will take care of the rest!. Just make sure you're happy with the position and starting rotation!

Edit: So you should be able to copy and paste this into your spinner code and set the groups and axel properly and any model(s) you want to rotate, Plus the rotation direction And Rotation step. Breath

So you should be good to go!

Hope this helps and if you have any problems let me know!

Peace! :)

4 comments

0

so how will i adapt this so that when i press a button it will automatically turn the model for like 60 seconds

0

Just updated the Code to include a timer and a few little extras! :)

0

Forgive me if i have spelling errors or typos in it lol

0

@TGazza thanks

This discussion is preserved as it was. New answers, comments, and votes are closed.