Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

how do I make my model rotate when button pushed?

Asked by 3 years ago

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)
0
hmm... ill see if i can come up with something... TGazza 1336 — 3y

1 answer

Log in to vote
0
Answered by
TGazza 1336 Moderation Voter
3 years ago
Edited 3 years ago

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! :)

0
so how will i adapt this so that when i press a button it will automatically turn the model for like 60 seconds UNIMAKZIN00 41 — 3y
0
Just updated the Code to include a timer and a few little extras! :) TGazza 1336 — 3y
0
Forgive me if i have spelling errors or typos in it lol TGazza 1336 — 3y
0
@TGazza thanks UNIMAKZIN00 41 — 3y
Ad

Answer this question