Model to camera tween not working

Hello developers,

I am trying to create a script that makes bobbing, and when you start walking, it tweens it to a cframe function. But for some reason it keeps saying “Unable to cast to Dictionary” and I can’t seem to figure out why.

Anything helps, my script is local, and this is inside a tool. Heres my script:

local tool = script.Parent

-- added
local connection

--CFRAME CAMERA CRAP AUGH EJEPGIHJEGPOIHETGOIHFEIOPJFEI

local debounce = true

local equipped = false

local player = game.Players.LocalPlayer

local mouse = player:GetMouse()

tool.Equipped:Connect(function()
	local player = game.Players.LocalPlayer
	local char = player.Character or player.CharacterAdded:Wait()
	player.CameraMode = Enum.CameraMode.LockFirstPerson

	local model = game:GetService("ReplicatedFirst").Viewmodel:Clone()
	model.Name = "MODEL"
	model.Parent = workspace
	
	local tweenservice = game:GetService("TweenService")

	connection = game:GetService("RunService").RenderStepped:Connect(function()
		model:WaitForChild("Humanoid").Animator:LoadAnimation(model.Idle):Play()
		model:SetPrimaryPartCFrame(workspace.CurrentCamera.CFrame * CFrame.new(0,0,0))
		
--problem starts here
		if char:WaitForChild("Humanoid").MoveDirection.Magnitude > 0 then
			local currentCF = workspace.CurrentCamera.CFrame
			local t = tick()

			local head = model

			local x = math.cos(t * 2) * 0.2
			local y = math.abs(math.sin(t * 5)) * 0.1

			local cf = currentCF * CFrame.new(x, y, 0)

			head:SetPrimaryPartCFrame(cf)
		else
			local tweeninfo = TweenInfo.new(1, Enum.EasingStyle.Exponential, Enum.EasingDirection.In, 0,false,0)
			local goal = {model.CameraBone}
			
			tweenservice:Create(model,tweeninfo,goal):Play() -- "Unable to cast to dictionary"
		end
	end)
-- problem ends here
	
	local function Hidegunl(transparency)
		for i,v in pairs(tool:GetChildren()) do
			if (v:IsA("BasePart")) then -- Only baseparts have a LocalTransparencyModifier property.
				v.LocalTransparencyModifier = transparency;
			end
		end
	end
	
	game:GetService("RunService").RenderStepped:Connect(function()
		Hidegunl(1)
	end)
	
end)

tool.Unequipped:Connect(function()
	equipped = false
	local player = game.Players.LocalPlayer
	local icon = player:GetMouse().Icon
	player.CameraMode = Enum.CameraMode.Classic
	-- added
	connection:Disconnect() -- prevent that function in RenderStepped from running again and printing errors
	workspace:WaitForChild("MODEL"):Destroy()
end)
1 Like

The third parameter of TweenSerivce:Create is a dictionary of properties.
Example: Tweening a part

{
	Size = Vector3.new(5,4,3),
	Position = Vector3.new(0,75,0)
}

This tweens the Part’s size to 5,4,3 and position to 0,75,0

In your code

You forgot to set the property for the tween. And what is model.CameraBone?

If you are tweening a model, a possible solution is to tween the primary part.

2 Likes

Basically the humanoidrootpart of the model, it controls the camera. But it also acts as the actual camera because humanoidrootpart is the main primary part. And with my animation, its continuously moving the whole model. so it would be tweening it to its exact position. I’m trying to figure out how to tween the entire model to the position of the currentcamera.

update: figured out what went wrong, one second

Yea, can’t get it to cast to dictionary…

If you want the model to go to CurrentCamera.CFrame then use it as the goal

local goal = {CFrame = workspace.CurrentCamera.CFrame}

And if model.CameraBone is the primary part, then you could just do

tweenservice:Create(model.CameraBone,tweeninfo,goal):Play()
1 Like

Just stays there for the tweened time, how can i still make it stay in the cameras position but tween it to 0,0,0 (from cam)?

Tweening to 0,0,0? Then use this as the goal

local goal = {CFrame = CFrame.identity}

I just want to point out problems in this code.
First of all, these problems are inside a RenderStepped connection, which runs about ~60 times per second.

You can load the animation outside of the connection, then play it inside

local animIdle = model:WaitForChild("Humanoid").Animator:LoadAnimation(model.Idle)
connection = game:GetService("RunService").RenderStepped:Connect(function()
	animIdle:Play()

.

Set a local variable for the humanoid outside of the connection. Calling WaitForChild repeatitively may lag the player.

local humanoid = char:WaitForChild("Humanoid")
...
connection = game:GetService("RunService").RenderStepped:Connect(function()
...
	if humanoid.MoveDirection.Magnitude > 0 then

.

You are instantly setting the model’s position to the camera, yet your problem is tweening to the camera? Plus, multiplying a CFrame by 0,0,0 or identity changes nothing.

Let’s say you are not moving (MoveDirection.Magnitude == 0).

Like the previous problem, you already set the model to the camera cframe, yet you want to tween the model to the camera cframe.

1 Like

Yea i only want it to when i start walking and when i stop walking.

If I am understanding this correctly, you want the model to teleport to the camera when moving, and you want it to tween if you are not moving?

One sec:

When i start walking, it starts to bob around when i walk

BUT: When I stop walking, i want the position of the model to tween to the cameras position, so it doesnt teleport there.

1 Like

This is the whole tool.Equipped

tool.Equipped:Connect(function()
	local player = game.Players.LocalPlayer
	local char = player.Character or player.CharacterAdded:Wait()
	player.CameraMode = Enum.CameraMode.LockFirstPerson

	local model = game:GetService("ReplicatedFirst").Viewmodel:Clone()
	model.Name = "MODEL"
	model.Parent = workspace
	local humanoid = char:WaitForChild("Humanoid")

	local tweenservice = game:GetService("TweenService")
	local animIdle = model:WaitForChild("Humanoid").Animator:LoadAnimation(model.Idle)
	local wasMoving = false
	connection = game:GetService("RunService").RenderStepped:Connect(function()
		animIdle:Play()

		if humanoid.MoveDirection.Magnitude > 0 then
			local currentCF = workspace.CurrentCamera.CFrame
			local t = time()

			local head = model

			local x = math.cos(t * 2) * 0.2
			local y = math.abs(math.sin(t * 5)) * 0.1

			local cf = currentCF * CFrame.new(x, y, 0)

			head:SetPrimaryPartCFrame(cf)
			wasMoving = true
		elseif wasMoving then
			local tweeninfo = TweenInfo.new(1, Enum.EasingStyle.Exponential, Enum.EasingDirection.In, 0,false,0)
			local goal = {CFrame = workspace.CurrentCamera.CFrame}
			
			tweenservice:Create(model.CameraBone,tweeninfo,goal):Play()
			wasMoving = false
		end
	end)
	
	local function Hidegunl(transparency)
		for i,v in pairs(tool:GetChildren()) do
			if (v:IsA("BasePart")) then -- Only baseparts have a LocalTransparencyModifier property.
				v.LocalTransparencyModifier = transparency;
			end
		end
	end
	
	game:GetService("RunService").RenderStepped:Connect(function()
		Hidegunl(1)
	end)
	
end)

Hopefuly this works

1 Like

Sadly this happens, no animation either. Perhaps theres another way to get the arms to the position of the camera smoothly?

Ah, I see, you will need Lerping instead of Tweening.

tool.Equipped:Connect(function()
	local player = game.Players.LocalPlayer
	local char = player.Character or player.CharacterAdded:Wait()
	player.CameraMode = Enum.CameraMode.LockFirstPerson

	local model = game:GetService("ReplicatedFirst").Viewmodel:Clone()
	model.Name = "MODEL"
	model.Parent = workspace
	local humanoid = char:WaitForChild("Humanoid")
	local animIdle = model:WaitForChild("Humanoid").Animator:LoadAnimation(model.Idle)

	local lerpSpeed = 10 -- You can modify this
	connection = game:GetService("RunService").RenderStepped:Connect(function(dt)
		animIdle:Play()

		if humanoid.MoveDirection.Magnitude > 0 then
			local currentCF = workspace.CurrentCamera.CFrame
			local t = time()

			local head = model

			local x = math.cos(t * 2) * 0.2
			local y = math.abs(math.sin(t * 5)) * 0.1

			local cf = currentCF * CFrame.new(x, y, 0)

			head:SetPrimaryPartCFrame(cf)
		else
			model.CameraBone.CFrame = model.CameraBone.CFrame:Lerp(workspace.CurrentCamera.CFrame,dt*lerpSpeed)
		end
	end)
	
	local function Hidegunl(transparency)
		for i,v in pairs(tool:GetChildren()) do
			if (v:IsA("BasePart")) then -- Only baseparts have a LocalTransparencyModifier property.
				v.LocalTransparencyModifier = transparency;
			end
		end
	end
	
	game:GetService("RunService").RenderStepped:Connect(function()
		Hidegunl(1)
	end)
	
end)
1 Like

Didn’t work… Same thing happens, what does :Lerp do?

Weird, can you try this.

model:PivotTo(model:GetPivot():Lerp(workspace.CurrentCamera.CFrame,dt*lerpSpeed))

There are multiple topics about lerp. But here’s a summary.

LERP means Linear Interpolation. Imagine, a line, 0% to 100%

You will pick a “percentage” of the way to 100%. Let’s say 35%, then you are 35% on the way to the end.

Let’s use a Vector3 for example. From 0,0,0 to 50,50,50, we will go 60%.

1 Like

This doesn’t quite solve the problem, but solves my other problem. Also now my equip animation lags out until i start moving.

Example: