Awesome, here’s something you can definitely use Math for Game Programmers: Juicing Your Cameras With Math - YouTube
is there a way to make it work with shift lock?(in the click, I activate shift lock on -00:02, in case the video doesn’t load, it basically makes the character be sideways while running forward)
Thanks for pointing that out. I added a section at the bottom to fix this
I am kind of new to vectors and CFrame but what does this mean and why does this work?
I have a guide for CFrames if you wanted to learn in general, but I’ll explain this thing specifically: A CFrame encodes the position and orientation of parts and cameras. The LookVector of a cameras CFrame is the direction of it’s view, and the LookVector of a part is the direction it’s front side is facing.
Basically what this code does is set the root part’s CFrame so that it’s position stays the same, but its front side points in the same horizontal direction as the camera. The CFrame.lookAt() constructor takes the position as the first argument, and a point in space to look at in the 2nd argument. For the second argument I took the horizontal component of the camera LookVector and added it to the position of the root part which creates a point in space which is displaced from the character in the direction we want them to look
Hello @xXSanrioSlayer99, thank you for taking your time to make this tutorial for us.
I didn’t have any problems with the code. But, as I’m an amateur programmer, I couldn’t figure out a way to implement my camera offset values (0,0.05,0) to our new CurrentCamera.
Can you help me on this? Thanks!
All you have to do is offset the goal position of the lerp based on your chosen offset:
We originally have this:
local function updateSubject()
subject.Position = subject.Position:Lerp(rootPart.Position,1/WEIGHT)
end
but instead of lerp to rootPart.Position
you can add your offset to get this:
local function updateSubject()
local offset = Vector3.new(0, 0.05, 0)
subject.Position = subject.Position:Lerp(rootPart.Position + offset,1/WEIGHT)
end
this will make it so the camera works to point towards the root part, plus your offset value.
Question if i go in first person the whole thing breaks is there any way to fix this?
Whoops that was a big oversight by me. I added a section to disable camera weight while in first person
I am struggling to add an offset to the camera module, I added the following to add Y offset of 3 without luck. Welp!
local myChar = script.Parent
local myHum = myChar.Humanoid
myHum.CameraOffset = Vector3.new(0,3,0)
Also, I m so so very happy with this module, BIG thank you! and if you have time and if you are interested, I would love to show you what I am doing with it
I’m having a bit of a struggle with the first person stuff. Everything works great at the start but once I go into first person then come out, the camera weighting stops working. I got no errors and would be grateful if you could point me in the right direction.
Source Code
local RUN_SERVICE = game:GetService("RunService")
local USER_INPUT_SERVICE = game:GetService("UserInputService")
local Cam = workspace.CurrentCamera
local Subject = script:WaitForChild("CameraSub")
local Head = script.Parent:WaitForChild("Head")
local Root = script.Parent:WaitForChild("HumanoidRootPart")
local Humanoid = script.Parent:WaitForChild("Humanoid")
Subject.Position = Head.Position
Cam.CameraSubject = Subject
local CamWeight = 60
local function UpdateSub()
if (Cam.CFrame.Position - Subject.Position).Magnitude < 1 or (Cam.CFrame.Position - Head.Position).Magnitude < 1 then
Cam.CameraSubject = Humanoid
Subject.Position = Head.Position
else
Subject.Position = Subject.Position:Lerp(Head.Position, 1/CamWeight)
if USER_INPUT_SERVICE.MouseBehavior == Enum.MouseBehavior.LockCenter then
local Look = Vector3.new(Cam.CFrame.LookVector.X, 0, Cam.CFrame.LookVector.Z)
Root.CFrame = CFrame.lookAt(Root.Position, Root.Position + Look)
end
end
end
RUN_SERVICE:BindToRenderStep("UpdateSub", Enum.RenderPriority.Camera.Value, UpdateSub)
you forgot to set camera subject back to the subject part in the “else” part of the update function.
works great but up close there’s still a slight stutter/jitter. how do you fix that?
local RunService = game:GetService("RunService")
local camera = workspace.CurrentCamera
local head = script.Parent:WaitForChild("Head")
local subject = script:WaitForChild("Subject")
subject.Position = head.Position
camera.CameraSubject = subject
local WEIGHT = 20
local function updateSubject()
subject.Position = subject.Position:Lerp(head.Position,1/WEIGHT)
end
RunService:BindToRenderStep("UpdateSubject", Enum.RenderPriority.Camera.Value + 1, updateSubject)
this going to be perfect for that one bmx game
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local CurrentCamera = workspace.CurrentCamera
local Humanoid = script.Parent:WaitForChild("Humanoid")
local Head = script.Parent:WaitForChild("Head")
local HumanoidRootPart = script.Parent:WaitForChild("HumanoidRootPart")
local Subject = script:WaitForChild("Subject")
local HeadPosition = Head.Position
local SubjectPosition = Subject.Position
SubjectPosition = HeadPosition
CurrentCamera.CameraSubject = Subject
local SubjectWeights_Horizontal = 10
local SubjectWeights_Vertical = 20
local function UpdateSubject()
local OffsetVectors = Vector3.new(0, 0.6, 0)
local HorizontalPosition = Vector3.new(SubjectPosition.X, 0, SubjectPosition.Z):Lerp(Vector3.new(HeadPosition.X, 0, HeadPosition.Z) + OffsetVectors, 1/SubjectWeights_Horizontal)
local VerticalPosition = Vector3.new(0, SubjectPosition.Y, 0):Lerp(Vector3.new(0, HeadPosition.Y, 0) + OffsetVectors, 1/SubjectWeights_Vertical)
SubjectPosition = HorizontalPosition + VerticalPosition
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then
local LookVectors = Vector3.new(CurrentCamera.CFrame.LookVector.X, 0, CurrentCamera.CFrame.LookVector.Z)
HumanoidRootPart.CFrame = CFrame.lookAt(HumanoidRootPart.Position, HumanoidRootPart.Position + LookVectors)
if (CurrentCamera.CFrame.Position - SubjectPosition).Magnitude < 1 or (CurrentCamera.CFrame.Position - HeadPosition).Magnitude < 1 then
CurrentCamera.CameraSubject = Humanoid
SubjectPosition = HeadPosition
else
CurrentCamera.CameraSubject = Subject
SubjectPosition = HorizontalPosition + VerticalPosition
end
end
end
RunService:BindToRenderStep("UpdateSubject", Enum.RenderPriority.Camera.Value, UpdateSubject)
It seems that I have ran into an issue, any idea why this is broken? I mean it seems to work but the camera doesn’t actually follow the player anymore?
It seems you are updating the variable SubjectPosition
rather than the actual position of the subject part, so instead of changing the value of Subject.Position
you’re just changing what value is stored in the SubjectPosition
variable.
So inside the loop you should replace SubjectPosition
with Subject.Position
so that it is actually changing the position property. Also inside the loop you need to change HeadPosition
to Head.Position
so that you’re referring to the current position of the head rather than what the head position was when you originally defined that variable.
Unfortunately I think that’s just a limitation of this method
Ah, I see, alright well I’ll make the changes as soon as I arrive home but thanks a lot. Needed that help! ^^
This gives a choppy effect when rotating camera or just walking