Why isn't it going where it should?

Hey everyone!
I have a script for my collectibles. When they’re touched, it anchors the player, then tweens the model to above the player. That works, except for it doesn’t get positioned properly. It’s either behind the player’s current position, or if it’s jumped on, way above where it should be. The model itself does have a script to allow it to spin, however that’s not the issue. Here’s the full script. (sorry if it’s bad, still trying to get better at scripting)

local RunService = game:GetService("RunService")
local event = game:GetService("ReplicatedStorage").RemoteEvents.PrismEvents:WaitForChild("Collected")
local ts = game:GetService("TweenService")

local name = script.Parent.PrismName
local color = script.Parent.PrismColor

local info = TweenInfo.new(
	0.2,
	Enum.EasingStyle.Back,
	Enum.EasingDirection.InOut,
	0,
	false,
	0
)

script.Parent.Collision.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if not player then return end

	script.Parent.Collision.Spin.Enabled = false
	event:FireClient(player, name.Value, color.Value)

	local character = hit.Parent
	local hrp = character:FindFirstChild("HumanoidRootPart")
	local head = character:FindFirstChild("Head")
	if not hrp or not head then return end
	
	hrp.Anchored = true
	task.wait()

	local headCFrame = head.CFrame

	local goal = {}
	goal.CFrame = headCFrame * CFrame.new(0, 4, 0)


	local tween = ts:Create(script.Parent.Collision, info, goal)
	tween:Play()

	task.wait(4)
	hrp.Anchored = false
	script.Parent:Destroy()
end)

Use tween.Completed:Wait() in replacement of task.wait(4), maybe that causes the delay to overlap with the excessive cframe operation usage.

local goal = head.CFrame * CFrame.new(0,4,0)
local tween = ts:Create(script.Parent.Collision,info, {CFrame = goal})
tween:Play()
tween.Completed:Connect(function()
	hrp.Anchored = false
	script.Parent:Destroy()
end)
1 Like

It might be because of the delays in between the definition of head.CFrame and the tweening of your part. While the script runs, if the character is still moving, the head.CFrame might be outdated at the time of moving your part, making it look off

1 Like

It’s definitely outdated, but I don’t know how to really fix that

1 Like

CFrame multiplication is relative to the parts orientation, you can try doing:

local goal = {}
goal.CFrame = CFrame.new(0, 4, 0) * headCFrame

there are a also couple of other solutions which you might want to look at:

1 Like