I’ve been trying to make an enemy that, when it sees you, it starts rushing towards you in a straight line and, after it crosses you, it’ll attack either to the left or right.
This is the code I use to check if the player is at the right or left of the enemy:
-- self is the Enemy's model
-- Target is the player's HumanoidRootPart
-- Slash is a function i made to slash
local Passed = false
self.PrimaryPart.CFrame = CFrame.lookAt(self.PrimaryPart.Position,Target.Position,Vector3.yAxis)
local Dir = self.PrimaryPart.CFrame.LookVector
self.Humanoid.WalkSpeed = self:GetAttribute("ChargeSpeed")
task.spawn(function()
while not Passed do
self.Humanoid:MoveTo(Dir*1000)
task.wait(4)
end
end)
local rbxc_CHECK_POS
rbxc_CHECK_POS = RunService.Heartbeat:Connect(function()
local relCFrame = self.PrimaryPart.CFrame:ToObjectSpace(Target.CFrame)
if relCFrame.Z < 0 or Passed then
-- Enemy has passed the player
Passed = true
rbxc_CHECK_POS:Disconnect()
if relCFrame.X > 0 then
Slash("Right")
else
Slash("Left")
end
end
end)
The problem is, the enemy istantly slashes to the right, even if the player is still in front. I have no idea what to do!
I think you should try welding a non-colliding and transparent part to the enemy’s HumanoidRootPart, then connect its Touched function and do what you need to do inside of it.
Do something like this:
then attach a script to the new part with this inside:
local Players = game.Players
local Sensor = script.Parent
Sensor.Touched:Connect(function(Hit)
if Players:GetPlayerFromCharacter(Hit.Parent) then -- Checks if the part collided is a player character child
-- your slash animation and code.
end
end)
I’ll use this as a temporary solution, but I won’t mark it as such yet to see if someone else responds. If I don’t find another way then I guess I’ll have to keep it.
The only problem I have with is that sometimes collisions are kinda janky, so I was trying something else.
Thanks anyways!
The problem is that there’s no way to know if a player passes by without collisions. The only other thing you can do is looping every player in the server and checking if their distance is less than the enemy’s range. But I strongly recommend to not do so as it is inefficient.
local enemy = workspace.Enemy
local target = workspace.Target
local horizontalDot = enemy.CFrame.RightVector:Dot(CFrame.new(target.Position,enemy.Position).LookVector)
local verticalDot = enemy.CFrame.LookVector:Dot(CFrame.new(target.Position,enemy.Position).LookVector)
local direction
if horizontalDot >= 0 then
direction = Vector2.new(-1,0)
else
direction = Vector2.new(1,0)
end
if verticalDot >= 0.5 then
direction = Vector2.new(0,1)
elseif verticalDot <= -0.5 then
direction = Vector2.new(0,-1)
end
print(direction.X,direction.Y)
Change the target and enemy, and it will return a vector2 of the relative location