Categories
Advanced Tutorials

Adding Camera Shake

Camera shake can help sell the effect that the player is firing a powerful weapon or is near an explosion and is causing the landscape to move under their feet.

How do I trigger it?

You have two ways to trigger a camera shake effect; you can either trigger it on a certain player, or you can trigger it at a location in the world.

Play camera shake effect on a user

The PlayCameraShakeEffect has been added to the User API and can be used to trigger camera shake on a specific player. You can pass the camera shake asset you wish to play along with a Scale value to control how powerfully this should be applied.

user:PlayCameraShakeEffect(self.properties.cameraShakeAsset, 1)

Adding the effect on the player

Let’s add this to our player so each time you jump it will trigger the shake effect.

First, select the Player template from the Entities drop-down.

Right-click on the Player and select Create Child > Script Folder > New Script Folder and then rename this JumpShake.

Select this folder then select Entity > Add > Script > New Script and call this jumpShake.

Next add the below code to the new script you created:

local JumpShake = {}

-- Script properties are defined here
JumpShake.Properties = {
	{name = "cameraShake", type = "camerashakeasset", },
	{name = "shakeMultiplier", type = "number", default = 0.5, min = 0, max = 1, tooltip="Multiplier scale value based on jump height."},
}

--This function is called when jump is pressed.
function JumpShake:LocalOnJump()
	--Call the shake effect on the user and pass in the camera shake asset and the strength.
	self:GetEntity():GetUser():PlayCameraShakeEffect(self.properties.cameraShake, self:GetEntity().jumpHeightMultiplier * self.properties.shakeMultiplier)
end

return JumpShake

Finally, set the Camera Shake property to either Recoil or Explosion on the script properties. 

Here’s an example of this in action with a camera shake triggered every time the player jumps, with the Scale parameter tied to the jump height multiplier of the player:

Creative Control : Adjusting the jump height

Inside your Player template you should have access to the Character settings, try adjusting the jump height and then re-running the preview. You should notice the intensity of the shake changes depending on how high the player can jump.

Playing camera shake at a location

The PlayCameraShakeEffectAtLocation has been added to the World API, and can be used to create a rumble at a certain location in the world. The closer the player is to the epicentre, the greater the camera shake’s effect can be felt.

world:PlayCameraShakeEffectAtLocation(self.properties.cameraShakeAsset, location, innerRadius, outerRadius, falloff, orientToDirection )

The function let’s you specify an innerRadius and outerRadius, where the camera shake is felt at full force at distances equal to or less than the inner radius, blending out to seeing no camera shake at all if the character is at a distance of outerRadius or more.

The Falloff parameter controls how this falloff between the inner and outer radius is applied, for example setting this to 1 will apply the falloff linearly, while a value of 2 will result in the camera shake intensity falling off exponentially. orientToDirection will adjust the movement of the camera shake based on the direction from the epicentre.

Note: This won’t do anything noticeable if triggering a camera shake that vibrates the camera in all directions!

Adding the effect on a mesh

Let’s add this to one of our meshes, once you’re in the radius of the mesh the effect will be applied based on the location.

Firstly, select the Grenade (Jumbo) from the meshes and place it in the World.

Place this away from the initial player spawn and somewhere visible in the level.

Select this folder then select Entity > Add > Script > New Script and call this proximityShake

Next add the below code to the new script you created:

local ProximityShake = {}

-- Script properties are defined here
ProximityShake.Properties = {
	{ name = "cameraShake", type = "camerashakeasset", },
	{ name = "cameraShakeIntensity", type = "number", default = 2, },
	{ name = "innerRadius", type = "number", default = 0, },
	{ name = "outerRadius", type = "number", default = 800,},
	{ name = "falloff", type = "number", default = 1, },
	{ name = "orientateToDirection", type = "boolean", default = false,},
}

function ProximityShake:Init()
	self.p = self.properties
	self:Explosion()
end

function ProximityShake:Explosion()
	self:Schedule(
		function()
			while true do
				Wait(1)
				--Get the position from this entity	
				local pos = self:GetEntity():GetPosition()
				--Apply the camera shake at this location
				GetWorld():PlayCameraShakeEffectAtLocation(self.p.cameraShake, self.p.cameraShakeIntensity, pos, self.p.innerRadius, self.p.outerRadius, self.p.falloff, self.p.orientateToDirection)
			end
		end
	)
end

return ProximityShake

Don’t forget to assign the Camera Shake property to Explosion on the script properties.

Here’s an example of this in action with a camera shake triggered by how close you are to the location specified, as you get closer to the grenade the effect is amplified:

Creative Control : Adjusting the radius and falloff

By adjusting the radius values you can set how close or far away that the screen shake will be triggered on the player as they go towards the location. By adjusting the falloff, you can choose how harshly or smoothly the effect will increase when you’re in its radius. It’s worth playing with these to dial in the effect that you want.

Recap

Awesome! You should now have the screen shake effects in your game. Feel free to adjust the settings to suit your situation and make the effect as subtle or intense as you want.

Adding Polish

  • Try adding particle effects and/or sounds when the grenade explodes.
  • Add the shake effect when the player lands after a jump or is launched through the air.