Rotation causes weird movement bug

Hello everyone! I am currently making a traditional 2.5D Fighting Game and is struggling with some issues, the one I am writing about however is the most dominant one.

Context:

So, like in any fighting game I have the player’s constantly looking at each other, no matter what side of the arena they are in.

Source Code:

-- Constant Variables

local Player: Player = game.Players.LocalPlayer
local Character: Model = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild('Humanoid')
local HumanoidRootPart: Part = Character:WaitForChild('HumanoidRootPart')

-- Requires

local RunService = game:GetService("RunService")
local PlayerService = game:GetService("Players")

-- Prerequisites
Humanoid.AutoRotate = false
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)

repeat wait() until #PlayerService:GetPlayers() >= 2 


-- Runtime Variables

local ePlayer: Player

for _, players in pairs(PlayerService:GetPlayers()) do
	
	if players.Name ~= Player.Name then
		ePlayer = players
	end
	
end

local eCharacter: Model = ePlayer.Character or ePlayer.CharacterAdded:Wait()
local eHumanoidRootPart: Part = eCharacter:WaitForChild('HumanoidRootPart')

-- Main Code Execution

local function LookAtOppositePlayer()
	
	local TargetPos = eHumanoidRootPart.Position
	local Direction = (TargetPos - HumanoidRootPart.Position).Unit
	local Angle = math.atan2(Direction.X, Direction.Z)
	
	Angle += math.pi
	
	HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.Position) * CFrame.Angles(0, Angle, 0)
	
end

RunService:BindToRenderStep("LookAtOppositePlayer", 1, LookAtOppositePlayer)

Issue:

The Issue is that when jumping above a player’s head, the other player can run through the empty space made by the jump

[Context Image]:

(Continuation of sentence before Context Image): When a player does run through that empty space, both players are locked in a feedback loop of always going backwards as shown in this demonstration:

Other Information:

You can get out of this by pressing jump, but I’d rather avoid this problem entirely.

Conclusion:

If anyone can help with this issue that’ll be amazing! Any help is appreciated!

2 Likes

Just off the top of my head, could try using CFrame.lookAt(playerPosition, enemyPosition)

You’ll have to make the Y value of the enemyPosition’s Vector3 equal to the playerPosition’s Y value, or else you’ll have them floating and rotating to look up in the air and all that, lol

Sorry, I’m having trouble visualizing that, can you explain further?

It’s simple, like

PlayerCFrame = CFrame.lookAt(playerPosition, Vector3.new(enemyPosition.X, playerPosition.Y, enemyPosition.Z))

The Vector3 is the enemy’s X and Z values. If you have the player look at the Y value too, they’ll turn sideways to look up and down instead of just forward toward the enemy lol

It turned out like this, do you need more information?

Try defining the HumanoidRootParts inside the function, them being outside of it could register as them being at (0,0,0), which is where all players spawn without a spawn point.

It could also just be the extra math you have. Maybe remove everything except what I showed you and try again.

Still the exact same :pensive:

Code now:

-- Constant Variables

local Player: Player = game.Players.LocalPlayer
local Character: Model = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild('Humanoid')

-- Requires

local RunService = game:GetService("RunService")
local PlayerService = game:GetService("Players")

-- Prerequisites
Humanoid.AutoRotate = false
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)

repeat wait() until #PlayerService:GetPlayers() >= 2 


-- Runtime Variables

local ePlayer: Player

for _, players in pairs(PlayerService:GetPlayers()) do
	
	if players.Name ~= Player.Name then
		ePlayer = players
	end
	
end

local eCharacter: Model = ePlayer.Character or ePlayer.CharacterAdded:Wait()

-- Main Code Execution

local function LookAtOppositePlayer()
	--[[
	local TargetPos = eHumanoidRootPart.Position
	local Direction = (TargetPos - HumanoidRootPart.Position).Unit
	local Angle = math.atan2(Direction.X, Direction.Z)
	
	Angle += math.pi
	]]--
	local eHumanoidRootPart: Part = eCharacter:WaitForChild('HumanoidRootPart')
	local HumanoidRootPart: Part = Character:WaitForChild('HumanoidRootPart')
	HumanoidRootPart.CFrame = CFrame.lookAt(HumanoidRootPart.Position, Vector3.new(eHumanoidRootPart.Position.X, HumanoidRootPart.Position.Y, eHumanoidRootPart.Position.X))
	
end

RunService:BindToRenderStep("LookAtOppositePlayer", 1, LookAtOppositePlayer)

Oof. The NPCs I make use CFrame.lookAt to look at the nearest player and they dont do that, not sure what’s happening, sorry lmao

It’s alright man, thanks for trying!