How could I create viewmodel sway in Roblox, like this?

This is a little bit of a weird question, but I was messing around in Garry’s Mod, when I found a pretty nice looking weapon sway addon (sorry for the lag):

I’m wondering, is it possible to make something that looks this good in Roblox? I’d assume it is, since GMod addons are made in Lua as far as I know.

Not much else to say, but I’d like to mention that I have so far tried to use spring, tweens, lerping, sine waves, and none of it looked as good as I would hope.

If it helps, this is the link to the addon. Thanks if possible.

1 Like

There are many ways to do this, however the first that comes to mind to me is a neat trick you can do to use BodyMovers, or Roblox’ relatively new Contraints, I recommend you make use of a AlignOrientation Constraint.

The general process you want to go for is to create the viewport model in workspace on the client, you want to ensure that you place it somwhere the player cannot access and that is out of sight. You then use the AlignOrientation Constraint to ensure that the viewmodel faces in the correct direction.
Inside a LocalScript, or a Script with its RunContext set to Client, you can make use of RunService’s event called “OnRenderStepped”, this event triggers every frame that your client updates, but right before it is rendered. Inside this event, you want to copy the orientation of the viewmodel in workspace, and apply it to your actual viewmodel placed inside your ViewportFrame’s Canera.

This works around the limitations of not being able to use Contraints on models inside ViewportFrames, and should achieve a similar effect to what you see in the video you provided.

Hope this helps!

1 Like

Would this break welds or motor6ds?

If you set the CFrame of the viewmodel using the Model’s SetPrimaryPartCFrame function, it should not affect the welds or joints.

1 Like

Okay- even though the solution provided by stef would probably work just as well, I ended up settling on using springs. It may not look the same or the best, but I think I can make do with it!

If anyone is curious, this is the code:

local RunService = game:GetService('RunService')
local Spring = require(script:WaitForChild('Spring'))
local Viewmodel = workspace:WaitForChild('Viewmodel')

local SwaySpring = Spring.new()
local BobSpring = Spring.new()

local function Bob(addition)
	return math.sin(tick() * addition * 1.3) * 0.5
end

local Player = game:GetService('Players').LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()

RunService.RenderStepped:Connect(function(dt)
	-- Get mouse velocity
	local Delta = game.UserInputService:GetMouseDelta()
	
	-- Shoving
	SwaySpring:shove(Vector3.new(-Delta.X/500, Delta.Y/500, 0))
	BobSpring:shove(Vector3.new(Bob(5), Bob(10), Bob(5)) / 10 * (Character.PrimaryPart.Velocity.Magnitude) / 10)
	
	-- Updating springs
	local UpdatedSway = SwaySpring:update(dt)
	local UpdatedBob = BobSpring:update(dt)
	
	-- Applying springs
	Viewmodel:PivotTo(
		workspace.CurrentCamera.CFrame *
			CFrame.new(UpdatedSway.X, UpdatedSway.Y, 0) *
			CFrame.new(UpdatedBob.X, UpdatedBob.Y, 0)
	)
end)

…and this is the spring module:

SpringModule.rbxm (1.3 KB)

This is stupidly simple for something I spent 3 hours researching on :skull:

15 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.