Tween does not play the first time, but plays every time afterwards

Hello!

I’ve made a rolling system, where the player can roll forwards.
To create the effect of them moving forward, I’ve tweened the CFrame of their character’s HumanoidRootPart. The problem is, the first time, the player just teleports - but every time after that, the tween works.

Here’s the code:

local ts = game:GetService("TweenService")

--indentation because it's in a function
    local rootPart:Part = hum.Parent.HumanoidRootPart
	local origin = rootPart.CFrame.Position
	local direction = rootPart.CFrame.LookVector * 65
	
	local params = RaycastParams.new()
	params.FilterDescendantsInstances = hum.Parent:GetDescendants()
	params.FilterType = Enum.RaycastFilterType.Exclude
	
	local hit = workspace:Raycast(origin, direction, params)
	
	local targetCFrame:CFrame = rootPart.CFrame + rootPart.CFrame.LookVector * 45.5
	if hit then
		targetCFrame = CFrame.new(hit.Position, rootPart.CFrame.LookVector)
	end
	
    local tween:Tween = ts:Create(
		rootPart,
		TweenInfo.new(
			playAnim.Length / 2.85, --an animation length
			Enum.EasingStyle.Sine, Enum.EasingDirection.Out
		),
		{CFrame = targetCFrame}
	)
	
	tween:Play()
	tween.Completed:Wait()

The raycasting is there to stop them going through walls. I thought it might be relevant.

There are no errors or warnings in the output, and I’ve tried debugging with print statements.

Any help is appreciated.

confusion, I still need help :frowning:

4 Likes
local ts = game:GetService("TweenService")

-- Assuming 'hum' is already defined somewhere in your code
local rootPart = hum.Parent.HumanoidRootPart
local origin = rootPart.CFrame.Position
local direction = rootPart.CFrame.LookVector * 65

-- Create RaycastParams
local params = RaycastParams.new()
params.FilterDescendantsInstances = hum.Parent:GetDescendants()
params.FilterType = Enum.RaycastFilterType.Whitelist -- Change to Whitelist if you want to specify which objects to include instead of exclude

-- Perform the raycast
local hit = workspace:Raycast(origin, direction, params)

-- Calculate target CFrame
local targetCFrame = rootPart.CFrame + rootPart.CFrame.LookVector * 45.5
if hit then
    targetCFrame = CFrame.new(hit.Position, rootPart.CFrame.LookVector)
end

-- Create tween
local playAnim = {} -- Assuming playAnim is defined somewhere in your code
local tween = ts:Create(
    rootPart,
    TweenInfo.new(
        playAnim.Length / 2.85, --an animation length
        Enum.EasingStyle.Sine,
        Enum.EasingDirection.Out
    ),
    {CFrame = targetCFrame}
)

-- Play tween
tween:Play()
tween.Completed:Wait()

local playAnim = {}

2 Likes

Can you upload a video here showing the problem? Based on the code you sent I couldn’t see anything wrong with it.

1 Like

Please could you point out what parts you changed? I saw you changed the RaycastFilterType, but Whitelist is deprecated and Exclude works fine because I need to not include the character and that’s it.

1 Like

Yeah. Give me a few minutes and I’ll send one.

1 Like

Video showing issue:

Video showing how it should be:

1 Like

My assumption is the animation isn’t yet fully loaded when the tween plays and thus

would equate to 0, as the Length would be 0.

4 Likes

Do you have any idea how to fix it? I can’t yield the code because that would mess with the animation timing and the tween, because the animation plays on the client. Can you use ContentProvider:PreloadAsync() on an animation ID or not?

Edit: I tested with ContentProvider:PreloadAsync() and it didn’t work. :frowning:

Edit 2: You’re completely right. For some reason, when debugging with print statements, I didn’t think of making it print the animation length. But, the first time, it outputs 0, then the actual animation length afterwards.

1 Like

Strange, I feel like PreloadAsync() should be able pre-load an animation. Are you attempting to load the ID or the Animation instance?

1 Like

I tried both, and then each one at a time, but it yielded infinitely. I think you can only preload image content and instances.

1 Like

Why don’t you just use Anim.Length? and check if it’s over 0

1 Like

I just tested it myself and it worked fine:

local players = game:GetService("Players")
local contentprovider = game:GetService("ContentProvider")
local player = players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

-- create the animation instance
local animation = Instance.new("Animation")
animation.AnimationId = "http://www.roblox.com/asset/?id=507771019" -- Roblox dance emote
contentprovider:PreloadAsync({animation}) -- Without this, the length printed was 0

local animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()

print(animationTrack.Length)
3 Likes

This works better than my solution as long as it works, I was under the impression after reading their previous post that it didn’t work with animations, which was confusing, but yea anyways it’s better than checking each function call for if it’s over 0

1 Like

You can use a fixed animation length instead of playAnim.Length, since diving isn’t one of those animations that tend to change over gameplay time. You’re also tweaking the value itself empirically with a divisor so it seems like you want it to stay at a consistent value.

Preloading should work on animations. It’s very likely an implementation error. See post below.

2 Likes

Interesting, I’ll have another look at it. It might be that I just put the desired length straight into the TweenInfo, like what @treebee63 said. Thanks everyone for the help :smiley:

1 Like

Yeah, like @treebee63 said, preloading worked - I did it slightly wrong. I made it print the length of the tween I wanted to play, and now it works just fine. Thanks for your help everyone. :smiley:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.