So, i tried to make so viewmodel will move back when colliding with wall (mostly to fix shooting through walls), like devs made it in experience called town :
…I’ve managed to get something like this :
Can someone explain why viewmodel act so weird? and how do i fix it?
Piece of code ( Inside of RunService.RenderStepped ) :
Viewmodel.PrimaryPart.CFrame = Camera.CFrame * CollideOffset
local Origin = Viewmodel.PrimaryPart
local Muzzle = Viewmodel:WaitForChild("MUZZLE")
local Num = (Origin.Position - Muzzle.Position).Magnitude
local RayCast = Ray.new(Origin.Position, Origin.CFrame.LookVector * Num)
local Part, HitPos = workspace:FindPartOnRayWithIgnoreList(RayCast, {Character, Camera:FindFirstChildOfClass("Model")})
if Part then
if Part.Transparency ~= 1 then
local Distance = (Muzzle.Position - HitPos).Magnitude
CollideOffset = CFrame.new(0,0,Distance)
end
else
CollideOffset = CollideOffset:Lerp(CFrame.new(0, 0, 0), 0.1)
end
Gray part is HRP (Viewmodel.PrimaryPart), Pink part is MUZZLE
2 Likes
I am not sure of the problem, to me it just looks like the loop is not running fast enough. Define local Origin = Viewmodel.PrimaryPart local Muzzle = Viewmodel:WaitForChild("MUZZLE")
outside of the loop, especially because you are using :WaitForChild()
which would be very slow to run every frame. Also, you could probably use BlockCasting instead of :FindPartOnRayWithIgnoreList()
(it has been deprecated). An example of this could be
local RunService = game:GetService("RunService")
local Origin = Viewmodel.PrimaryPart
local Muzzle = Viewmodel:WaitForChild("MUZZLE")
RunService.RenderStepped:Connect(function()
Viewmodel.PrimaryPart.CFrame = Camera.CFrame * CollideOffset
local Direction = Origin.Position - Muzzle.Position
local Parameters = RaycastParams.new()
Parameters.FilterType = Enum.RaycastFilterType.Exclude
Parameters.FilterDescendantsInstances = {Character, Camera:FindFirstChildOfClass("Model")}
local BlockCastResult = workspace:Blockcast(Muzzle.CFrame, Muzzle.Size, Direction, Parameters)
if BlockCastResult then
if BlockCastResult.Transparency ~= 1 then
local Distance = (Muzzle.Position - BlockCastResult.Position).Magnitude
CollideOffset = CFrame.new(0, 0, Distance)
end
else
CollideOffset = CollideOffset:Lerp(CFrame.new(0, 0, 0), 0.1)
end
end)
Because I don’t have access to your viewmodel, I cannot confirm if this code will work, however I hope it points you in the right direction.
1 Like
After some hours, i got something that looks exactly like i wanted to…
I used BlockCast
Instead of FindPartOnRayWithIgnoreList()
…
…Instead of using Origin as HRP, i added a new part called Detector :
(Orange part is Detector, Pink part is Muzzle)
…and changed code :
local Direction = Muzzle.Position - Detector.Position
local Parameters = RaycastParams.new()
Parameters.FilterType = Enum.RaycastFilterType.Exclude
Parameters.FilterDescendantsInstances = {Character, Camera:FindFirstChildOfClass("Model")}
local BlockCastResult = workspace:Blockcast(Detector.CFrame, Detector.Size * 2, Direction, Parameters)
if BlockCastResult then
Direction = (Muzzle.Position - Detector.Position) * 1.5
local Distance = (Muzzle.Position - BlockCastResult.Position).Magnitude
CollideOffset = CollideOffset:Lerp(CollideOffset * CFrame.new(0, 0, Distance), 0.3)
else
Direction = Muzzle.Position - Detector.Position
CollideOffset = CollideOffset:Lerp(CFrame.new(0, 0, 0), 0.1)
end
But there’s one problem left… :
As you can see, for some reason viewmodel is trying to lerp to CFrame.new(0,0,0)
(i guess it happens because of when viewmodel moving from wall, blockcast stops seeing wall and viewmodel is trying to lerp)…
What should i do?