How to create first person model Cosine animation?

I’ve made multiple posts on this. I can’t get a proper answer. But here we go again.

Let me be more specific:

  • This is a walking/running animation. I may use it for idle stuff too.
  • I want to use math for moving a model as I want to play animations with it.
  • It is for a first person model. So I want to move the whole model.

If anyone knows, please let me know. I haven’t gotten any answers so far on multiple posts, and I would greatly appreciate it.

I would love to help, but I’m not sure what you mean.
Do you have any scripts, videos, etc that show what you’re trying to do?

1 Like

Arsenal is a great example. I also want to know how to make the gun lerp back to the original position when your done walking/running.

Let’s say that we already have the animation loaded.
You could use:

while true do
	wait()
	if not game.Players.LocalPlayer.Character:WaitForChild("Humanoid").MoveDirection == Vector3.new(0, 0, 0) then
		if not animation.IsPlaying then
			animation:Play()
		end
	else
		animation:Stop
	end
end
2 Likes

I assume you’re using a viewmodel with the gun and arms all attached together?

You could store a CFrameValue to use as an animation offset, and you can manipulate its value when the player begins moving. CFrame the viewmodel at its base position (in front of the camera or whatever) and then multiply it by the CFrameValue.

You can use the sin and cos functions to get X and Y points you can use as a direction vector, multiply them to change the amplitude or radius.

local a = 0
local speed = 5
local radius = 2

game:GetService("RunService").RenderStepped:Connect(function(dt)
a += dt*speed

local X, Y = math.cos(a)*radius, math.sin(a)*radius
--//Use X and Y as an offset

end)
4 Likes

Well I wanted to use math for these animations. So I can play animations over them.

So I have been tweaking with the code, and I can’t seem to NOT get the “Vector3 expected, got CFrame” error, or in between. Anything I’m doing wrong here?

local runservice = game:GetService("RunService")
local RepFirst = game.ReplicatedFirst

local Cam = workspace.CurrentCamera
local CamPos = Cam.CFrame

local Plr = game.Players.LocalPlayer
local Chr = Plr.CharacterAdded:Wait()

local Model = RepFirst.Luger
local Tool = script.Parent

local isRunning

Tool.Equipped:Connect(function()
	Luger = Model:Clone()
	Luger.Parent = workspace
	
	local GunPos = Luger.CameraBone
	
	local a = 0
	local speed = 5
	local radius = 2
	
	running = game:GetService("RunService").RenderStepped:Connect(function(dt)
		a += dt*speed

		GunPos.CFrame = CFrame.new(Cam.CFrame)

		local X, Y = math.cos(a)*radius, math.sin(a)*radius
		GunPos.CFrame = CFrame.new(Cam.CFrame * CFrame.new(X,Y,0))

	end)

end)

Tool.Unequipped:Connect(function()
	Luger:Destroy()
	running:Disconnect()
end)

Just don’t wrap it in a CFrame.new() call, try this instead:

GunPos.CFrame = Cam.CFrame * CFrame.new(X,Y,0)

Edit:

Also this line:

GunPos.CFrame = CFrame.new(Cam.CFrame)

should be

GunPos.CFrame = CFrame.new(Cam.CFrame.Position)
1 Like

It works, it just keeps moving in circles. How do I make it move in a :infinity: motion?

Edit: How do I make it work when the player runs? And I need to lerp the gun to the Camera position as well. I’ve tried to figure that out but I haven’t gotten it to work. It just stays in the air. Heres my code:

local runservice = game:GetService("RunService")
local RepFirst = game.ReplicatedFirst

local Cam = workspace.CurrentCamera
local CamPos = Cam.CFrame

local Plr = game.Players.LocalPlayer
local Chr = Plr.CharacterAdded:Wait()

local Model = RepFirst.Luger
local Tool = script.Parent

local isRunning = false

Tool.Equipped:Connect(function()
	Luger = Model:Clone()
	Luger.Parent = workspace
	
	local GunPos = Luger.CameraBone
	
	local a = 0
	local speed = 5
	local radius = 2
	
	while true do
		wait()
		if not game.Players.LocalPlayer.Character:WaitForChild("Humanoid").MoveDirection == Vector3.new(0, 0, 0) then
			if not isRunning then
				isRunning = true
				running = game:GetService("RunService").RenderStepped:Connect(function(dt)
					a += dt*speed

					GunPos.CFrame = CFrame.new(Cam.CFrame.Position)

					local X, Y = math.cos(a)*radius, math.sin(a)*radius
					GunPos.CFrame = Cam.CFrame * CFrame.new(X,Y,0)

				end)
			end
		else
			isRunning = false
		end
	end

end)

Tool.Unequipped:Connect(function()
	wait(1)
	Luger:Destroy()
end)
1 Like

Okay so the key line here is this:


local X, Y = math.cos(a)*radius, math.sin(a)*radius

Which just needs tweaking to


local X, Y = math.cos(2*a)*radius, math.cos(a)*radius

Which makes the x movement twice as frequent as the y movement which should give the pattern you want.

1 Like

ohhhhh thanks. Now i just need to fix my walking and lerping problem

This type of pattern is a lissajous curve, there are others that you can produce by using different frequency ratios and phase offsets

1 Like

The actual code I wrote is wrong in the previous comment, it should be

local X, Y = radius*math.cos(a), radius*math.sin(2*a)

It should be the the y axis twice as frequent and also a phase offset is needed (hence cos and sin)

Edit: Desmos link

Ah, much better. Thank you so much!

1 Like