How to tween a anchored model

Hello, I’m trying to tween an anchored model in my game however I’m experiencing issues.

I am trying to use PrimaryPart as the tween but it doesnt function as intended. Here is my current script:

local function tweenModel(model, endCFrame)
	local primaryPart = model.PrimaryPart

	-- If there's no primary part, create a placeholder part
	if not primaryPart then
		primaryPart = Instance.new("Part")
		primaryPart.Name = "ModelCenter"
		primaryPart.Anchored = true
		primaryPart.Size = Vector3.new()
		primaryPart.CFrame = model:GetModelCFrame()
		primaryPart.Parent = model
	end

	local startCFrame = primaryPart.CFrame
	local info = TweenInfo.new(.1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	local tween = tweenService:Create(primaryPart, info, {CFrame = endCFrame})

	tween:Play()
end

and to be clear, I;m trying to run this inside of a viewportframe. So I am trying to tween the model in a viewportframe.

Basically you’re going to want to have a dummy CFrameValue and then tween that and when it’s value is changed have the model PivotTo() the new value

Something like this for example

@FriendlyEvo

local Model = workspace.Model

local DummyCFrameValue : CFrameValue = Instance.new("CFrameValue")
DummyCFrameValue.Value = Model:GetPivot()

DummyCFrameValue.Changed:Connect(function(value)
   Model:PivotTo(value)
end)

TweenService:Create(DummyCFrameValue, TweenInfo.new(1), {
   Value = Model:GetPivot() + Vector3.new(0, 10, 0)
}):Play()

add a worldmodel to the viewport, and weld every other part to the primary part, and unanchor every part (except the primary part). Then tween the primary part

the worldmodel allows welds to work in the viewport

this is not true. models still cannot animate with worldmodels.

my bad, i thought worldmodels allowed non-humanoid physics to work, your only other option is using motor6ds

This exact question has been asked and answered so many times. Please use the search feature before posting a thread.

this is true however viewportframes dont support any kind of physics and 99% of the approaches to tweeting models requires solutions such as primary parts and welding, which all rely on physics.

I ended up making this script which utilizes roblox’s pivotTo:

local runService = game:GetService("RunService")

local activeTweens = {}

local function tweenModel(model, targetCF, fps)
	if activeTweens[model] then
		activeTweens[model]:Disconnect()
		activeTweens[model] = nil
	end

	local initialCF = model:GetPivot()
	local progress = 0

	local connection
	connection = runService.RenderStepped:Connect(function(dt)
		progress = math.min(1, progress + dt * fps)

		local currentCF = initialCF:Lerp(targetCF, progress)
		model:PivotTo(currentCF)

		if progress >= 1 then
			connection:Disconnect()
			activeTweens[model] = nil
		end
	end)

	activeTweens[model] = connection
end

i would use a spring module, use a state for the cframe and use the spring to tween to the goal. spring modules should pair with signals, so you can get events for tween endings.

is there anything wrong with my current approach? I don’t see a need for a third party module considering its optimized and working well.

typically i wouldn’t rely on a runservice event because it’s based on the framerate, so your tween can run into that problem. other than that, just modularity and scaleability issues for handling tweens.

some modules like you said, shouldn’t be introduced, especially if you have an optimized and functional script. however in this case, there are problems with the way this is structured, and having a spring module will assist you in more than just tweens, such as UI effects or anything that requires a value to change in a lerp-fashion.

either way, you’re wanting a native way to make a cframe lerp, so you could use a bindable event for your lerp that can disconnect the lerp for you easily :slight_smile:

I don’t see why framerate would be an issue here as the delta time returned is the exact time since the last render call. If framerates drop the object being moved will still move correctly. Also adding an additional third party module will introduce unneeded bloat to a rather simple solution.

Also you should probably mark this as the solution.

you’re right, framerate wouldn’t be an issue, but your function will use runservice as a dependency rather than using a binding or a signal. it’s really up to the original poster on how he wants to structure his code, but it’s a good practice to use dependency events than using runservice events.

as for third party modules, bloat is subjective on how you much you utilize them and what’s actually happening in the module. some modules are bloat, yes, but that depends on the context of the module itself. the ideology that any third party module is going to bloat a game, it’s not quite true enough to determine without looking through the source, and it wouldn’t be a significant bloat as repetitively having bad handling on the framework itself.

we’re talking about a spring module here, not a whole library of modules. a spring module should be under 300 lines, and if you look at most spring modules, they’re simply taking a value and changing them to the goal, which should have a runtime complexity no bigger than O(N).

I don’t really get your use of runtime complexity here. How is lerping an object every frame any different to moving it every frame based on spring calculations? Also I see no issue in the use of RenderStepped and in turn the RunService. It accomplishes exactly what is needed, a function call right before every frame is rendered so the objects can be moved the least amount of times possible without sacrificing fidelity in the objects movement. Then again it’s up to each developer to decide on his own but I don’t see any reason to discourage the use of RunService.

To clarify I just want a linear replacement for tweening that works for a model without physics (in a viewportframe) and is based on a recording framerate.

I am using this for my recording and playback module which I am planning to make public. This tween model is used to replay the movements of models and player characters within the replay. I don’t need any kind of bouncing or springing action: just a simple linear tween that goes on an accurate framerate as defined with the parameter.

it’s all good man, i mean once you start working on a larger framework with a bunch of developers, you’ll start to understand where all of this comes in.

Do you think its really nescessary for my use case as described?

A record/playback module that records in-game experiences? This function is used to playback saved frames and use tweeting to make the frames smooth with each other despite lower framerates.

Feel free to elaborate although I struggle to see the issues you’re bringing up.

a spring module? for something like recording and playing back cached data, it’s probably best in this case to try using the exact values and tween them as you are. spring modules would be more suited towards controlled ways, like lerping models for animations or ui animations.