Monster wave staying in circle

Alrigth so I have a problem with monsters so basically the monsters rushes on the player but after a certain point the player can decide to outsmart the wave by trying to force them to stay in circle and it’s very annoying.

Here’s the code of the monster

local RunService = game:GetService("RunService")

local chasingPart = script.Parent:WaitForChild("HumanoidRootPart")
local moveSpeed = 10
local player = nil
local spawnRadius = 50
local enemyFolder = workspace:FindFirstChild("Enemies") or workspace
local damageAmount = 10
local damageCooldown = 0.5
local lastHitTime = 0
local separationDistance = 10
local currentVelocity = Vector3.zero

local uniqueOffset = (tonumber(string.sub(tostring(script.Parent.Name), -3)) or math.random()) * 0.2

local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(100000, 100000, 100000)  
bodyGyro.D = 1000  
bodyGyro.P = 10000 
bodyGyro.CFrame = chasingPart.CFrame  
bodyGyro.Parent = chasingPart  

function getPlayer()
	for _, p in pairs(game.Players:GetPlayers()) do
		if p.Character and p.Character:FindFirstChild("HumanoidRootPart") then
			return p.Character
		end
	end
	return nil
end

function randomSpawnPosition(playerPosition)
	local angle = math.random() * math.pi * 2
	local offset = Vector3.new(math.cos(angle), 0, math.sin(angle)) * spawnRadius
	local spawnPos = playerPosition + offset

	local rayOrigin = spawnPos + Vector3.new(0, 10, 0)
	local rayDirection = Vector3.new(0, -20, 0)
	local result = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())

	if result then
		spawnPos = result.Position + Vector3.new(0, 2, 0)
	end

	return spawnPos
end

function moveToPlayer()
	if not player then return end

	local basePosition = player.HumanoidRootPart.Position
	local angle = tick() * 0.2 + uniqueOffset
	local radius = 2
	local offset = Vector3.new(math.cos(angle), 0, math.sin(angle)) * radius
	local targetPosition = basePosition + offset
	local desiredDirection = (targetPosition - chasingPart.Position).Unit

	local separation = Vector3.zero
	for _, otherEnemy in pairs(enemyFolder:GetChildren()) do
		if otherEnemy ~= script.Parent and otherEnemy:FindFirstChild("HumanoidRootPart") then
			local otherPart = otherEnemy.HumanoidRootPart
			local distance = (chasingPart.Position - otherPart.Position).Magnitude
			if distance < separationDistance and distance > 0 then
				local pushDir = (chasingPart.Position - otherPart.Position).Unit
				local strength = (separationDistance - distance) / separationDistance
				separation += pushDir * strength
			end
		end
	end

	local finalDirection = (desiredDirection + separation).Unit
	local deltaTime = RunService.Heartbeat:Wait()
	local damping = 0.15
	currentVelocity = currentVelocity:Lerp(finalDirection * moveSpeed, damping)

	chasingPart.Position += currentVelocity * deltaTime

	bodyGyro.CFrame = CFrame.new(chasingPart.Position, chasingPart.Position + finalDirection)
end

function onTouch(otherPart)
	local char = otherPart:FindFirstAncestorOfClass("Model")
	if char and char:FindFirstChild("Humanoid") and char:FindFirstChild("HumanoidRootPart") then
		if char == player then
			local currentTime = tick()
			if currentTime - lastHitTime >= damageCooldown then
				lastHitTime = currentTime
				char.Humanoid:TakeDamage(damageAmount)
			end
		end
	end
end

-- Spawn initial
function spawnAtRandomPosition()
	local char = getPlayer()
	if char then
		player = char
		chasingPart.Position = randomSpawnPosition(char.HumanoidRootPart.Position)
	end
end

spawnAtRandomPosition()

-- Boucle de suivi
RunService.Heartbeat:Connect(function()
	local char = getPlayer()
	if char then
		player = char
		moveToPlayer()
	end
end)

-- Dégâts
chasingPart.Touched:Connect(onTouch)

Here’s what the effect gives in video

1 Like

Ok so basically the monster has to be varied and come from any side which is not the case at the moment

It looks like if you walk in a straight line the same thing happens. Try increasing the monster’s speed so it’s slightly faster than the player’s speed.

Right now I’m working on making the movement smooth to create a feeling that the monster is jumping