Model tween going in the wrong direction after cloning

I’m following up to a post I made yesterday questioning how to create VFX and this tackles a different issue in the process so sorry if this is considered a duplicate post!

To recap, this is an animation that I worked on in Moon Animator and I am currently transferring the effects over into the actual product:

The process of making the VFX function in the in game animation itself has been a bit of a process but I am almost done with it! Just a small thing that I cannot seem to figure out currently.

I have figured out how to tween a model using a combination of the primary part and the pivot point to animate it, but the model is going off in a seemingly consistent direction. It is shown in the video here: (Rocks are flying up in the sky to demonstrate the problem clearly.)


For the rocks, I want them to go straight upwards instead of veering off in a random direction. My leading theory is that the rocks are attempting to return to the point at which they are called from replicated storage, but looking back at the picture compared to the footage it seems like a completely different direction. Image below:

I’m sure this is a small fix and that it’s just something I’m not able to wrap my head around just yet. I will leave the code that conducts the animation to play: (Everything commented out is unrelated to the problem.

			buster:GetMarkerReachedSignal("Effects"):Connect(function()
				
				print("Effects marker reached")
				
				--local shockwaveEffect = shockwave:Clone()
				
				local rocksEffect = rocks:Clone()
				local primaryRock = rocksEffect.PrimaryPart --Gets the Rock Spawn part in rocks:Clone()
				local rocksCFrame = primaryRock.CFrame --Gets the CFrame of the primary part for animating
				
				local explosionEffect = explosion:Clone()
				
				--[[shockwaveEffect.Position = humanPlayer.Position + Vector3.new(0, -2.5, 0) --Cloning for parts
				shockwaveEffect.Parent = workspace]]
				
				rocksEffect:PivotTo(characterDirection + Vector3.new(0, -4, 0)) --Cloning for models
				rocksEffect.Parent = workspace
				
				--[[explosionEffect.Position = humanPlayer.Position --Cloning for parts
				explosionEffect.Parent = workspace
				
				local shockwaveInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
				local shockwaveProperties = {
					["Size"] = Vector3.new(0.169, 20, 20),
					["Transparency"] = 1
				}
				local shockwaveTween = tweenService:Create(shockwaveEffect, shockwaveInfo, shockwaveProperties)]]
				
				local rockInfo = TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
				local rockProperties = {
					["CFrame"] = rocksCFrame + Vector3.new(0, 50, 0), --Tween the primary part
						
				}
				local rockTween = tweenService:Create(primaryRock, rockInfo, rockProperties)
				
				--shockwaveTween:Play()
				rockTween:Play()
				wait(2)
				--shockwaveEffect:Destroy()
				rocksEffect:Destroy()
				--explosionEffect:Destroy()

Again, sorry if this is considered a duplicate post!

What is characterDirection? Is it the character’s Vector3 position?

Oh, my bad! CharacterDirection is the player characters CFrame. Let me post the entire block up to the problem point. (Apologies for the naming conventions, I plan to fix them after I get everything working)

local replicatedStorage = game:GetService("ReplicatedStorage")
local busterFolder = replicatedStorage:WaitForChild("Buster")
local busterFunction = busterFolder:WaitForChild("BusterFunction")
local runService = game:GetService("RunService")
local tweenService = game:GetService("TweenService")
local effectsFolder = replicatedStorage:WaitForChild("Effects")
local part = Instance.new("Part")

busterFunction.OnServerInvoke = (function(player)
	
	print(player.Name.." called this function on the server")
	
	local mainChar = player.Character
	local humanPlayer = mainChar:WaitForChild("HumanoidRootPart")
	local characterDirection = humanPlayer.CFrame
	local cf = humanPlayer.CFrame * CFrame.new(0, 0.5, -0.5)
	local size = Vector3.new(3, 1, 3)
	local parameters = OverlapParams.new()
	local characterDirection = humanPlayer.CFrame
	local throwConnect = false
	

	--Part is only for visualizing the hitbox for testing purposes
	part.Anchored = true
	part.CanCollide = false
	part.CanQuery = false
	part.CanTouch = false
	part.CastShadow = false
	part.BrickColor = BrickColor.new("Really red")
	part.Material = Enum.Material.SmoothPlastic
	part.CFrame = cf
	part.Size = size
	part.Transparency = 0.5 --Change this value to 1 to disable the hitbox and to 0.5 to see it
	part.Parent = workspace
	----------------------------------------------------------
	
	parameters.FilterDescendantsInstances = {mainChar} --Filters out own character from being hit
	parameters.MaxParts = 1
	local hitbox = workspace:GetPartBoundsInBox(cf, size, parameters)
	
	if #hitbox == 1 then --If Pot Buster hits we find the player who got hit then run the animation
		local humanoid = hitbox[1].Parent:FindFirstChild("Humanoid")
		local enemy = humanoid.Parent:FindFirstChild("HumanoidRootPart")
		throwConnect = true
		if humanoid then
			
			local shockwave = effectsFolder:WaitForChild("Shockwave")
			local rocks = effectsFolder:WaitForChild("Rocks")
			local explosion = effectsFolder:WaitForChild("Explosion")
			
			local busterAnim = game.StarterPack["Ro-Buster"]:WaitForChild("Hit")
			local buster = player.Character.Humanoid:LoadAnimation(busterAnim)
			local busterVictimAnim = game.StarterPack["Ro-Buster"]:WaitForChild("Victim")
			local victimAnim = humanoid:LoadAnimation(busterVictimAnim)
			
			buster:GetMarkerReachedSignal("Effects"):Connect(function()
				
				print("Effects marker reached")
				
				--local shockwaveEffect = shockwave:Clone()
				
				local rocksEffect = rocks:Clone()
				local primaryRock = rocksEffect.PrimaryPart --Gets the Rock Spawn part in rocks:Clone()
				local rocksCFrame = primaryRock.CFrame --Gets the CFrame of the primary part for animating
				
				local explosionEffect = explosion:Clone()
				
				--[[shockwaveEffect.Position = humanPlayer.Position + Vector3.new(0, -2.5, 0) --Cloning for parts
				shockwaveEffect.Parent = workspace]]
				
				rocksEffect:PivotTo(characterDirection + Vector3.new(0, -4, 0)) --Cloning for models
				rocksEffect.Parent = workspace
				
				--[[explosionEffect.Position = humanPlayer.Position --Cloning for parts
				explosionEffect.Parent = workspace
				
				local shockwaveInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
				local shockwaveProperties = {
					["Size"] = Vector3.new(0.169, 20, 20),
					["Transparency"] = 1
				}
				local shockwaveTween = tweenService:Create(shockwaveEffect, shockwaveInfo, shockwaveProperties)]]
				
				local rockInfo = TweenInfo.new(5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
				local rockProperties = {
					["CFrame"] = rocksCFrame + Vector3.new(0, 50, 0), --Tween the primary part
						
				}
				local rockTween = tweenService:Create(primaryRock, rockInfo, rockProperties)
				
				--shockwaveTween:Play()
				rockTween:Play()
				wait(2)
				--shockwaveEffect:Destroy()
				rocksEffect:Destroy()
				--explosionEffect:Destroy()
				
			end)		

I mean, stuff can be really goofy so just to make sure that it doesn’t include orientation through CFrame – you can actually just use CFrame.new(primaryRock.Position) (or CFrame.new(rocksEffect:GetPivot().Position) instead

local rockProperties = {
					["CFrame"] = CFrame.new(primaryRock.Position) + Vector3.new(0, 50, 0), --Tween the primary part			
				}

Try calling rocksEffect:PivotTo before assigning PrimaryPart CFrame to the rocksCFrame variable like this:

local rocksEffect = rocks:Clone()
local primaryRock = rocksEffect.PrimaryPart
rocksEffect:PivotTo(characterDirection + Vector3.new(0, -4, 0))
rocksEffect.Parent = workspace
local rocksCFrame = primaryRock.CFrame

Oh I knew it was something small like that! Worked perfectly.