The coding below is a Local Script that contains code to either animate a camera rig, and connect a players camera to said rig… or tween the players camera between two positions from a list, in the order provided.
I feel that this coding is overly complex when it doesn’t need to be, and there’s a much more efficient way to achieve the goal of the system.
I’ve thought of using task, or coroutines to do the same thing… but am unsure of the best way to do said idea correctly.
I want to improve the code any way possible, even if it’s something as simple as cleaning the coding up.
local Connections = {CameraTrack = {}}
["Change Camera Subject"] = {
Description = "",
Function = function(CameraType,CameraProperties,Info,Frames)
local Camera = game.Workspace.CurrentCamera
--[[This is to reset the camera whenever the event is fired.]]
if Connections.CameraTrack[1] and typeof(Connections.CameraTrack[1]) == "RBXScriptConnection" then
--[[This is to stop any, and all animations that could be player on the CameraRig]]
if game.Workspace:FindFirstChild("Camera_Rig") then
for _,v in pairs(game.Workspace["Camera_Rig"].Humanoid:GetPlayingAnimationTracks())do v:Stop(0) end
end;
--[[This disconnects the connection]]
Connections.CameraTrack[1]:Disconnect();Connections.CameraTrack[1] = nil
end
if Connections.CameraTrack[1] and typeof(Connections.CameraTrack[1]) == "Instance" then
--[[This is meant to cancel any camera tweens in motion, and nulify the function running]]
Connections.CameraTrack[1]:Cancel();Connections.CameraTrack[1] = nil; Connections.CameraTrack[2] = true
end
--[[Coding starts here,
Hard Camera = A camera that goes off of the positions of multiple parts already placed and hidden away in Server Storage.
Animate Camera = A Camera Rig is set up with a humanoid, and is used to animate a camera however you see fit.
]]
if string.lower(CameraType) == "hard camera" then
if not Frames then return end
for NumPosition,Frame in pairs(Frames) do
local bool = true
if Frames[(NumPosition + 1)] ~= nil then
--[Variables]
if Connections.CameraTrack[2] == true then
break
end
--[[This sets the cameras starting position.]]
Camera.CFrame = CFrame.new(Frame.Position) * CFrame.Angles(math.rad(Frame.Orientation.X), math.rad(Frame.Orientation.Y), math.rad(Frame.Orientation.Z));
Camera.CameraType = CameraProperties["Camera Type"];
Camera.FieldOfView = CameraProperties["FoV"];
--[[This is so I can make sure the CFrame is valid, this gets the next frames CFrame.]]
local newCFrame;
newCFrame = {CFrame = Frames[NumPosition + 1].CFrame}
--[[This runs the camera]]
if newCFrame == nil then continue end
warn("CREATING NEW TWEEN".." to "..tostring(Frames[(NumPosition + 1)]["Angle Name"]))
Connections.CameraTrack[1] = game:GetService("TweenService"):Create(Camera,TweenInfo.new(Frame.Camera_Speed,table.unpack(Info)),newCFrame)
Connections.CameraTrack[1]:Play()
Connections.CameraTrack[1].Completed:Wait()
bool = false;Connections.CameraTrack[1] = nil
end
end
--[[If there is nothing after the current frame, it shall fix the camera to be normal.]]
Connections.CameraTrack[1] = nil;Connections.CameraTrack[2] = false
Camera.CameraType = Enum.CameraType.Custom;Camera.FieldOfView = 70
elseif string.lower(CameraType) == "animate camera" then
--[[This is a bunch of instances that either create, or need to be created, alongside variables.]]
local CameraRig = Info["Camera_Rig"];local CameraAnimation,PlayerAnimation = Instance.new("Animation");
local CameraHum = CameraRig.Humanoid or CameraRig:WaitForChild("Humanoid")
Camera.CameraType = CameraProperties["Camera Type"]; --[[This sets the current Cameras Type]]
CameraAnimation.AnimationId = Info["Camera_Animation"]; --[[This is the animationID sent from the server.]]
local CamTrack = CameraHum:LoadAnimation(CameraAnimation); --[[This loads the animation.]]
CamTrack:Play() --[[This plays the animation.]]
--[[This changes the Cameras Position when the CFrame of the CameraRig's primary part moves, I think..?]]
Connections.CameraTrack[1] = game:GetService("RunService").RenderStepped:Connect(function()
if CamTrack.TimePosition > .1 then --[[I'm unsure how to prevent a small pause in-between when the Camera moves to the correct position.]]
Camera.CFrame = CameraRig.PrimaryPart.CFrame
end
end)
--[[This is to set off particle emmitters when reached.]]
CamTrack:GetMarkerReachedSignal("Pyro"):Connect(function(paramString)
end)
--[[This is to do an action/animation when the Marker "Queue Player" is reached.]]
CamTrack:GetMarkerReachedSignal("Queue Player"):Connect(function(paramString)
--[[This checks if there's a player to animate inside the Info provided from the server]]
if not Info["Animate_Player"] then return "No Animated Player(s)" end
--[[This is to animate the player when the Marker is reached.]]
local Char = game.Workspace[Info["Animate_Player"][2].Name] or game.Workspace:WaitForChild(Info["Animate_Player"][2].Name,30)
local PlayerHum = Char.Humanoid or Char:WaitForChild("Humanoid",30)
if Info["Animate_Player"] and Info["Animate_Player"][1] then
PlayerAnimation = Instance.new("Animation");PlayerAnimation.AnimationId = Info["Player_Animation"];
local PlayerTrack = PlayerHum:LoadAnimation(PlayerAnimation);PlayerTrack:Play()
end
end)
--[[This stops any, and all connection after the animation has completed.]]
CamTrack.Stopped:Connect(function()
Connections.CameraTrack[1]:Disconnect();Camera.CameraType = Enum.CameraType.Custom;Camera.FieldOfView = 70;Camera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
end)
end
return "Completed"
end,
}
Any recommendations is appreciated