Tilting the camera upon an event

Greetings.

Basically, when a player takes damage, I want the camera to tilt like this:


then revert back to normal. I want this to be smoothed with tweening or lerping? I dunno how to ease CFrames.

I’ve come to ask for help since CFrame calculations are gibberish to me.
I’d really appreciate if someone told me how to achieve this. Thanks in advance.

3 Likes

Heres how you can do this i didnt take into account when the player is damaged but just call these function when the player is

local TweenService = game:GetService("TweenService")

local camera = game.Workspace.CurrentCamera
local normalCFrame = CFrame.new(0, 180, 0)
local tiltedCFrame = CFrame.new(-10, 180, -33)

-- Function to tilt the camera when player takes damage
local function tiltCamera()
    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
    local tween = TweenService:Create(camera, tweenInfo, {CFrame = tiltedCFrame})
    tween:Play()
end

-- Function to revert the camera back to normal position
local function revertCamera()
    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
    local tween = TweenService:Create(camera, tweenInfo, {CFrame = normalCFrame})
    tween:Play()
end


3 Likes

Hey, I’ll take you through a step by step process to achieving this goal. I hope you will truly try to learn something from this instead of just skipping over.

First things first, we will define the services we will need to use and the variables we will need:

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService") -- Used to make the smooth animation
local _Workspace = game:GetService("Workspace") -- Just for easier access to Workspace

local CurrentCamera = _Workspace.CurrentCamera -- Getting the current player's camera
local Player = Players.LocalPlayer
local Humanoid = Player.Character:FindFirstChild("Humanoid") -- Getting the character and the humanoid

local LastPlayerHealth = Humanoid.Health -- We will need this for later when we detect damage, unless you use other types of receiving health information like Events.

Great, now that we have everything ready we will be placing this into a LocalScript and into StarterPlayer > StarterCharacterScripts. That insures this will run only once the Character has been loaded and saves us the writing of Player.Character and Player.Character:Wait().

Now comes the fun part, we will first listen on the :GetPropertySignalChanged("Health") on the Humanoid. That way we will get every time the Humanoid has been damaged.

Humanoid:GetPropertyChangedSignal("Health"):Connect(OnHealthChanged) -- We will define the OnHealthChanged() function now

Keeping that in mind, we will be writing the function that will run every time that the Humanoid is damaged, and that is OnHealthChanged(). Inside the function we will check if the current Humanoid's Health is less than before, then run the Tween function to Tween the camera into place. We will also store the current health so we can compare it with later health loss/gain and run again. That looks like this:

function OnHealthChanged()
	if Humanoid.Health < LastPlayerHealth then
		TweenCamera()
	end

    LastPlayerHealth = Humanoid.Health 
end

Last but not least we will be creating the TweenCamera() function and tilting it like you wanted, you can tweak the values how you’d like the effect to be. That would look like this:

function TweenCamera()
	local Info = TweenInfo.new(.2, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut, 0, true, 0.01) -- TweenInfo.new(Time it takes, The easing style, The easing direction, Repeat count, Should Reverse, Delay between), tweak however you'd like
	local Goal = {
		["CFrame"] = CurrentCamera.CFrame * CFrame.Angles(0, 0, math.rad(-33)) -- You can tweak the CFrame.Angles(x, y, z) to your liking. Read up on CFrame.Angles() to know how it works.
	}
	
	local Tween = TweenService:Create(CurrentCamera, Info, Goal) -- Creating the Tween
	Tween:Play() -- Executing it
	
	Tween.Completed:Wait() -- Waiting until the Tween has played and reversed, then continuing on.
end

The full code would look something like this:

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local _Workspace = game:GetService("Workspace")

local CurrentCamera = _Workspace.CurrentCamera
local Player = Players.LocalPlayer
local Humanoid = Player.Character:FindFirstChild("Humanoid")

local LastPlayerHealth = Humanoid.Health

-----

function TweenCamera()
	local Info = TweenInfo.new(.2, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut, 0, true, 0.01)
	local Goal = {
		["CFrame"] = CurrentCamera.CFrame * CFrame.Angles(0, 0, math.rad(-33))
	}
	
	local Tween = TweenService:Create(CurrentCamera, Info, Goal)
	Tween:Play()
	
	Tween.Completed:Wait()
end

function OnHealthChanged()
	if Humanoid.Health < LastPlayerHealth then
		TweenCamera()
	end

    LastPlayerHealth = Humanoid.Health
end

-----

Humanoid:GetPropertyChangedSignal("Health"):Connect(OnHealthChanged)

You can also look at @master675457 's more straight-to-the-point solution. Cheers and happy scripting!

3 Likes

Thanks for your answer, although that’s not exactly what I wanted. Your script causes the camera go unattached(from the humanoid). I want it to be attached while the camera tilts.

You can set the CameraSubject property of your Camera to the character Humanoid. This should fix the problem.

1 Like

1 Like

The reason the camera is not attached to the humanoid when it tilts is because the code is using TweenService to directly tween the camera CFrame and when the humanoid moves the TweenService is still tweening the camera to the same position, the way to fix this is to tween a CFrameValue which will be relative to the humanoid, and then every frame offset the camera by the CFrameValue, here’s the updated code

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local _Workspace = game:GetService("Workspace")

local RunService = game:GetService("RunService")

local CurrentCamera = _Workspace.CurrentCamera
local Player = Players.LocalPlayer
local Humanoid = Player.Character:FindFirstChild("Humanoid")

local LastPlayerHealth = Humanoid.Health

local TiltCFrameValue = Instance.new("CFrameValue")

-----

function TweenCamera()
	local Info = TweenInfo.new(.2, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut, 0, true, 0.01)
	local Goal = {
		["Value"] = CFrame.Angles(0, 0, math.rad(-33))
	}
	
	local Tween = TweenService:Create(TiltCFrameValue, Info, Goal)
	Tween:Play()
	
	Tween.Completed:Wait()
end

function OnHealthChanged()
	if Humanoid.Health < LastPlayerHealth then
		TweenCamera()
	end

    LastPlayerHealth = Humanoid.Health
end

-----

Humanoid:GetPropertyChangedSignal("Health"):Connect(OnHealthChanged)

RunService.RenderStepped:Connect(function()
	CurrentCamera.CFrame *= TiltCFrameValue.Value
end)
3 Likes

Thank you so much man. You saved me from a great pain.

2 Likes

Good answer, good job also on modifying the code. I apologize for not thinking about that right away, I did write it up without even testing it however, that is entirely my fault! I’m glad the community solved it.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.