Hello, I have a car model, and I want to make it rotate itself, but I don’t know how to do that with scripts. I would like some tutorials or examples. Thank you.
Set a primary part of the model and then change the primary part of the cframe:
For example to rotate the model 90 degrees to the left you would do:
rotation = CFrame.Angles(0, math.rad(90), 0)
modelCFrame = model:GetPrimaryPartCFrame()
model:SetPrimaryPartCFrame( modelCFrame * rotation )
Make sure that the front face of the primary part is facing towards the front of the car.
EDIT: THIS IS NOT LONGER ACCURATE AS SETPRIMARYPARTCFRAME() IS BEING DEPRECATED
Please use Model:PivotTo(targetCFrame) like in the following code and ignore the above code:
rotation = CFrame.Angles(0, math.rad(90), 0)
modelCFrame = model:GetPivot()
model:PivotTo(modelCFrame * rotation)
Thanks, but is there a way to slowly have a transition of rotation? I tried writing this from getting the idea from a YouTube tutorial video, but it doesn’t seem to work.
Here is the script:
wait(5)
script.Parent:SetPrimaryPartCFrame(script.Parent:GetPrimaryPartCFrame() * CFrame.Angles(0, math.rad(90), 0))
Hi yes there is sorry for the late reply. You can do this:
local cframeTween = Instance.new("CFrameValue")
cframeTween.Value = script.Parent:GetPrimaryPartCFrame() -- Starter Cframe
game:GetService("TweenService"):Create(cframeTween, TweenInfo.new(1), {Value = script.Parent:GetPrimaryPartCFrame() * CFrame.Angles(0, math.rad(90), 0)}):Play()
cframeTween:GetPropertyChangedSignal("Value"):Connect(function()
script.Parent:SetPrimaryPartCFrame(cframeTween.Value)
end)
I would suggest against using supergreatr299’s method because while it absolutely is a valid way to go about this, there is a cleaner one that does not rely on the creation of a ghost tween.
- Give your car model a
PrimaryPart
if it doesn’t have one. - Use constraints (such as weld constraints for parts that do not need to move on their own)
- Use
TweenService
to tween the rotation of thePrimaryPart.CFrame
of the model.
local carPrimaryPart = -- insert PrimaryPart here
local TweenService = game:GetService("TweenService")
local carTweenInfo = TweenInfo.new(-- specify duration, etc.)
local newCFrame = carPrimaryPart.CFrame * CFrame.Angles(0, math.rad(90), 0)
local carRotationTween = TweenService:create(carPrimaryPart, carTweenInfo, {CFrame = newCFrame})
carRotationTween:Play()
If you have properly attached all parts of your model to the PrimaryPart, the entire model will rotate smoothly. Hope this helps!
By the meaning of “Specify durations, etc.”, do I put a number? Can you please show me an example? Thanks.
Those are the arguments passed in TweenInfo class constructor method (the new function).
It is as follows: TweenInfo (roblox.com)
TweenInfo.new ( number time = 1.0, Enum easingStyle = Enum.EasingStyle.Quad, Enum easingDirection = Enum.EasingDirection.Out, number repeatCount = 0, bool reverses = false, number delayTime = 0 )
Real example:
local tweenInfo = TweenInfo.new(10, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
The rest of the arguments are optional.
Thanks, I couldn’t understand what to write.
Hi! Did you manage to get this working?
If not, I’ll show you my secrets haha. I’ve been looking on tweening entire models for ages and have been nearly eating my keyboard before I finally found out how to do this lol. I decided to make a little plug-in for it.
Prerequisites
- My plug-in: https://www.roblox.com/library/6588939999/Jonas-Weld-Entire-Model
- A model (the one you want to rotate)
- Make sure these options are selected on the “Model” tab in studio (on top of your screen):
First step: welding the model
This makes sure that everything will turn with the part we’ll tween in the second step.
- Set one part of the model as
PrimaryPart
. - Now, select the model.
- Press the “Weld model” button from your plug-in toolbar.
- You should now see that the welds have been created:
Second part: scripting the movement!
I’ll post the script we used in V3 of Go-Karting Xtreme here. You’ll need to modify in order to make it rotate, as this was for a sliding roof from our racing track
The GameSettings.Track.BigRoof1
stuff just refers to an ObjectValue which refers to the model.
You might also see the name “WeldEndPart” but it’s basically a part which is there so we can easily move it instead of editing the scripts if we ever needed to adjust the tween. You can just put a CFrame there.
--[[
Name: TrackDoors
Author: Jonas
Description: Track Doors API
© 2021 Go-Karting Xtreme
]]
local Services = {
TweenService = game:GetService("TweenService");
}
local GameSettings = game.ServerScriptService.GameSettings;
local Dependencies = game:GetService("ServerScriptService"):WaitForChild("Dependencies")
local API = {}
local AnimationDuration = 50;
local originalPositions = {};
local currentState = "closed";
local debounce = false;
function openTrack(doorLabel,duration)
local TweenService = game:GetService("TweenService")
local Group = doorLabel.value
local PrimaryPart = Group.PrimaryPart
local PanelSlideInfo = TweenInfo.new(
duration,
Enum.EasingStyle.Quad,
Enum.EasingDirection.InOut
)
local PanelSlideTween = TweenService:Create(PrimaryPart, PanelSlideInfo, {
CFrame = Group.WeldEndPart.CFrame
})
PanelSlideTween:Play()
end
function closeTrack(doorLabel, duration)
local TweenService = game:GetService("TweenService")
local Group = doorLabel.value
local PrimaryPart = Group.PrimaryPart
local PanelSlideInfo = TweenInfo.new(
duration,
Enum.EasingStyle.Quad,
Enum.EasingDirection.InOut
)
local PanelSlideTween = TweenService:Create(PrimaryPart, PanelSlideInfo, {
CFrame = Group.OriginalPosition.CFrame
})
PanelSlideTween:Play()
end
-------------------------------------------------------------------
function API:Open()
if debounce or currentState == "open" then
return "debouncing"
end;
debounce = true;
-- Smallest parts
originalPositions["SmallRoof1"] = GameSettings.Track.SmallRoof1.Value.PrimaryPart.CFrame;
openTrack(GameSettings.Track.SmallRoof1,AnimationDuration);
originalPositions["SmallRoof2"] = GameSettings.Track.SmallRoof2.Value.PrimaryPart.CFrame;
openTrack(GameSettings.Track.SmallRoof2,AnimationDuration);
-- Bigger parts
originalPositions["BigRoof1"] = GameSettings.Track.BigRoof1.Value.PrimaryPart.CFrame;
openTrack(GameSettings.Track.BigRoof1,AnimationDuration);
originalPositions["BigRoof2"] = GameSettings.Track.BigRoof2.Value.PrimaryPart.CFrame;
openTrack(GameSettings.Track.BigRoof2,AnimationDuration);
wait(AnimationDuration);
debounce = false;
currentState = "open"
return "done";
end
function API:Close()
if debounce or currentState == "closed" then
return "debouncing"
end;
debounce = true;
-- Smallest parts
closeTrack(GameSettings.Track.SmallRoof1,AnimationDuration);
closeTrack(GameSettings.Track.SmallRoof2,AnimationDuration);
-- Bigger parts
closeTrack(GameSettings.Track.BigRoof1,AnimationDuration);
closeTrack(GameSettings.Track.BigRoof2,AnimationDuration);
wait(AnimationDuration);
debounce = false;
currentState = "closed"
return "done";
end
-------------------------------------------------------------------
return API
Make sure to let me know if you have any questions!
Before I forget, you can use CFrame tweening (what was used here) for rotations as well Refer to the replies above mine for that!
Thanks, but I’m not trying to create a opening door, and I haven’t tried filling out the TweenInfo, so I don’t know if it works.
I’m pretty sure SetPrimaryPartCFrame has some floating point issues that cause the model to slightly move apart each time it is called, so you should use PivotTo instead.
It should also work with what you’re trying to do. However, feel free to try out whatever you think fits and keep me posted!
Thanks, it worked for the direction, but it didn’t work the way I wanted it to work. I want the car to actually turn, but it just goes towards the direction, which I set it to 45 degrees.
Maybe, can you help me with this, @supergreatr299?
This is a video showing you my explanation:
Oh yeah I just read up on that, thank you.
cant thank you enough bro, need this badly
What’s crazy is that I essentially did the same thing, but it won’t actually do it?
The same formula works on my other functions but not here…
local posPivot = GhostObject:GetPivot()
local orX, orY, orZ = GhostObject:GetPivot():ToOrientation()
local orYDeg = math.deg(orY)
if orYDeg >= 0 and orYDeg <= 45 then
GhostObject:PivotTo(posPivot * CFrame.Angles(0, math.rad(0), 0))
elseif orYDeg >= 45 and orYDeg <= 90 then
GhostObject:PivotTo(posPivot * CFrame.Angles(0, math.rad(90), 0))
elseif orYDeg >= 90 and orYDeg <= 180 then
GhostObject:PivotTo(posPivot * CFrame.Angles(0, math.rad(180), 0))
elseif orYDeg <= -45 and orYDeg >= -90 then
GhostObject:PivotTo(posPivot * CFrame.Angles(0, math.rad(-90), 0))
elseif orYDeg <= 0 and orYDeg >= -45 then
GhostObject:PivotTo(posPivot * CFrame.Angles(0, math.rad(0), 0))
end
Managed to fix it, just had to remove the posPivot.