Skip to content

Instantly share code, notes, and snippets.

@DavidCatalano
Created September 11, 2022 21:59
Show Gist options
  • Save DavidCatalano/3d82c8d789f26e6f39848138d217df99 to your computer and use it in GitHub Desktop.
Save DavidCatalano/3d82c8d789f26e6f39848138d217df99 to your computer and use it in GitHub Desktop.
Roblox perfectly sized Viewport Frame with model rotation
-- Perfect ViewportFrame Script with 360 degree Rotate
-- thanks to @sleitnick https://www.youtube.com/watch?v=2J-2v_UqNDw for the hard part
-- Put this code in a LocalScript inside of a ScreenGui in StarterGui
-- Change the reference to the model a few lines down to point to your model
-- Delete rows 40 and below if you don't want the rotate code
local makeModelSpin = true -- change this to false to keep the model stationary
local viewportFrame = Instance.new("ViewportFrame")
local camera = Instance.new("Camera" , viewportFrame)
-- Set model
local model = game.ReplicatedStorage:WaitForChild("Troop Carrier"):Clone()
model.Parent = viewportFrame
model:MoveTo(Vector3.zero)
-- Set viewport frame
viewportFrame.Parent = script.Parent
viewportFrame.CurrentCamera = camera
-- Determine camera position / using logic from https://www.youtube.com/watch?v=2J-2v_UqNDw
local orientation, size = model:GetBoundingBox()
local rot = CFrame.Angles(math.rad(0), math.rad(90), 0)
size = rot:VectorToObjectSpace(size)
local sizeX, sizeY, sizeZ = math.abs(size.X), math.abs(size.Y), math.abs(size.Z)
local frameSize = 500
local h = (sizeY / (math.tan(math.rad(camera.FieldOfView / 2)) * 2)) + (sizeZ / 2)
local frameX = (sizeX > sizeY and frameSize or (frameSize * (sizeX / sizeY)))
local frameY = (sizeY > sizeX and frameSize or (frameSize * (sizeY / sizeX)))
viewportFrame.Size = UDim2.new(0, frameX, 0, frameY)
-- Set camera position
camera.CFrame = orientation * rot * CFrame.new(0, 0, h)
--======= ROTATE 360 ========
local TS = game:GetService("TweenService")
local function tweenModel(model)
-- set PrimaryPart to center of model to allow for a smooth rotation
local centerPart = Instance.new("Part")
centerPart.Material = Enum.Material.Neon
centerPart.BrickColor = BrickColor.new("Cyan")
centerPart.Size = Vector3.one
centerPart.Position = orientation.Position
centerPart.Transparency = 1
centerPart.Anchored = true
centerPart.Parent = viewportFrame
model.PrimaryPart = centerPart
local CFrameValue = Instance.new("CFrameValue")
CFrameValue.Value = model:GetPrimaryPartCFrame()
CFrameValue:GetPropertyChangedSignal("Value"):Connect(function()
model:SetPrimaryPartCFrame(CFrameValue.Value)
end)
local tweenInfo = TweenInfo.new(
2, -- Time
Enum.EasingStyle.Linear, -- EasingStyle
Enum.EasingDirection.Out, -- EasingDirection
0, -- RepeatCount (when less than zero the tween will loop indefinitely)
false, -- Reverses (tween will reverse once reaching it's goal)
0 -- DelayTime
)
local tween1 = TS:Create(CFrameValue, tweenInfo, {Value = model:GetPrimaryPartCFrame()* CFrame.Angles(0,math.rad(120),0)})
local tween2 = TS:Create(CFrameValue, tweenInfo, {Value = model:GetPrimaryPartCFrame()* CFrame.Angles(0,math.rad(240),0)})
local tween3 = TS:Create(CFrameValue, tweenInfo, {Value = model:GetPrimaryPartCFrame()* CFrame.Angles(0,math.rad(360),0)})
tween1:Play()
tween1.Completed:Connect(function()tween2:Play() end)
tween2.Completed:Connect(function()tween3:Play() end)
tween3.Completed:Connect(function()tween1:Play() end)
end
if makeModelSpin then
tweenModel(model)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment