See how the camera follows the player? The player is not centered but rather is always to the side, allowing you to move around without the camera going along. I also want to achieve the transition effect it has between rooms.
How would you implement something like this? Thanks!
If you create an anchored part in workspace named “CameraPart” and paste the following in a localscript, which you put under StarterCharacterScripts, then you can achieve it:
local cameraPartCFrame = workspace:WaitForChild("CameraPart").CFrame
local camera = workspace.Camera
camera.CameraType = Enum.CameraType.Scriptable
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
while humanoid.MoveDirection ~= Vector3.zero do
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local newPosition = Vector3.new(
cameraPartCFrame.X,
cameraPartCFrame.Y,
humanoidRootPart.Position.Z
)
camera.CFrame = CFrame.new(newPosition) * (cameraPartCFrame - cameraPartCFrame.Position)
task.wait()
end
end)
This script basically sets the position of the camera to a part and only allows it to move along the z axis. You can change which axis the camera should move along by changing the newPosition variable. This of course assumes your background, and everything is parallel to the axis you choose, but i didn’t assume that to be a problem.
(Edit: I didn’t notice you wrote about the transition effect as well. For that i guess you could just have a touch-detection part at the doors that cause the darkening of the screen, teleports the player to the new room and updates the CameraPart)
Yes i think so, but i also just realized something. In the video, there is a point where the player walks forward and the camera follows. My provided script will not do that. I’ll try to see if i can make it do so.
I haven’t tried 2112Jay’s code, so it might work. However, i was invested in this problem myself, and came up with the solution:
local cameraPartCFrame = workspace:WaitForChild("CameraPart").CFrame
local camera = workspace.Camera
camera.CameraType = Enum.CameraType.Scriptable
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local distanceLimit = 20 --Studs between player and cam. If it exceeds this, camera will follow
local function UpdateCamera()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local cameraPartPosition = cameraPartCFrame.Position
local vectorToPlr = humanoidRootPart.CFrame.Position - cameraPartPosition
local distanceInRightVector = vectorToPlr:Dot(cameraPartCFrame.RightVector)
local newCFrame = cameraPartCFrame + cameraPartCFrame.RightVector * distanceInRightVector
local distance = (
Vector2.new(newCFrame.X, newCFrame.Z) -
Vector2.new(humanoidRootPart.Position.X, humanoidRootPart.Position.Z)
)
if distance.Magnitude > distanceLimit then
local distanceXYZ = Vector3.new(distance.X, 0, distance.Y)
local forwardAxis = Vector3.new(cameraPartCFrame.LookVector.X, 0, cameraPartCFrame.LookVector.Z).Unit
newCFrame = newCFrame - distanceXYZ - forwardAxis * distanceLimit
end
camera.CFrame = newCFrame
end
UpdateCamera() --Makes sure camera is updated before player starts walking after reset/joining
humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
local startMoveDirection = humanoid.MoveDirection
while humanoid.MoveDirection ~= Vector3.zero and humanoid.MoveDirection == startMoveDirection do
UpdateCamera()
task.wait()
end
end)
I also noticed that you could cause the loop to run more than needed with the humanoid.MoveDirection ~= Vector3.zero command, since it never stops running unless the player moves, meaning it will keep running when you walk forward and left at the same time. This code should also make sure you aren’t forced to use one axis only. Now you can rotate the CameraPart however you like, and it will follow its own kind of axis.
(Edit: Forgot to mention the most important change, it now follows your player if they move longer than 20 studs away.)
“I think it’s best we all try to improve the solution.” This is the way …
Also the loop isn’t going to over-run, add a print after and you’ll see it only runs when moving.
I also have that directional turning option going.
My last posts were all trash …
This works, make sure you place it in StarterCharacterScripts.
-- A LocalScript in StarterPlayerScripts.StarterCharacterScripts
local camera = game.Workspace.Camera
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
camera.CameraType = Enum.CameraType.Scriptable
local function updateCamera()
while humanoid.MoveDirection ~= Vector3.new() do
local newPosition = humanoidRootPart.Position + Vector3.new(0, 2, 10)
camera.CFrame = CFrame.new(newPosition, humanoidRootPart.Position)
task.wait()
end
end
newPosition = humanoidRootPart.Position + Vector3.new(0, 2, 10)
camera.CFrame = CFrame.new(newPosition, humanoidRootPart.Position)
humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(updateCamera)
updateCamera()
This is kind-of what I was going for, but what I meant was a static camera that moves when you go to the sides. (See how in the video, the camera is static until the Petscop guy moves past a certain threshhold to the left or right. Otherwise, it remains static.)
The script you provided me is good, but it instantly moves to the left or right. Something ideal would be like the distance thing you did when going forward, implementing it for the sides too. (If player is X studs away from the center, then follow along to the left or right.)
Ahh yeah i see. I came up with a solution, that i think works pretty reliably: Camera System.rbxl (57.2 KB)
I uploaded a place file this time, because i made it so you can simply update the camera by this function:
local function SetCamera(player: Player, cameraCFrame: CFrame, forwardLimit: number, horizontalLimit: number)
local cameraEvent = game.ReplicatedStorage.CameraEvent
cameraEvent:FireClient(
player,
cameraCFrame,
forwardLimit,
horizontalLimit
)
end
In ServerScriptService, you will find the script where this function is located. I also added parameters for the function, so you can adjust the forward and horizontal limit per camera cframe. If this isn’t quite what you were looking for or it has bugs, please let me know.
Note: To use it you will have to copy the remotevent: “CameraEvent” from ReplicatedStorage and “CameraScript” from StarterPlayerScripts into your own game at those exact locations.