Tweening 2 properties at the same but at different speeds

Say I am trying to create a fireball.
I would like the fireball to smoothly spin really fast, but move very slow.

I have tried using a coroutine to run a while loop and spin the model.

local function infiniteSpin(model, moveTime)
	while model do
		local tween = ts:Create(model.PrimaryPart, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {CFrame = model.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(20), 0)})
		tween:Play()
		tween.Completed:Wait(1)
	end
end

But then when I try tweening the position, the ball stays in place.

local tween = ts:Create(newBall.PrimaryPart, TweenInfo.new(moveTime, Enum.EasingStyle.Linear), {CFrame = mousePos})
	tween:Play()

Any support is appreciated, thanks.

What you are doing right now is tweening CFrame, and regardless if its position or Orientation, one will override the other. You could try using AngularVelocity to replace the second Orientation Tween, but I am not that familiar so I cannot guarantee that my proposed solution will work.

You need to create two separate tweens: one for the rotation and one for the position. Using coroutines will allow you to run these tweens simultaneously.

local TweenService = game:GetService("TweenService")

local function infiniteSpin(model)
    while model do
        local spinTween = TweenService:Create(model.PrimaryPart, TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, -1, true), {CFrame = model.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(20), 0)})
        spinTween:Play()
        wait(0.5)
    end
end

local function moveModel(model, moveTime, targetCFrame)
    local moveTween = TweenService:Create(model.PrimaryPart, TweenInfo.new(moveTime, Enum.EasingStyle.Linear), {CFrame = targetCFrame})
    moveTween:Play()
    moveTween.Completed:Wait()
end

local fireball = -- your fireball model
local moveTime = 5 -- time in seconds to move the fireball
local targetCFrame = CFrame.new(Vector3.new(0, 10, 0)) -- target position

-- Start spinning the fireball
coroutine.wrap(infiniteSpin)(fireball)

-- Move the fireball to the target position
moveModel(fireball, moveTime, targetCFrame)

Hi, thank you for your reply.
The result is that my part tweens to the CFrame given. However, the spinning tween does not play until the movement tween is complete.
I have tried using RunService.Heartbeat to rotate my part, and tween the CFrame to move it. But my part does not rotate until the movement tween is complete.

I’ve run into this issue months ago many times, and I found out 2 good solution:

First off, you can’t make 2 seperate tweens that both edit CFrame, as CFrame defines both position and orientation.
You can fix this either by, tweening the position of the part instead of the CFrame, and then tweening the orientation in a different script.
Or, instead of tweening the part to move, use a body mover like linear velocity or body velocity to move it forward, and then tween the CFrame.angles() in one tween.

1 Like

Combining the rotation and movement of a fireball can be a bit tricky, especially if you want both effects to happen simultaneously. One approach to achieve this is to use a combination of TweenService for smooth movement and a separate coroutine or RunService to handle the continuous spinning.

Here’s a step-by-step guide to achieve the desired effects:

1. Tweening the Movement

Use TweenService to smoothly move the fireball to the target position.

2. Spinning the Fireball

Use RunService to continuously rotate the fireball.

Here’s a sample script that demonstrates this approach:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

-- Function to create and launch a fireball
local function createFireball(startPos, targetPos, moveTime)
    -- Create the fireball model
    local fireball = Instance.new("Part")
    fireball.Size = Vector3.new(2, 2, 2)
    fireball.Position = startPos
    fireball.Anchored = true
    fireball.CanCollide = false
    fireball.BrickColor = BrickColor.new("Bright orange")
    fireball.Material = Enum.Material.Neon
    fireball.Parent = workspace

    -- Tween to move the fireball
    local tweenInfo = TweenInfo.new(moveTime, Enum.EasingStyle.Linear)
    local goal = {Position = targetPos}
    local moveTween = TweenService:Create(fireball, tweenInfo, goal)

    -- Function to spin the fireball
    local function spinFireball()
        while fireball do
            fireball.CFrame = fireball.CFrame * CFrame.Angles(0, math.rad(20), 0)
            RunService.RenderStepped:Wait()
        end
    end

    -- Start the spinning in a coroutine
    coroutine.wrap(spinFireball)()

    -- Play the movement tween
    moveTween:Play()

    -- Cleanup after the tween is completed
    moveTween.Completed:Connect(function()
        fireball:Destroy()
    end)
end

-- Example usage
local startPos = Vector3.new(0, 10, 0)
local targetPos = Vector3.new(50, 10, 0)
local moveTime = 5 -- Duration in seconds
createFireball(startPos, targetPos, moveTime)

Explanation:

  1. Creating the Fireball:

    • A new Part is created to represent the fireball.
    • The fireball is set to be anchored and non-collidable.
  2. Tweening the Movement:

    • TweenService is used to create a tween that moves the fireball from the start position to the target position over a specified duration (moveTime).
  3. Spinning the Fireball:

    • A coroutine is used to continuously rotate the fireball. The RunService.RenderStepped event is used to update the rotation each frame.
    • The fireball is rotated around the Y-axis by 20 degrees each frame.
  4. Cleanup:

    • After the movement tween completes, the fireball is destroyed to free up resources.

Key Points:

  • The fireball smoothly moves to the target position using TweenService.
  • The fireball continuously spins using a coroutine and RunService.RenderStepped.
  • The script handles cleanup by destroying the fireball after the movement is complete.

This approach ensures that both the movement and spinning effects are applied simultaneously and smoothly.