Moving the character's pivot forward by 5 studs only moves in one direction, even if you turn the character

Hello!

I came across a bug in my code that I can’t seem to fix, no matter what I do. Whenever I move the character’s pivot forward by 5 studs, it only moves in one direction even if you turn the character. I want it so that if i turn my character while its teleporting me, it’ll go and teleport in that direction that I turned the character. I tried lookvector, and plenty of other alternatives but I still can’t get it to work. Heres what I mean: a bug - YouTube (the file size was over 10mb so i uploaded it to youtube)

Also, heres the ability’s function: (I also tried repeat instead of the while loop which didn’t work either)

    ability = function()
		if CheckIfAlive() then
			local s, r = pcall(function()
				sound:Play()
				while sound.IsPlaying do
					char:PivotTo(char:GetPivot() * CFrame.new(0, 0, -5))
					task.wait(.125)
				end
			end)
			if not s and r then
				print(r)
			end
		end
	end;
1 Like

try replacing * CFrame.new(0, 0, -5) with + char.CFrame.LookVector*5

1 Like

As I said, I already tried lookvector.

cant you use CFrame?
char.HumanoidRootPart.CFrame += char.HumanoidRootPart.CFrame.LookVector*5

I tried CFrame, also that doesn’t work.

Check out CFrame:ToWorldSpace(), it’ll let you edit the CFrame relative to rotation, so no matter the angle it’ll always move forward.

An example would look like

Part.CFrame = Part.CFrame:ToWorldSpace(CFrame.new(0, 0, -5))

Yeah, that didn’t work. I have a feeling its a problem with the loop but I can’t figure out what part of the loop doesn’t work.

What did your new code look like? The loop itself has nothing to do with the position, its gonna be this line.

    ability = function()
		if CheckIfAlive() then
			local s, r = pcall(function()
				sound:Play()
				while sound.IsPlaying do
					torso.CFrame = torso.CFrame:ToWorldSpace(CFrame.new(0, 0, -5))
					task.wait(.125)
				end
			end)
			if not s and r then
				print(r)
			end
		end
	end;

You’re close, but you need to set the entire models CFrame, not just the Torso. Moving only 1 part of the character won’t do anything.

Character:SetPrimaryPartCFrame(Character.PrimaryPart.CFrame:ToWorldSpace(CFrame.new(0, 0, -5)))

didn’t work, also i wanna note that this is a tool

Pivot acts really weirdly on R6 rigs, at least for me. I recommend to set the HumanoidRootPart CFrame instead if you’re using R6. On R15 it works perfectly fine though.

I tried it as you can see above. This seems so simple yet nobody can solve it…

Im not sure if this can help, but in a noclip script i made I used humanoidRootPart.CFrame = CFrame.new(position, position+lookvector)
Hope this can help you.

Edit: Just tried this and it works:

local char = game:GetService("Players").LocalPlayer.Character
local hrp = char:WaitForChild("HumanoidRootPart")

local speed = 10

while true do
	task.wait(0.5)
	hrp.CFrame = CFrame.new(hrp.Position, hrp.Position+ hrp.CFrame.LookVector) * CFrame.new(Vector3.new(0,0,-1) * speed)
end

Didn’t work for me… Am I doing something wrong?

I don’t think you’re doing anything wrong. Are you getting any errors or is it just not moving at all?

No, look at this: a bug - YouTube
When I try to turn the character for it to teleport me in another direction, it doesn’t go in that direction, it keeps going in the same direction.

Heres the full code:

local attackFunc
tool = script.Parent
ability = tool:FindFirstChild("Ability")
rs = game:GetService("ReplicatedStorage")
debris = game:GetService("Debris")
handle = tool.Handle
sound = handle.Sound
plrs = game:GetService("Players")
preId = nil
abilityDb = false -- true
db = false
plr = nil
char = nil
hum = nil
torso = nil

sounds = {
	hit1 = "rbxassetid://7441132956";
	hit2 = "rbxassetid://7441133345";
	hit3 = "rbxassetid://7441133912";
	swing1 = "rbxassetid://8838460866";
	swing2 = "rbxassetid://8838463024";
	swing3 = "rbxassetid://8838463387";
	crush1 = "rbxassetid://7441130752";
	crush2 = "rbxassetid://7441129853";
	crush3 = "rbxassetid://7441129469";
}

function CheckIfAlive()
	local Player = plr
	local Character = char
	local Humanoid = hum
	local Torso = torso
	return (((Player and Player.Parent and Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Torso and Torso.Parent) and true) or false)
end

config = {
	damage = 20;
	toolDelay = 1;
	abilityDelay = 25;
	ability = function()
		if CheckIfAlive() then
			local s, r = pcall(function()
				sound:Play()
				while sound.IsPlaying do
					torso.CFrame = CFrame.new(torso.Position, torso.Position+ torso.CFrame.LookVector) * CFrame.new(Vector3.new(0,0,-1) * 5)
					task.wait(.125)
				end
			end)
			if not s and r then
				print(r)
			end
		end
	end;
}

--[[
local abilityWait = coroutine.wrap(function()
	task.wait(config.abilityDelay)
	abilityDb = false
end)
abilityWait() ]]

local randomId = math.random(100000, 999999)

local idLoop = coroutine.wrap(function()
	while task.wait(1) do
		local randomGUID = game:GetService("HttpService"):GenerateGUID()
		tool:SetAttribute("ABILITY_ID_"..tostring(randomId), randomGUID)
		local preSet = coroutine.wrap(function()
			task.wait()
			preId = randomGUID
		end)
		preSet()
	end
end)
idLoop()

tool.Equipped:Connect(function()
	char = tool.Parent
	plr = plrs:GetPlayerFromCharacter(char)
	hum = char:FindFirstChildOfClass("Humanoid")
	torso = char:FindFirstChild("Torso") or char:FindFirstChild("HumanoidRootPart")
	local function abilityButton1()
		local plrGui = plr:WaitForChild("PlayerGui")
		local ability = plrGui:WaitForChild("Ability")
		ability.Enabled = true
	end
	abilityButton1()
end)

tool.Unequipped:Connect(function()
	local function abilityButton2()
		local plrGui = plr:WaitForChild("PlayerGui")
		local ability = plrGui:WaitForChild("Ability")
		ability.Enabled = false
	end
	abilityButton2()
end)

tool.Activated:Connect(function()
	if not db and CheckIfAlive() then
		db = true
		local Anim = Instance.new("StringValue")
		Anim.Name = "toolanim"
		Anim.Value = "Slash"
		Anim.Parent = tool
		local randomSwingSound = math.random(1, 3)
		if randomSwingSound == 1 then
			sound.SoundId = sounds.swing1
		elseif randomSwingSound == 2 then
			sound.SoundId = sounds.swing2
		elseif randomSwingSound == 3 then
			sound.SoundId = sounds.swing3
		end
		sound:Play()
		local plrsHit = {}
		attackFunc = handle.Touched:Connect(function(part)
			local s, r = pcall(function()
				if part.Parent and part.Parent:IsA("Model") and part.Parent:FindFirstChildOfClass("Humanoid") and #plrsHit <= 0 then
					local otherChar = part.Parent
					local otherPlr = plrs:GetPlayerFromCharacter(otherChar)
					if not otherPlr or otherPlr.UserId ~= plr.UserId then
						local otherHum = otherChar:FindFirstChild("Humanoid")
						if otherHum.Health > 0 then
							local otherHrp = otherChar.PrimaryPart
							if (otherHum.Health - config.damage) > 0 then
								local randomHitSound = math.random(1, 3)
								if randomHitSound == 1 then
									sound.SoundId = sounds.hit1
								elseif randomHitSound == 2 then
									sound.SoundId = sounds.hit2
								elseif randomHitSound == 3 then
									sound.SoundId = sounds.hit3
								end
							elseif (otherHum.Health - config.damage) <= 0 then
								plr.leaderstats.Kills.Value += 1
								local randomCrushSound = math.random(1, 3)
								if randomCrushSound == 1 then
									sound.SoundId = sounds.crush1
								elseif randomCrushSound == 2 then
									sound.SoundId = sounds.crush2
								elseif randomCrushSound == 3 then
									sound.SoundId = sounds.crush3
								end
							end
							local soundClone = sound:Clone()
							soundClone.Parent = otherHrp
							soundClone:Play()
							local soundCoro = coroutine.wrap(function()
								soundClone.Ended:Wait()
								soundClone:Destroy()
							end)
							soundCoro()
							plrsHit[#plrsHit+1] = otherChar.Name
							plr.leaderstats.Hits.Value += 1
							otherHum.Health -= config.damage
						end
					end
				end
			end)
		end)
		task.wait(config.toolDelay)
		attackFunc:Disconnect()
		table.clear(plrsHit)
		if Anim then 
			Anim:Destroy() 
		end
		db = false
	end
end)

if ability then
	ability.OnServerEvent:Connect(function(plr, id)
		if tostring(id) == tostring(tool:GetAttribute("ABILITY_ID_"..randomId)) or tostring(id) == tostring(preId) then
			if not abilityDb then
				abilityDb = true
				local abilityCoro = coroutine.wrap(function()
					config.ability()
				end)
				abilityCoro()
				task.wait(config.abilityDelay)
				abilityDb = false
			end
		end
	end)
end

tool.GetIfReady.OnServerInvoke = function()
	if abilityDb then
		return false
	else
		return true
	end
end

Is this a localscript or a serverscript? Because I noticed that in the video you’re turning your camera with shiftlock, which the server might not detect (idk)

Edit: I tried it my code on a serverscript and i still worked so idk.

You’re probably right, its a serverscript. How do I fix this? Can I perhaps use a RemoteFunction to get the player’s orientation on the client and transfer it to the server?