So, basically, I’ve been trying to get a character to be in a viewport frame, however, I’ve come across a few issues.
-
The camera is weirdly positioned at the legs of the character, and I can’t seem to change that, no matter what I try.
-
I can’t rotate the camera properly for some reason. I really don’t know why, the camera is set to attach, and I’m rotating the part that it’s attached to, nothing. I have a stupidly long and bulky script here, and it just straight-up doesn’t work.
while wait(1) do
game:GetService("TweenService"):Create(
script.Parent,
TweenInfo.new(
2,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
0,
false,
0
),
{Orientation = Vector3.new(0, 180, 0)}
):Play()
wait(2)
game:GetService("TweenService"):Create(
script.Parent,
TweenInfo.new(
1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
0,
false,
0
),
{Orientation = Vector3.new(0, -90, 0)}
):Play()
wait(1)
game:GetService("TweenService"):Create(
script.Parent,
TweenInfo.new(
1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
0,
false,
0
),
{Orientation = Vector3.new(0, 0, 0)}
):Play()
end
1 Like
The way I personally do rotating around an object is with a short Module I wrote awhile back when first learning.
Basically just sets up the object and the second function more importantly sets up the Tween which you store in a variable. I store it in TweenVar[“Tween”]. This acts by tweening one NumValue from 0-360 on repeat. Here’s where I also define the TweenVar[“Offset”], a simple configurable Vector3. Using either RenderStepped or a .Changed event if you want to use an IntValue instead, you call the update like so:
Probably not the best solution available but works 100% reliably in my case and doesn’t have a noticeable impact on performance even when rendering a large amount of rotating objects.
2 Likes
I don’t understand most of the second part, could you maybe elaborate on what the brackets are doing, as well as what ClosetTweens
is?
1 Like
ClosetTween is just a table of Tweens and their information essentially. I store them in a table because I have multiple objects rotating at any given time. In your case you might want to use a single variable such as PlayerTween. The variable itself though you’ll still want to be a Table so you can set various information about it such as PlayerTween[“Offset”].
The second function of the Module, CreateCameraTween creates the RotationalAngle object in the viewport and creates the Tween for going between 0-360 on it. It then returns that Tween which is what we’re storing in the Tables.
So it’d be called something like:
PlayerTween["Tween"] = ViewportModule:CreateCameraTween(Viewport, 5)
PlayerTween["Offset"] = Vector3.new(0,1.5,0) --Offsets it 1.5 studs upwards
The “Object” parts of the PlayerTween table stores the object it’s rotating around to get it’s primary part for pointing the Camera at. The [“Frame”] may not be one you need as it simply refers to the specific Frame that that particular objects Viewport is in.
2 Likes
This hasn’t seemed to work, and I’m not sure what I did wrong. (There’s no for
loop at the end because I am only testing this with one viewpointFrame, and there is no object cloning because the object is already in the frame)
local viewportFunctionStorage = require(game:GetService("ReplicatedStorage").Functions.ViewportFunctionStorage)
local camera = viewportFunctionStorage.CreateCamera(script.Parent, script.Parent.CameraPos.CFrame)
local playerTween = {}
playerTween["Tween"] = viewportFunctionStorage.CreateCameraTween(script.Parent, 5)
playerTween["Offset"] = Vector3.new(0, 1.5, 0)
local target = script.Parent.CameraPos
game:GetService("RunService").RenderStepped:Connect(function()
viewportFunctionStorage.UpdateViewportCamera(camera, playerTween["Offset"], script.Parent, target.Position)
end)
local functions = {}
--Create Camera
functions.CreateCamera = function(viewport, camPos)
local newCam = workspace.Camera:Clone()
newCam.Parent = viewport
newCam.CFrame = camPos
viewport.CurrentCamera = newCam
return newCam
end
--Create Camera Tween
functions.CreateCameraTween = function(viewport, rotationTime)
local rotationAngle = Instance.new("NumberValue", viewport)
rotationAngle.Name = "RotationAngle"
local tween = game:GetService("TweenService"):Create(
rotationAngle,
TweenInfo.new(
rotationTime,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
-1
),
{Value = 360}
)
return tween
end
--Update Camera
functions.UpdateViewportCamera = function(camera, cameraOffset, viewport, lookAtPosition)
local rotatedCFrame = CFrame.Angles(0, math.rad(viewport.RotationAngle.Value), 0)
camera.CFrame = CFrame.new(lookAtPosition) * rotatedCFrame * CFrame.new(cameraOffset)
camera.CFrame = CFrame.new(camera.CFrame.Position, lookAtPosition)
end
return functions
All this does is this:
And it stays like that, too. No rotation.
1 Like
After you create playerTween[“Tween”] make sure to call playerTween[“Tween”]:Play()
When the viewport isn’t being displayed you’ll probably want to Destroy the Tween and clear the table as well.
2 Likes
There’s still no rotation, and the camera is still in the same odd place.
A solution I’ve found to this issue is that instead of rotation the camera is to rotate the model itself?
Heres some code i’ve made if you’d like to use it.
local NEWSTUDS = 200
local WAIT = 1
local TARGET = script.Parent
while wait(1) do
if TARGET:IsA("Model") then
if TARGET.PrimaryPart then
TARGET:SetPrimaryPartCFrame(TARGET.PrimaryPart.CFrame * CFrame.Angles(0,math.rad(NEWSTUDS),0))
end
else
TARGET.CFrame *= CFrame.Angles(0,math.rad(NEWSTUDS),0)
end
end
1 Like
Alright, it’s rotating now, but I still have the problem of the odd camera position.
1 Like
What is target.Position? Is CameraPos where you’re wanting to position the camera initially or where you want it to look at? The position of the camera away from the object is determined by the Offset whereas LookAtPos is the position the camera will rotate around as well as look at.
Ideally you’ll want the LookAtPos somewhere around the center of the object, and Offset you’ll need to tweak as needed to achieve the desired camera. With an offset of (0,1.5,0) you’ll move only 1.5 studs above where you want to rotate, you’ll need another slight offset in either the x or z axis, I think it’s normally +z but can depend on your initial setup.
2 Likes
Oh, that’s a good point. After making the offset change, everything works! Thanks for the help!
Final Scripts:
local functions = {}
--Create Camera
functions.CreateCamera = function(viewport, camPos)
local newCam = workspace.Camera:Clone()
newCam.Parent = viewport
newCam.CFrame = camPos
viewport.CurrentCamera = newCam
return newCam
end
--Create Camera Tween
functions.CreateCameraTween = function(viewport, rotationTime)
local rotationAngle = Instance.new("NumberValue", viewport)
rotationAngle.Name = "RotationAngle"
local tween = game:GetService("TweenService"):Create(
rotationAngle,
TweenInfo.new(
rotationTime,
Enum.EasingStyle.Linear,
Enum.EasingDirection.InOut,
-1
),
{Value = 360}
)
return tween
end
return functions
local viewportFunctionStorage = require(game:GetService("ReplicatedStorage").Functions.ViewportFunctionStorage)
local camera = viewportFunctionStorage.CreateCamera(script.Parent, script.Parent.CameraPos.CFrame)
local target = script.Parent.CameraPos
viewportFunctionStorage.CreateCameraTween(script.Parent, 7.5):Play()
camera.CFrame = CFrame.new(Vector3.new(0, 1, 5))
game:GetService("RunService").RenderStepped:Connect(function() script.Parent:FindFirstChildWhichIsA("Model"):SetPrimaryPartCFrame(CFrame.Angles(0, math.rad(script.Parent.RotationAngle.Value), 0)) end)
1 Like