ViewportFrame rotation buttons not working

Hey everyone! So I’ve been working on a game for quite some time now and I wanted to have a cool pop up screen whenever a proximityprompt attached to an object is triggered where the item pops up in a viewport display.
Kind of like Resident Evil 7 and 8 where when you pick up an object you can view it and rotate it whereever you want. But instead I wanted to make it so that there is an arrow button on each side and when you hold it the object rotates towards that direction like the avatar creator in Grand Piece. Everything else works but the issue i’m facing is that when I click on the buttons it doesn’t work.

This is what it looks like:

As you can see the rotation doesn’t work when it’s inside a viewportframe but it works when it’s in workspace:

This is the local script inside each button (the axis is different for each one this is just one of the 6 scripts)

local isHoldingMouse = false
local button = script.Parent
local part = workspace.Part

button.MouseButton1Down:Connect(function()
	isHoldingMouse = true

	while isHoldingMouse do
		task.wait(0.01)
		part.CFrame *= CFrame.Angles(0,0,math.rad(3))
	end
end)

button.MouseButton1Up:Connect(function()
	isHoldingMouse = false
end)

This is the output:

and this is where the object is:
image

Hey! Viewport frames are pretty neat and personally I haven’t used them much.

However, I think I do recall that every instance must be a child of the ViewportFrame to be rendered, right? Your call here is on local part = workspace.Part and is not actually fetching the model within the frame.

I am going to go test what I said to make sure I am not just talking nonsense ( ͡° ͜ʖ ͡°), but I figure this is the issue

Oh shoot that’s the wrong script, the one i posted above was in the workspace one but this is the one in the game

local isHoldingMouse = false
local button = script.Parent
local part = game.Players.LocalPlayer.PlayerGui:WaitForChild("ScreenGui3").ViewportFrame.Part

button.MouseButton1Down:Connect(function()
	isHoldingMouse = true

	while isHoldingMouse do
		task.wait(0.01)
		part.CFrame *= CFrame.Angles(0,math.rad(3),0)
	end
end)

button.MouseButton1Up:Connect(function()
	isHoldingMouse = false
end)
1 Like

Hmm, I tested this new script you just sent and it worked perfectly fine for me. I just used the default ViewportFrame GUI tutorial script provided by Roblox to make the viewport during runtime.

In my opinion, it seems that it would be better in this scenario to manage each button in a single script. That way you can change stuff easily and see if it is connecting properly.

Here is my world if you would like to compare and see what has gone wrong (must run the game):
ViewportButtonTest.rbxl (35.3 KB)

I played the game and copied the viewportframe from the playergui section and pasted it into the other game and it still doesn’t work for some reason

Can you send a picture of the script output? I suspect something is going wrong with the connections

If you want a 2D rotation, you can change the rotation property in the viewport frame:

while isHoldingMouse do
	task.wait(0.01)
	ViewPortFrame.Rotation += 1
end

However if you want a 3D you might need to either weld the entire gun first, there are great youtube tutorials on how to use WeldConstraints to do this, and then just change the CFrame of the primary part of the gun like this (Your method is a bit wrong and might result in that the gun gets positioned wrong). I would also suggest trying to rotate Z first and if it doesn’t work try rotate X:

GunModel.PrimaryPart.CFrame *= GunModel:GetPrimaryPartCFrame() CFrame.Angles(0,0,math.rad(3))

However if you do not want to weld the gun model you can use this method, which works as long as the entire gun is a model and has a primary part:

GunModel:SetPrimaryPartCFrame(GunModel:GetPrimaryPartCFrame() * CFrame.Angles(0,0,math.rad(3))) 

Ok so, I made a model with 2 children. One is called Part which acts as a rootpart and is the primarypart of the model, and the other one is the gun who is welded to the other part. I did the first one, and it still didn’t work and I also tried the second method you sent and it also didn’t work
image
image

  1. Are you able to just get a part moving in there? Just a part?
    → If you cannot, then your connections (like why the output is screaming at us) is the problem
  2. Is the script that is being referenced in the output one of the button scripts?
  3. Have you updated your script connections to be
local part = game.Players.LocalPlayer.PlayerGui:WaitForChild("ScreenGui3").ViewportFrame.Model.Part

or do it like this so its easier to reference

local VP = game.Players.LocalPlayer.PlayerGui:WaitForChild("ScreenGui3").ViewportFrame
local Model = VP.Model
local part = Model.Part

I’m kinda confused, so do i reference the gun part itself and move it itself or do I reference the model and move the model

I mean you could do either or, but because you have welded it together it should move as a single piece no matter what.

ok so i changed the script to this, it didn’t have any output errors but it also didn’t move and I also changed the script to a local script to see if it’d work as a local script

local isHoldingMouse = false
local button = script.Parent
local part = game.Players.LocalPlayer.PlayerGui:WaitForChild("ScreenGui3").ViewportFrame.Model.Part

button.MouseButton1Down:Connect(function()
	isHoldingMouse = true

	while isHoldingMouse do
		task.wait(0.01)
		part.CFrame *= CFrame.Angles(0,0,math.rad(-3))
	end
end)

button.MouseButton1Up:Connect(function()
	isHoldingMouse = false
end)

Alright, well apparently Welds do not work in Viewports :smiley: :sob:

You will need to rotate the mesh gun part itself. Put the gun back under the viewport, remove the model and part and then alter your script to move just the Gun part. It might be wonky rotation but we’ll just need to see if it rotates for now :sweat_smile:

Ok so i messed with some things and it worked now!

local isHoldingMouse = false
local button = script.Parent
local Gun = game.Players.LocalPlayer.PlayerGui.ScreenGui3.ViewportFrame.Gun

button.MouseButton1Down:Connect(function()
	isHoldingMouse = true

	while isHoldingMouse do
		task.wait(0.01)
		Gun.CFrame *= CFrame.Angles(0,math.rad(3),0)
	end
end)

button.MouseButton1Up:Connect(function()
	isHoldingMouse = false
end)

idk what I did but this is the new script that works

1 Like

By setting the CFrame of a primary part in a model the entire model should follow the CFrame.

Another problem is the while loop you have, you kind of initiate a new while loop every time the muse button is down. Instead try to move the while loop outside of the mouse button down event and put it in the very bottom of the script so it doesn’t interfere with anything, alternatively create a new task with task.spawn so that the while loop won’t block other processes in the script.

The error message is basically saying that the player object is nil. The playerGui is a member of the player so if it says that you are trying to index nil with playerGui that would mean that the player object is nil

Glad it works and it seems that moving the actual Gun part was the solution.

Good luck with the game and if you are willing to let me know when it has released I will gladly try it out

1 Like

task.wait(0.01) may as well be task.wait() since 0.01 is less than 1/60 of a second (minimum wait duration).