I’ll even put in the code, if anyone wants to see.
-- Service
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
-- Var
local Camera = workspace.CurrentCamera
local Plr = Players.LocalPlayer
local Tag = "Test_ViewModel"
-- Wait For load
local Character = Plr.Character or Plr.CharacterAppearanceLoaded:Wait()
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
repeat task.wait() until CollectionService:GetTagged(Tag)[1] ~= nil
local Viewmodel : Model = CollectionService:GetTagged(Tag)[1]; print(Viewmodel)
-- Setup Viewmodel
local vm_colors = Viewmodel:FindFirstChildOfClass("BodyColors")
local bodycolors = Character:FindFirstChildOfClass("BodyColors")
if Character:FindFirstChildOfClass("Shirt") then
Viewmodel:FindFirstChildOfClass("Shirt").ShirtTemplate = Character:FindFirstChildOfClass("Shirt").ShirtTemplate
end
vm_colors.LeftArmColor3 = bodycolors.LeftArmColor3
vm_colors.RightArmColor3 = bodycolors.RightArmColor3
Viewmodel.Parent = workspace.VM_store
--////////////////////////////////
-- Calibration Variables
local LastCameraCFrame = CFrame.new()
local SwayAmount = 0.55
local SwayCFrame = CFrame.new()
local LeftTiltMax = CFrame.Angles(0, 0, math.rad(-5))
local RightTiltMax = CFrame.Angles(0, 0, math.rad(5))
local TiltCFrame = CFrame.new()
local LastTiltCFrame = CFrame.new()
local BobOffset
--////////////////////////////////
-- Func
local function CalibrateViewModel(Delta)
local evilalpha = 1 - 0.005 ^ Delta; local testalpa = 0.07
--Sway
local Rot = Camera.CFrame:ToObjectSpace(LastCameraCFrame)
local x, y, z = Rot:ToOrientation()
SwayCFrame = SwayCFrame:Lerp(CFrame.Angles(math.sin(x) * SwayAmount, math.sin(y) * SwayAmount, 0), 0.15)
LastCameraCFrame = Camera.CFrame
--Tilt
local RawTilt = Humanoid.MoveDirection:Dot(Camera.CFrame.RightVector)
local Tilt = math.round(RawTilt / 0.01) * 0.01
if Tilt == 0 then
TiltCFrame = LastTiltCFrame:Lerp(CFrame.Angles(0, 0, 0), 0.075)
elseif Tilt > 0.7 then
TiltCFrame = LastTiltCFrame:Lerp(LeftTiltMax, testalpa)
elseif Tilt < 0.7 then
TiltCFrame = LastTiltCFrame:Lerp(RightTiltMax, testalpa)
end
LastTiltCFrame = TiltCFrame
--Bobbing
if Humanoid.MoveDirection.Magnitude > 0 then
BobOffset = CFrame.new(math.cos(tick() * 5) * 0.25, math.sin(tick() * 10) * 0.125, -Humanoid.CameraOffset.Z/3)
else
BobOffset = CFrame.new(0, -Humanoid.CameraOffset.Y/3, 0)
end
Viewmodel:PivotTo(
Camera.CFrame * TiltCFrame * SwayCFrame * BobOffset-- Service
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
-- Var
local Camera = workspace.CurrentCamera
local Plr = Players.LocalPlayer
local Tag = "Test_ViewModel"
-- Wait For load
local Character = Plr.Character or Plr.CharacterAppearanceLoaded:Wait()
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
repeat task.wait() until CollectionService:GetTagged(Tag)[1] ~= nil
local Viewmodel : Model = CollectionService:GetTagged(Tag)[1]
-- Setup Viewmodel
local vm_colors = Viewmodel:FindFirstChildOfClass("BodyColors")
local bodycolors = Character:FindFirstChildOfClass("BodyColors")
if Character:FindFirstChildOfClass("Shirt") then
Viewmodel:FindFirstChildOfClass("Shirt").ShirtTemplate = Character:FindFirstChildOfClass("Shirt").ShirtTemplate
end
vm_colors.LeftArmColor3 = bodycolors.LeftArmColor3
vm_colors.RightArmColor3 = bodycolors.RightArmColor3
Viewmodel.Parent = workspace.VM_store
--////////////////////////////////
-- Calibration Variables
local LastCameraCFrame = CFrame.new()
local SwayAmount = 0.55
local SwayCFrame = CFrame.new()
local LeftTiltMax = CFrame.Angles(0, 0, math.rad(-5))
local RightTiltMax = CFrame.Angles(0, 0, math.rad(5))
local TiltCFrame = CFrame.new()
local LastTiltCFrame = CFrame.new()
local BobOffset
--////////////////////////////////
-- Func
local function CalibrateViewModel(Delta)
--Sway
local Rot = Camera.CFrame:ToObjectSpace(LastCameraCFrame)
local x, y, z = Rot:ToOrientation()
SwayCFrame = SwayCFrame:Lerp(CFrame.Angles(math.sin(x) * SwayAmount, math.sin(y) * SwayAmount, 0), 0.15)
LastCameraCFrame = Camera.CFrame
--Tilt
local RawTilt = Humanoid.MoveDirection:Dot(Camera.CFrame.RightVector)
local Tilt = math.round(RawTilt / 0.01) * 0.01
if Tilt == 0 then
TiltCFrame = LastTiltCFrame:Lerp(CFrame.Angles(0, 0, 0), 0.075)
elseif Tilt > 0.7 then
TiltCFrame = LastTiltCFrame:Lerp(LeftTiltMax, 0.07)
elseif Tilt < 0.7 then
TiltCFrame = LastTiltCFrame:Lerp(RightTiltMax, 0.07)
end
LastTiltCFrame = TiltCFrame
--Bobbing
if Humanoid.MoveDirection.Magnitude > 0 then
BobOffset = CFrame.new(math.cos(tick() * 5) * 0.25, math.sin(tick() * 10) * 0.125, -Humanoid.CameraOffset.Z/3)
else
BobOffset = CFrame.new(0, -Humanoid.CameraOffset.Y/3, 0)
end
Viewmodel:PivotTo(
Camera.CFrame * TiltCFrame * SwayCFrame * BobOffset
)
end
-- Start
RunService:BindToRenderStep("Test_ViewModelCalibrate", 301, CalibrateViewModel)
)
end
-- Start
RunService:BindToRenderStep("Test_ViewModelCalibrate", 301, CalibrateViewModel)
is to make an option for players to shrink or “minimize” the view model (if you don’t have already) because some players (like me) hate having their vision obstructed by a view model (no matter how cool it is)
is to make it a tad closer to the player, and angle a bit in as this is more realistic
For your first suggestion, I’ll definitely keep that in mind, thank you for that!
For your second suggestion, I’ll do some research and experiment, as well as get others opinions>
Thanks!
Small quick reply, did some testing with a friend real quick and I like this look much better!
I’ll experiment with settings like you proposed much later down the line
Thats all for now, have a good one
I’ve been working on this on and off for about a month and a half I’d say
Took some tutorials, some of my own knowledge, and a lot of tweaking to get the values used in this.
I plan to make this easy to use and maybe even in a module script and distribute it for everyone to use.