Roblox Body Velocity Not Updating Position?

I’m trying to make a rush kind of move where you rush foward and if you hit somebody than you grab them. My issue is that when I apply a body velocity to a character’s HumanoidRootPart and then stop it by anchoring the player and deleting the Body Velocity. For some reason the server has a different position for the player than their actual position. But I can’t think of why this would be a thing when none of it is client sided. This becomes a problem because I can’t figure out how to get the player’s actual position.

Simplified Version Of The Script i’m using. (In serverscriptservice being called by a remote function)

local function Rush(Real) -- Real is the Player's Character
	local YourHumanoid = Real.Humanoid
	local YourHRP = Real.HumanoidRootPart
	local Track = YourHumanoid:LoadAnimation(game.ReplicatedStorage.Animations.UniversalAnimations.Rush)
	Track:Play()
	local Sound = game.ReplicatedStorage.Audio.WhatType:Clone() -- Audio For Rush
	Sound.Parent = Real.HumanoidRootPart
	Sound:Play()
	DS:AddItem(Sound,Sound.TimeLength)
	YourHumanoid.WalkSpeed = 0
	YourHumanoid.JumpPower = 0
	
	local IF = Instance.new("BoolValue") -- IFrames
	IF.Name = "IF" 
	IF.Parent = Real
	
	local YV = Instance.new("BodyVelocity") -- Your Velocity
	YV.MaxForce = Vector3.new(math.huge,0,math.huge)
	YV.Velocity = Real.HumanoidRootPart.CFrame.LookVector * 50
	YV.Parent = Real.HumanoidRootPart
	DS:AddItem(YV,0.5)

	-- HitBoxCreation
	
	local Hitbox = Instance.new('Part')
	Hitbox.Size = Vector3.new(5,6,5)
	Hitbox.BrickColor = BrickColor.new("Really red")
	Hitbox.Material = Enum.Material.SmoothPlastic
	Hitbox.Name = "HitBox"
	Hitbox.CanCollide = false
	Hitbox.Anchored = false
	Hitbox.Transparency = 0.5
	Hitbox.CFrame = Real.HumanoidRootPart.CFrame * CFrame.new(0,0,-3)
	Hitbox.Massless = true
	local Weld = Instance.new("WeldConstraint")
	Weld.Part0 = Real.HumanoidRootPart
	Weld.Part1 = Hitbox
	Weld.Parent = Real
	Hitbox.Parent = YourHumanoid
	DS:AddItem(Hitbox,0.5)
	DS:AddItem(Weld,0.5)
	
	-- HitBoxCreation
	
	local TargetFound = false -- If a target was found
	local Target = "None"
	local Over = false -- If move is over
	
	local StunValue = Instance.new("BoolValue")  -- A stun value to stop the player from being able to do any moves or punches
	StunValue.Name = "StunValue"
	StunValue.Parent = Real
	DS:AddItem(StunValue,0.5)
	
	Hitbox.Touched:Connect(function(hit)
		if TargetFound == false and Over == false then
			if hit.Parent then
				if hit.Parent:FindFirstChild("Humanoid") then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					local HRP = hit.Parent:FindFirstChild("HumanoidRootPart")
					if Humanoid.Health ~= 0 and not hit.Parent:FindFirstChild("IF") and Humanoid ~= YourHumanoid then -- IFrames
						local real = hit.Parent -- Player hit
						if not real:FindFirstChild("BlockValue") then -- Checking if their blocking
							TargetFound = true
							
							local Amount = 1 -- Stunning the player hit
							game.ReplicatedStorage.Stun:FireAllClients(real,Amount) -- Stunning the player hit
							
							YV:Destroy() -- Destroying the velocity

							Target = real -- Setting the target to the player hit
							
							print("Rush Hit")
							
							Track:Stop()
							
							local Part = Instance.new("Part")
							Part.CFrame = Real.HumanoidRootPart.CFrame -- For testing purposes i'm putting the part at the humanoidrootpart
							Part.Anchored = true
							Part.CanCollide = false
							Part.Parent = Real
				
							IF:Destroy() -- Getting rid of the iframes
					end
				end
				end
			end
		end
	end)
end

What I get when I do it:

Also there is no bug reports or anything in ouput.

1 Like

I forgot to add that DS is Debris Service.

My bad. First time using the devforum. Thanks for the heads up.

Do not weld the hitbox part to the character and do not use the Touched event for this. Instead try using spatial queries or the RotatedRegion3 module to get parts that are in a certain place without having to make a part.

Explaining the issue, the hitbox’s NetworkOwnership is of the client due to the weld, and the Touched event is not a fully server sided thing. So the hitbox actually only hits in the client perspective, not the server; but due to Touched respecting the client’s view, it still fires the event, since the touched information comes from the client. This means that the hitbox hits the enemy before it actually should for the server. When in your view you are close to the enemy, in the server you and the hitbox haven’t even got close to the enemy. That’s why you shouldn’t use Touched for hitboxes.

Go search about server and client differences and how ping influences it. The higher your ping, the less synchronized your client is with the server; therefore, the position of the character is one to the client and another the server.

I know how to use spatial quarries but how would I go about not welding the hitbox to the player? I can’t think of any other way to keep it with the player.

Basically use a Heartbeat loop for the hitbox. For example, I use the RotatedRegion3 which can get parts in a place without needing to use a part as a reference of size and position. With that, in a Heartbeat loop I would just do:

local hitboxSize = Vector3.new(6, 6, 6)

-- in the loop:
rotatedRegion3.new(rootPart.CFrame * CFrame.new(0, 0, -hitboxSize.Z / 2), hitboxSize)

And then just do loop:Disconnect() to stop it.

This way it gets parts that are in front of the character with the size of 6 studs for each axis and it’s only where the character is for the server.

If you still wanna use a part, just constantly update its position in a Heartbeat loop too, using workspace: GetPartsInPart() to get the parts inside of it, and don’t forget to enable Anchored and disable CanCollide, CanTouch.

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