So basically, I’m trying to make a system where I can rotate a “preview” of a part
Now, I want there to be support for rotating models but issue is, I can’t seem to find a way to rotate the primary part
If I just rotate it using orientation, for some reason every part EXCEPT for the primary part rotates?
I figured it was because the weld was breaking, so I tried rotating with CFrame, but all the posts I found gave extremely weird glitches were some but not all of the parts were rotating and of course, the primary part still didn’t budge.
I tried using a for loop in order to rotate every part individually but that didn’t work the way I wanted it to, and of course the primarypart still isn’t rotating.
function rotateT(obj)
if obj then
if obj:IsA("Model") then
if not obj.PrimaryPart then
return
end
obj.PrimaryPart.CFrame = obj.PrimaryPart.CFrame * CFrame.Angles(math.rad(0),math.rad(0),math.rad(90))
elseif obj:IsA("BasePart") then
obj.Orientation += Vector3.new(0,0,90)
end
end
end
This is just a small section of the code, so if you want the rest of it ask me.
Also, it uses RunService’s BindToRenderStep() so maybe there’s something to do with that?
Video about issue with rotating the primary part using CFrame or Vector3
For some reason, it doesn’t move at all, is there something wrong with the primary part?
I had loads of errors about the primary part not existing which is why I added the if statement to check if it was there.
Have you tried adding some “print” statements through your code to check how far it’s getting.
And for Models it really shouldn’t matter if it has a PrimaryPart or not. Since you should be using :PivotTo on the Model itself.
function rotateT(obj)
if obj then
if obj:IsA("Model") then
print("is a model")
obj:PivotTo(obj:GetPivot() * CFrame.Angles(math.rad(0),math.rad(0),math.rad(90)))
elseif obj:IsA("BasePart") then
obj.Orientation += Vector3.new(0,0,90)
end
end
end
As a quick test I threw this together and the part is rotating.
local tm = workspace.TestModel
while true do
task.wait(1)
print(tm:GetPivot())
tm:PivotTo(tm:GetPivot() * CFrame.Angles(math.rad(0),math.rad(0),math.rad(10)))
end
Yes, I removed them to make it more readable for this post.
The reason why I’m so concerned about the primary part is because it’s the most important part for the model, what I mean is that it’s a “hitbox” which is very important for the model to do what its supposed to do once its placed.
Also, I need to choose a part to run these lines of codes on clone:PivotTo(CFrame.new(result.Position + result.Normal * clone.PrimaryPart.Size.Y/2))
Choosing it randomly wouldn’t be the greatest.
I tried without the primary part and even without it, the function failed.
What the hell is going on with my code
Yeah, it’s normal and probably good for your models to still have a primaryPart defined. The main thing is you should be PivotTo to make sure the whole model, not just the primary part gets moved.
And as for your other snippet, depending on what your model looks like it could also be independent of the primaryPart by going off of the model’s size instead of the primaryPart’s size
Yeah I think changing all references of obj.PrimaryPart.CFrame to either obj:GetPivot() or obj:SetPivot() as @CookieAroundTheBend suggested should do the trick. Since you are working with these methods you won’t need to worry about the madness of welding, so you can just delete those and set all of your parts to be anchored. That should save you a headache as well.
I removed primary parts, welds and replaced all references with what you told me to do and I’m still stumped.
Here’s my whole script I don’t know what’s going on
Script
-- services
local runservice = game:GetService("RunService")
local repstore = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local uis = game:GetService("UserInputService")
local tweenservice = game:GetService("TweenService")
local cas = game:GetService("ContextActionService")
-- stuff to do with the player
local char = script.Parent
local plr = players:GetPlayerFromCharacter(char)
local mouse = plr:GetMouse()
local camera = workspace.CurrentCamera
local gui = plr.PlayerGui.Cancel
local returned = false
-- stuff in replicatedstorage
local parts = repstore.Previews
local remoteevent = repstore.Place
local fail = repstore.Failed
local mobile = plr.PlayerGui.Bool
-- deb
local deb = false
local deb2 = false
function rotateR(obj)
if obj then
if obj:IsA("Model") then
obj:PivotTo(obj:GetPivot() * CFrame.Angles(math.rad(0),math.rad(15),math.rad(0)))
elseif obj:IsA("BasePart") then
obj.Orientation += Vector3.new(0,15,0)
end
end
end
function rotateT(obj)
if obj then
if obj:IsA("Model") then
print("aed")
obj:PivotTo(obj:GetPivot() * CFrame.Angles(math.rad(0),math.rad(0),math.rad(90)))
elseif obj:IsA("BasePart") then
obj.Orientation += Vector3.new(0,0,90)
end
end
end
repstore.Other.OnClientEvent:Connect(function(part)
if plr.Character.Stacked.Value > 1 then
return
end
local part = parts:FindFirstChild(part)
if not part then
warn("Client returned nil")
return
end
gui.Enabled = true
local function preview()
local clone = part:Clone()
clone.Parent = workspace.Previews
return clone
end
local clone = preview()
local param = RaycastParams.new()
param:AddToFilter(script.Parent)
local function render()
local location = uis:GetMouseLocation()
local direction = camera:ViewportPointToRay(location.X, location.Y)
local result = workspace:Raycast(direction.Origin, direction.Direction * 1000, param)
if plr.Items:FindFirstChild(clone.Name) then
if plr.Items:FindFirstChild(clone.Name).Value <=0 then
clone:Destroy()
end
end
if result and clone then
if clone:IsA("Model") then
clone:PivotTo(CFrame.new(result.Position + result.Normal * clone:GetExtentsSize()/2))
elseif clone:IsA("BasePart") then
clone.Position = result.Position + result.Normal * clone.Size.Y/2
end
end
end
cas:BindActionAtPriority("RotateSideways", function(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
rotateR(clone) end end, true, 2)
cas:BindActionAtPriority("RotateFowards", function(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
rotateT(clone) end end, true, 2)
cas:SetTitle("RotateSideways", "Rotate")
cas:SetDescription("RotateSideways", "Af")
cas:SetTitle("RotateFowards", "Rotate Up")
cas:SetPosition("RotateSideways", UDim2.new(0.3,0,0.56,0))
cas:SetPosition("RotateFowards", UDim2.new(0.05,0,0.56,0))
runservice:BindToRenderStep("Preview", Enum.RenderPriority.Camera.Value, render)
uis.InputBegan:Connect(function(input, grp)
if grp then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if clone and not deb then
gui.Enabled = false
if clone:IsA("BasePart") then
remoteevent:FireServer(clone.CFrame, clone.Name)
elseif clone:IsA("Model") then
remoteevent:FireServer(clone:GetPivot(), clone.Name)
end
end
elseif input.UserInputType == Enum.UserInputType.Touch then
mobile.Value = true
elseif input.KeyCode == Enum.KeyCode.R then
rotateR(clone)
print("errr")
elseif input.KeyCode == Enum.KeyCode.T then
rotateT(clone)
end
end)
mobile.Changed:Connect(function()
if mobile.Value == false then
cas:UnbindAction("RotateSideways")
cas:UnbindAction("RotateFowards")
end
end)
uis.InputEnded:Connect(function(input, grp)
if not grp and input.UserInputType == Enum.UserInputType.Touch then
if mobile.Value == true then
return
end
mobile.Value = false
gui.Enabled = false
print("err")
cas:UnbindAction("RotateSideways")
cas:UnbindAction("RotateFowards")
remoteevent:FireServer(clone:GetPivot(), clone.Name)
print(clone.CFrame)
end
end)
end)
Ah okay so the problem here is that while you are updating the rotation, it’s only there for a frame until it is undone by the call to PivotTo in the next frame:
This constructor contains no information on orientation, meaning the model will revert to its “0, 0, 0” orientation. Maybe you could create a variable to keep track of the rotation that the user has applied? Then, instead of making calls to rotateR and rotateT, you would update this rotation variable. To increment the rotation, you could do something like:
-- services
local runservice = game:GetService("RunService")
local repstore = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local uis = game:GetService("UserInputService")
local tweenservice = game:GetService("TweenService")
local cas = game:GetService("ContextActionService")
-- stuff to do with the player
local char = script.Parent
local plr = players:GetPlayerFromCharacter(char)
local mouse = plr:GetMouse()
local camera = workspace.CurrentCamera
local gui = plr.PlayerGui.Cancel
local returned = false
local rotation = CFrame.new()
-- stuff in replicatedstorage
local parts = repstore.Previews
local remoteevent = repstore.Place
local fail = repstore.Failed
local mobile = plr.PlayerGui.Bool
-- deb
local deb = false
local deb2 = false
function rotateR(obj)
if obj then
rotation *= CFrame.fromEulerAnglesXYZ(0, math.rad(15), 0)
end
end
function rotateT(obj)
if obj then
print("aed")
rotation *= CFrame.fromEulerAnglesXYZ(0, 0, math.random(90))
end
end
repstore.Other.OnClientEvent:Connect(function(part)
if plr.Character.Stacked.Value > 1 then
return
end
local part = parts:FindFirstChild(part)
if not part then
warn("Client returned nil")
return
end
gui.Enabled = true
local function preview()
local clone = part:Clone()
clone.Parent = workspace.Previews
return clone
end
local clone = preview()
local param = RaycastParams.new()
param:AddToFilter(script.Parent)
local function render()
local location = uis:GetMouseLocation()
local direction = camera:ViewportPointToRay(location.X, location.Y)
local result = workspace:Raycast(direction.Origin, direction.Direction * 1000, param)
if plr.Items:FindFirstChild(clone.Name) then
if plr.Items:FindFirstChild(clone.Name).Value <=0 then
clone:Destroy()
end
end
if result and clone then
if clone:IsA("Model") then
local offset = CFrame.new(result.Position + result.Normal * clone:GetExtentsSize()/2)
clone:PivotTo(offset * rotation)
elseif clone:IsA("BasePart") then
local offset = CFrame.new(result.Position + result.Normal * clone.Size.Y/2)
clone:PivotTo(offset * rotation)
end
end
end
cas:BindActionAtPriority("RotateSideways", function(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
rotateR(clone) end end, true, 2)
cas:BindActionAtPriority("RotateFowards", function(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
rotateT(clone) end end, true, 2)
cas:SetTitle("RotateSideways", "Rotate")
cas:SetDescription("RotateSideways", "Af")
cas:SetTitle("RotateFowards", "Rotate Up")
cas:SetPosition("RotateSideways", UDim2.new(0.3,0,0.56,0))
cas:SetPosition("RotateFowards", UDim2.new(0.05,0,0.56,0))
runservice:BindToRenderStep("Preview", Enum.RenderPriority.Camera.Value, render)
uis.InputBegan:Connect(function(input, grp)
if grp then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if clone and not deb then
gui.Enabled = false
if clone:IsA("BasePart") then
remoteevent:FireServer(clone.CFrame, clone.Name)
elseif clone:IsA("Model") then
remoteevent:FireServer(clone:GetPivot(), clone.Name)
end
end
elseif input.UserInputType == Enum.UserInputType.Touch then
mobile.Value = true
elseif input.KeyCode == Enum.KeyCode.R then
rotateR(clone)
print("errr")
elseif input.KeyCode == Enum.KeyCode.T then
rotateT(clone)
end
end)
mobile.Changed:Connect(function()
if mobile.Value == false then
cas:UnbindAction("RotateSideways")
cas:UnbindAction("RotateFowards")
end
end)
uis.InputEnded:Connect(function(input, grp)
if not grp and input.UserInputType == Enum.UserInputType.Touch then
if mobile.Value == true then
return
end
mobile.Value = false
gui.Enabled = false
print("err")
cas:UnbindAction("RotateSideways")
cas:UnbindAction("RotateFowards")
remoteevent:FireServer(clone:GetPivot(), clone.Name)
print(clone.CFrame)
end
end)
end)
````Preformatted text`