I managed to get it working a bit, but not that well.
current code on renderstepped that sets the offset
fp2c is the distance from the muzzle to the camera
local Model = Tool:FindFirstChild("ToolModel")
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {Viewmodel,Character}
local Origin = Model.FirePos.Position
local Direction = Model.FirePos.CFrame.LookVector
local Cast = game.Workspace:Raycast(Origin, Direction, Params)
if Cast then
local Distance = (Cast.Distance-Tool.FP2C.Value) - script.Offset0.Value.Z
print(Distance)
script.Offset0.Value = CFrame.new(0, 0, -Distance)
else
script.Offset0.Value = CFrame.new(0, 0, 0)
end
end
FP2C - the distance from the guns muzzle from the camera, this value should be updated on renderstepped but if the viewmodel is going back then do not update it
local FP2C = Parent:FindFirstChild("FP2C")
-- below shows a check that checks if the viewmodel is backing up or not, if it isn't it's safe to update FP2C
if FP2C and math.abs(Player.PlayerScripts.Viewmodel.Offset0.Value.Position.Z)<=0 then
local a = false -- if the fp2c value should be updated
-- I also recommend detecting if only the idle animation is playing and if not make a true
if not a then
FP2C.Value =(GetPart("FirePos").Position-Camera.CFrame.Position).Magnitude -- getpart firepos can be your muzzle
end
end
viewmodel code
Model = the tools model
EndPoint - the point to raycast from, should be the same axis as the firepos but moved back to the guns length
offset0 = the viewmodels back offset, aka what you want to use and apply to the viewmodel when using pivot to etc
code
local Model = Tool:FindFirstChild("ToolModel")
local Length = Model.Length.Size.Z
local EndPoint = Model.EndPoint.Position
local FP2C = Tool.FP2C.Value
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = {Viewmodel,Character}
local Origin = EndPoint+(Model.FirePos.CFrame.LookVector*script.Offset0.Value.Z)
local Direction = Model.FirePos.CFrame.LookVector*Length
local Cast = game.Workspace:Raycast(Origin, Direction, Params)
if Cast then
local Distance = -math.clamp((Cast.Distance-2)-FP2C,-FP2C,0) -- math.clamp((Cast.Distance-Tool.FP2C.Value) - script.Offset0.Value.Z,-Tool.FP2C.Value,Tool.FP2C.Value)
print(Distance)
script.Offset0.Value = CFrame.new(0, 0, Distance)
else
script.Offset0.Value = CFrame.new(0, 0, 0)
end