I am trying to make a large skinned mesh player’s footstep animation events activate screenshake on each step for regular robloxian players that are in range, while the skinned mesh player and other skinned mesh players do not see those screenshakes (because they are large).
I’ve been looking for how this might be done, but so far haven’t found anything that specifically applies. I’ve tried looking at several different tutorials to piece them together (camera shake when monster is near, custom footstep sounds, camera shake on explosion) but I’m having trouble tying them together for this specific case.
I’m not new to roblox studio but I have struggled a lot with scripting over the years, a more indepth explanation would be super appreciated, but any advice is much appreciated!
Here, I have put together a test place using @ sleitnick’s Shake module: CameraShake.rbxl (65.4 KB)
Here is the source code (all modules used are included in the file):
local Shake = require(script.Shake) -- We are using sleitnick's Shake module.
local function shakeCamera()
local shakeInstance = Shake.new() -- Create a new shake instance
shakeInstance.FadeInTime = 0.1 -- Time taken for shake to tween in
shakeInstance.Frequency = 0.01 -- How often the camera should shake
shakeInstance.Amplitude = 0.075 -- How big should each shake be
shakeInstance.SustainTime = 0.2 -- How long the shake should last
shakeInstance.FadeOutTime = 0.1 -- Time taken for shake to tween out
shakeInstance:Start() -- Initialize the shake
shakeInstance:BindToRenderStep(shakeInstance.NextRenderName(), Enum.RenderPriority.Camera.Value, function(pos, rot, isDone) -- Connect to render stepped loop
workspace.Camera.CFrame *= CFrame.new(pos) * CFrame.Angles(rot.X, rot.Y, rot.Z) -- Update camera CFrame with the given position and rotation
if isDone then
return shakeInstance:Destroy() -- If shake is done, we destroy the shake instance as we no longer need it
end
end)
end
while task.wait(3) do
shakeCamera() -- For testing, call this function whenever you want the camera to shake
end
If you don’t want to use a module, another option might be modifying the player’s character’s humanoid’s CameraOffset.
--LocalScript
local runService = game:GetService("RunService")
local players = game:GetService("Players")
--get the player's character
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local function onStep()
--check whether a shake is already happening to prevent weird things.
if hum.CameraOffset ~= Vector3.zero then return nil end
--compare the distance between the object and the player
local distance = (part.CFrame.Position - char.HumanoidRootPart.CFrame.Position).Magnitude
if distance < 10 then --less than 10 studs away from each other
for i = 1, 50, 1 do --shake 50 times, with random offset values
local xNum = math.random(1, 20) / 10
local yNum = math.random(1, 20) / 10
local zNum = math.random(1, 20) / 10
local newOffset = Vector3.new(xNum, yNum, zNum)
hum.CameraOffset = newOffset
end
--reset the offset
hum.CameraOffset = Vector3.zero
end
end
runService:BindToRenderStep("Shake", 2000, onStep)