Character thrusting system keeps breaking

I am trying to make a thrusting system where a click of a button would thrust your player forward depending on the direction it is facing. To do this, I am using a LinearVelocity with an Attachment which connects it to the character’s HumanoidRootPart

The issue I have is that the system just glitches the player out like half the time and when it doesn’t do that, the player turns in an 110° clockwise angle (regardless if I turn my camera or not) when thrusting although it thrusts my character in the right direction.

Video showing the abilty breaking, and turning the player:

How do I fix this so that it doesn’t glitch out the player when run and doesn’t turn the player for some weird reason. Changing the speed does reduce the chance for the player to glitch out, but it doesn’t completely solve this issue

Code which handles the character’s thrusting system:

["Thrust"] = function(player, attack, config, rootPart)
		local sword = player.Character:WaitForChild("NewSword")
		local humanoid = player.Character.Humanoid
		local swordConfig = sword.Config:GetAttributes()
		
		-- Remake the force moving script
		if humanoid and rootPart then
			local Attachment = rootPart:FindFirstChild("PartAttachment")
			local speed = 50  -- Adjust the speed as needed
			humanoid.WalkSpeed = 0 -- Preventing the player from moving

			task.wait(0.83)
			
			local velocity = Instance.new("LinearVelocity", Attachment)
			local lookVector = rootPart.CFrame.lookVector
			velocity.MaxForce = math.huge
			velocity.VectorVelocity = lookVector * speed -- change 100 with how fast you want the projectile to go
			velocity.Attachment0 = Attachment
			
			-- Duration of the thrusting
			task.wait(1)
			
			-- Clean up after a short duration (adjust as needed)
			velocity:Destroy()
			
			task.wait(2)
			
			humanoid.WalkSpeed = 16
		end
		
end

If you need extra info here’s the code for creating the PartAttachment

player.CharacterAdded:Connect(function(character)
		local Attachment = Instance.new("Attachment", character.HumanoidRootPart) -- the attachment used in Linearvelocity
		Attachment.Name = "PartAttachment"
		character.Humanoid.WalkSpeed = 16
		
		character.Humanoid.Died:Connect(function()
			Attachment:Destroy()
		end)
	end)

Thanks for reading and please reply

3 Likes

LinearVelocity is pretty jank.

The first thing I’d do is disable certain humanoid states to do our best to prevent the ragdolling. Ones like falling, ragdoll, ect. Even if a player still gets flung, they’ll be on their feet at least. I also reccomending using the client to push the player instead of the server

The trickier part is to cancel the velocity if we’re very close to a wall. LinearVelocity and obstacles don’t get along, and that’s what causes all the flinging in the first lunge. The best solution is to raycast 2.5 studs in front of the player every 0.05-0.1 seconds. If we hit a wall with a raycast, we cancel the thrust entirely.

As for the weird rotation, I have no idea what’s causing that. I think it’s caused by a humanoid state type, but I’m not sure which.

3 Likes

alr ill see if these solutions work for me

1 Like

would it work if we cancel the velocity when the character’s HumanoidRootPart/torso touches a wall, etc?

1 Like

You can get what you need from here.

1 Like

Don’t mind if I do…

["Thrust"] = function(player, attack, config, rootPart)
    local sword = player.Character:WaitForChild("NewSword")
    local humanoid = player.Character.Humanoid
    local swordConfig = sword.Config:GetAttributes()

    if humanoid and rootPart then
        local Attachment = rootPart:FindFirstChild("PartAttachment")
        local speed = 50  -- Adjust the speed as needed
        humanoid.WalkSpeed = 0 -- Preventing the player from moving

        -- Create the LinearVelocity once
        local velocity = Instance.new("LinearVelocity", Attachment)
        velocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

        -- Get the look vector once
        local lookVector = rootPart.CFrame.lookVector

        -- Apply velocity
        velocity.VectorVelocity = lookVector * speed

        -- Wait for the desired duration of the thrusting
        task.wait(1)

        -- Destroy the LinearVelocity
        velocity:Destroy()

        -- Wait for a short duration (adjust as needed)
        task.wait(0.5)

        -- Restore WalkSpeed
        humanoid.WalkSpeed = 16
    end
end
1 Like

The player may already have been flung by the time .Touched fires.

Also, I heard that if the attachment isn’t set like this, Attachment.WorldPosition = HumanoidRootPart.AssemblyCenterOfMass, it may cause the weird rotation seen in the video. Haven’t tested to see if that’s the case.

1 Like

yep, the rotation thing doesn’t happen anymore after some tests, thank you

3 Likes

So far most problems have been solved with solutions that you guys posted above apart from the character flinging off walls

Apparently, someone has fixed the problem of their movement system from flinging off walls using the code below:

mover.MaxForce = Vector3.new(1, 0, 1) * 14000
mover.Velocity = hrp.CFrame.LookVector * 100

for i = 1, 8 do
	task.wait(0.1)
	mover.Velocity *= 0.7
end

His code uses BodyVelocity however, instead of a Linear Velocity and when I tried using a Vector3.new value on the MaxForce on my LinearVelocity, the character doesn’t move properly.

I figured out that BodyVelocity.MaxForce is a number value so I had to use a BodyVelocity.MaxAxesForce to get a Vector3 MaxForce value onto my LinearVelocity.

This time, the code works with no errors, but during the thrusting, my character moves a tiny amount forwards, a lot lower than my intended speed, and then stops and returns to normal. I’m sure I used the right Data Types so I think the problem comes down to the values I placed in my MaxAxesForce value.

btw here is the thread which had a similar problem which lead to the solution I found:

I will post my new function below in a moment

alr so here’s my updated code with changes that you’ve suggested

Server Script:

local ClientAbility = ReplicatedStorage.Events:FindFirstChild("ClientAbility")

["Thrust"] = function(player, attack, config, rootPart)
		local sword = player.Character:WaitForChild("NewSword")
		local humanoid = player.Character.Humanoid
		local swordConfig = sword.Config:GetAttributes()
		
		-- Remake the force moving script
		if humanoid and rootPart then
			local Attachment = rootPart:FindFirstChild("PartAttachment")
			local initialSpeed = 1
			local maxSpeed = 100  -- Adjust the speed as needed
			humanoid.WalkSpeed = 0 -- Preventing the player from moving

			task.wait(0.83)
			
			print(player, humanoid, Attachment, rootPart, initialSpeed, maxSpeed)
			ClientAbility:FireClient(player, humanoid, Attachment, rootPart, initialSpeed, maxSpeed)
			
			task.wait(2)
			
			humanoid.WalkSpeed = 16
			
		end
		
	end,

Client Script

local Events = ReplicatedStorage.Events

local ClientAbility = Events:FindFirstChild("ClientAbility")

local function clientAbility(humanoid, Attachment, rootPart, initialSpeed, maxSpeed)
	local velocity = Instance.new("LinearVelocity", Attachment)
	local lookVector = rootPart.CFrame.lookVector
	velocity.MaxAxesForce = Vector3.new(math.huge, 0, math.huge) 
	velocity.VectorVelocity = lookVector * initialSpeed -- change 100 with how fast you want the projectile to go
	velocity.Attachment0 = Attachment
	Attachment.WorldPosition = rootPart.AssemblyCenterOfMass
	humanoid.PlatformStand = false
	
	for speed = initialSpeed, maxSpeed, 5 do
		task.wait(0.01)
		velocity.VectorVelocity = lookVector * speed
	end

	-- Duration of the thrusting
	task.wait(0.35)

	-- Clean up after a short duration (adjust as needed)
	velocity:Destroy()
end

ClientAbility.OnClientEvent:Connect(clientAbility)

Hello! I would highly suggest using :ApplyImpulse for short bursts of movement. Here is the API BasePart | Documentation - Roblox Creator Hub
Here is an example piece of code

local force = lookVector * 1000 -- 1000 is not velocity, it is the pushing force. It must be big enough to move your object, so change to your liking
part:ApplyImpulse(force) -- Replace part with HumanodRootPart or any part, mesh part, union, etc. 

This code will push the part in the direction of the lookVector. This is an instant force, not no delay after applying. Note it will not have a constant speed, because it is just a force. Also, it will move the part slightly different distances, depending on the friction of the surface, gravity and any other forces currently acting on it. ApplyImpulse is fantastic for knockback, speed boosts, jumps, abilities, and more! The API contains more information, it is a great resource.

I hope this helps you!

It’s really good and way more stable than using a Linear Velocity, although it is more limited in the length it thrusts

by the way is there any setting associated with applyimpulse or is it just the force?

how do i make so that the distance it travels is equal for all characters and surfaces

Hey hey!

  1. You just have to increase the force. I’ve used it to fling players thousands of studs. It will move things at higher speeds and go farther. You could try adding a little Y force, that will also help move it farther.
  2. Just force. It’s automatically applied to the center of mass of the part.
  3. You could attempt to make it equal by calculating the mass of the character and adjusting the force based on that. But that; 's a bunch of unneeded work. Keeping it as it currently is may be better for your game. It would let players discover how to maximize their ability and increase the skill cap. That is my personal opinion, feel free to tweak it as wanted.

Also, if that is the solution to your problem, please mark it so others can also benefit from it :grinning:

1 Like

I’ve figured out 1 and 2 but for 3, not being able to fully control the distance of the thrust as a dev might make it harder to balance it (which might allow for it to become broken OP for PvP on some maps), although it could diversify the gameplay more with less work needed

Since ApplyImpulse moves parts depending on the surface’s friction, I’ve figured out a way to check the friction of the part the player is standing on so perhaps I could tone down the distance variation with that, perhaps?

I could control what materials can be used on maps, but that’ll be hard work and would limit the game in a way

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