How To Make A Player Move With A Tweening Model

Hello I need Help So bad, just before explaining i want to say that i did research and nothing worked, I am tweening a train using a module and i want to move the player with the train

TweenModule.TweenModulePosition(model,TweenInfo.new(50, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut),Vector3.new(3927, 6.85, 479))

1 Like

You can either weld the character’s primary part to one of the train’s parts, or if you’d prefer the character to still be able to move while on top of the train you can use the Humanoid physics controller:

I made a part when touched it changed the primary part to the part of the train and when untouched it restores the primary part to humanoidrootpart but the player isnt moving

May check this out:

It’s not a good idea to change the primary part of the player’s character, which is why I recommended to weld it to one of the train’s parts, like for example the train’s roof

that works but i would like the player to move, rn i am using this script

local Players = game:GetService("Players")
script.Parent.Touched:Connect(function(touch: BasePart)
	local model:Model = touch:FindFirstAncestorWhichIsA("Model")
	local hum:Humanoid? = model and model:FindFirstChildWhichIsA("Humanoid")
	
	if hum then
		local plr = Players:GetPlayerFromCharacter(model)
		local weld = Instance.new("Weld",model.PrimaryPart)
		weld.Part0=model.PrimaryPart
		weld.Part1=script.Parent
		--model.PrimaryPart=script.Parent
	end
end)

script.Parent.TouchEnded:Connect(function(touch: BasePart)
	local model:Model = touch:FindFirstAncestorWhichIsA("Model")
	local hum:Humanoid? = model and model:FindFirstChildWhichIsA("Humanoid")

	if hum then
		local plr = Players:GetPlayerFromCharacter(model)
		
		if model.PrimaryPart:FindFirstChild("Weld") then
			model.PrimaryPart.Weld:Destroy()
		end
		--model.PrimaryPart=model:WaitForChild("HumanoidRootPart")
		
	end
end)

and when i touch the part it makes me in a fixed position that does move with the train but it doesnt make the character able to move

Well, in that case you’ll need to use the physics controller like I previously mentioned. To do so, you’ll need to add this as a server Script in ServerScriptService:

-- Replace Humanoid physics with a ControllerManager when a character loads into the workspace

local Players = game:GetService("Players")

function initialize(character)

	local cm = Instance.new("ControllerManager")
	local gc = Instance.new("GroundController", cm)
	Instance.new("AirController", cm)
	Instance.new("ClimbController", cm)
	Instance.new("SwimController", cm)

	local humanoid = character.Humanoid
	cm.RootPart = humanoid.RootPart
	gc.GroundOffset = humanoid.HipHeight
	cm.FacingDirection = cm.RootPart.CFrame.LookVector

	local floorSensor = Instance.new("ControllerPartSensor")
	floorSensor.SensorMode = Enum.SensorMode.Floor
	floorSensor.SearchDistance = gc.GroundOffset + 0.5
	floorSensor.Name = "GroundSensor"

	local ladderSensor = Instance.new("ControllerPartSensor")
	ladderSensor.SensorMode = Enum.SensorMode.Ladder
	ladderSensor.SearchDistance = 1.5
	ladderSensor.Name = "ClimbSensor"

	local waterSensor = Instance.new("BuoyancySensor")

	cm.GroundSensor = floorSensor
	cm.ClimbSensor = ladderSensor

	waterSensor.Parent = cm.RootPart
	floorSensor.Parent = cm.RootPart
	ladderSensor.Parent = cm.RootPart
	cm.Parent = character

end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character.Humanoid.EvaluateStateMachine = false -- Disable Humanoid state machine and physics
		wait() -- ensure post-load Humanoid computations are complete (such as hip height)
		initialize(character)
	end)	
end)

and this as a LocalScript in StarterCharacterScripts:

-- A simple state machine implementation for hooking a ControllerManager to a Humanoid.
	-- Runs an update function on the PreAnimate event that sets ControllerManager movement inputs 
	-- and checks for state transition events.
	-- Creates a Jump action and "JumpImpulse" attribute on the ControllerManager.

local rs = game:GetService("RunService")
local cas = game:GetService("ContextActionService")

local character = script.Parent
local cm = character:WaitForChild("ControllerManager")
local humanoid = character:WaitForChild("Humanoid")

-- Returns true if the controller is assigned, in world, and being simulated
local function isControllerActive(controller : ControllerBase)
	return cm.ActiveController == controller and controller.Active
end

-- Returns true if the Buoyancy sensor detects the root part is submerged in water, and we aren't already swimming
local function checkSwimmingState()
	return character.HumanoidRootPart.BuoyancySensor.TouchingSurface and humanoid:GetState() ~= Enum.HumanoidStateType.Swimming
end

-- Returns true if neither the GroundSensor or ClimbSensor found a Part and, we don't have the AirController active.
local function checkFreefallState()
	return (cm.GroundSensor.SensedPart == nil and cm.ClimbSensor.SensedPart == nil 
		and not (isControllerActive(cm.AirController) or character.HumanoidRootPart.BuoyancySensor.TouchingSurface))
		or humanoid:GetState() == Enum.HumanoidStateType.Jumping
end

-- Returns true if the GroundSensor found a Part, we don't have the GroundController active, and we didn't just Jump
local function checkRunningState()
	return cm.GroundSensor.SensedPart ~= nil and not isControllerActive(cm.GroundController) 
		and humanoid:GetState() ~= Enum.HumanoidStateType.Jumping
end

-- Returns true of the ClimbSensor found a Part and we don't have the ClimbController active.
local function checkClimbingState()
	return cm.ClimbSensor.SensedPart ~= nil and not isControllerActive(cm.ClimbController)
end

-- The Controller determines the type of locomotion and physics behavior
-- Setting the humanoid state is just so animations will play, not required
local function updateStateAndActiveController()
	if checkSwimmingState() then
		cm.ActiveController = cm.SwimController
		humanoid:ChangeState(Enum.HumanoidStateType.Swimming)
	elseif checkClimbingState() then
		cm.ActiveController = cm.ClimbController
		humanoid:ChangeState(Enum.HumanoidStateType.Climbing)
	elseif checkRunningState() then
		cm.ActiveController = cm.GroundController
		humanoid:ChangeState(Enum.HumanoidStateType.Running)
	elseif checkFreefallState() then
		cm.ActiveController = cm.AirController
		humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
	end
end

-- Take player input from Humanoid and apply directly to the ControllerManager.
local function updateMovementDirection()
	local dir = character.Humanoid.MoveDirection
	cm.MovingDirection = dir

	if dir.Magnitude > 0 then
		cm.FacingDirection = dir
	else
		
		if isControllerActive(cm.SwimController) then
			cm.FacingDirection = cm.RootPart.CFrame.UpVector
		else
			cm.FacingDirection = cm.RootPart.CFrame.LookVector
		end
	end
	
end

-- Manage attribute for configuring Jump power
cm:SetAttribute("JumpImpulse", Vector3.new(0,500,0))

-- Jump input
local function doJump(actionName, inputState, inputObject)
	if inputState == Enum.UserInputState.Begin and isControllerActive(cm.GroundController) then
		local jumpImpulse = cm:GetAttribute("JumpImpulse")
		cm.RootPart:ApplyImpulse(jumpImpulse)
		
		character.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		cm.ActiveController = cm.AirController
		
		-- floor receives equal and opposite force
		local floor = cm.GroundSensor.SensedPart
		if floor then
			floor:ApplyImpulseAtPosition(-jumpImpulse, cm.GroundSensor.HitFrame.Position)
		end
	end
end
cas:BindAction("Jump", doJump, true, Enum.KeyCode.Space)

--------------------------------
-- Main character update loop --
local function stepController(t, dt)

	updateMovementDirection()
		
	updateStateAndActiveController()

end
rs.PreAnimation:Connect(stepController)

-----------------
-- Debug info ---

--humanoid.StateChanged:Connect(function(oldState, newState)
--	print("Change state: " .. tostring(newState) .. " | Change controller: " .. tostring(cm.ActiveController))
--end)

Both scripts were taken from the post I linked in my original reply:

Tweening a Part’s CFrame does not move the part physically. Its the same as setting CFrame in a stepped loop. The part has no velocity, and therefore other parts (and characters) will not interact with it property.

You’ll want to use a Mover Constraint to move your part instead. This will allow for realistic interactions with other parts and characters (including the new character controller). You won’t need to do any extra work to ensure parts sit on top of each other such as welding.