How should i make a smooth ADS transition?

I have been scripting my FPS framework and i need some help with the ADS, i want to make a smooth ADS transition of the viewmodel and i don’t know how to do it.

Here is a video showing how it looks like:

Here is the script used for ADS:

local ads = false

mouse.Button2Down:Connect(function()
	ads = true
end)

mouse.Button2Up:Connect(function()
	ads = false
end)

runservice.RenderStepped:Connect(function()
	viewmodel.HumanoidRootPart.CFrame = camera.CFrame
	if ads == true then
		viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame * adsoffset --If the player is on ADS, this will change the CFrame of the viewmodel and align the sights of the gun with the player's camera, if the player is not on ADS, nothing will happen and the viewmodel will be on hip fire position.
	end
end)

I am sorry if there are any grammar problems, because i’m still learning how to speak english.

2 Likes

You can lerp the cframe to transition o the ads cframe with renderstep’s delta time parameter

RunService:BindToRenderStepped("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta)
   viewmodel.HumanoidRootPart.CFrame = camera.CFrame
   if ads then
      viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:lerp(adsoffset, delta * 60)
   end
end)

I also recommend you use userinputservice or contextactionservice since they superseded the mouse object.

Now the viewmodel shakes.

The script:

local ads = false

mouse.Button2Down:Connect(function()
	ads = true
end)

mouse.Button2Up:Connect(function()
	ads = false
end)

runservice:BindToRenderStep("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta) --Is this how i am supposed to use it?
	viewmodel.HumanoidRootPart.CFrame = camera.CFrame
	if ads == true then
		viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:lerp(viewmodel.HumanoidRootPart.CFrame * adsoffset, delta * 60)
	end
end)

The issue with your script is that you have 2 conflicting CFrame lines, one goes towards camera CFrame the other goes toward the aimCFrame which overwrite each other

This edit should be good enough to prevent overwrite.

runservice:BindToRenderStep("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta) --Is this how i am supposed to use it?
	if ads == true then
		viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:lerp(viewmodel.HumanoidRootPart.CFrame * adsoffset, delta * 60)
	else
	viewmodel.HumanoidRootPart.CFrame = camera.CFrame

end
end)

Additionally you can also use tweenservice to lerp with a tween if you want to use tween styles

Now this happens:

The script:

local ads = false

mouse.Button2Down:Connect(function()
    ads = true
end)

mouse.Button2Up:Connect(function()
    ads = false
end)

runservice:BindToRenderStep("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta) --Is this how i am supposed to use it?
    viewmodel.HumanoidRootPart.CFrame = camera.CFrame
    if ads == true then
        viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:lerp(viewmodel.HumanoidRootPart.CFrame * adsoffset, delta * 60)
    else
        if not eqquiped then return end
        viewmodel.HumanoidRootPart.CFrame = camera.CFrame
    end
end)

I have tried to change the Lerp goal to the camera.CFrame * adsoffset and the alpha number to a lower value such as delta * 20. It kinda works, but the viewmodel CFrame takes too long to update and it “lags” behind the camera.
Here is a video showing how it looks like:

To fix the lag keep the rotation using (camera.CFrame * adsoffset).Rotation which is being lerped but add in the final goal dojng +(camera.CFrame * adsoffset).Position to avoid lerping the position which causrs the lag.

Can i get an example? I’m not sure if i’m doing something wrong, i implemented the changes to the script but nothing really changed and the viewmodel keeps lagging.

runservice:BindToRenderStep("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta)
	if ads == true then
		viewmodel.HumanoidRootPart.CFrame = viewmodel.HumanoidRootPart.CFrame:Lerp((camera.CFrame * adsoffset).Rotation + (camera.CFrame * adsoffset).Position, delta * 20)
	else
		if not eqquiped then return end
		viewmodel.HumanoidRootPart.CFrame = camera.CFrame
	end
end)

It’s not really an example, but should be like this

runservice:BindToRenderStep("Viewmodel", Enum.RenderPriority.Camera.Value + 1, function(delta)
	if ads == true then
local goalCFrame = camera.CFrame * adsoffset
local goalRotationCFrame = viewmodel.HumanoidRootPart.CFrame:Lerp((goalCFrame), delta * 20)
		viewmodel.HumanoidRootPart.CFrame = goalRotationCFrame.Rotation +goalCFrame .Position
	else
		if not eqquiped then return end
		viewmodel.HumanoidRootPart.CFrame = camera.CFrame
	end
end)

It solved the CFrame position lag but not the CFrame rotation lag, also for some reason the transition is not smooth anymore.

That’s just progress fix one problem onto the next.

The next step I can suggest is comparing your code with tutorials.

By comparing your solution with this other post will notice you also need to perform rotation lerping when the sights is not aid in order to smoothly return to normal non aim down sights.

Also this tutorial helps as well and you haven’t mentioned if you used it or had specific problems with it.