간단한 적의 AI를 만들어 봤다.

적 AI

너무 단순해서 순서도를 그릴 가치도 없음. ㅋ

 

공격은 애니메이션을 찾기 귀찮기 때문에 크기를 키웠다가 줄이는 것으로 표현했다.

일단 동작은 잘 되는데 로블록스는 멀티가 기본인 거 같아서 로컬에서 반복을 돌리는거보다 서버의 틱에 맞춰서 돌아가도록 해봤다.

 

이제 적과 플레이어의 상호작용을 만들면 얼추 플레이는 가능할 것 같다.

local enemy = script.Parent
local speed = 10
local attackRange = 10 -- 공격 범위
local attackTime = 0.25 -- 공격 애니메이션 시간
local attackCooldown = 1 -- 공격 쿨다운 시간
local isAttacking = false -- 공격 중 여부
local lastAttackTime = 0 

local RunService = game:GetService("RunService")

local bodyVelocity = Instance.new("BodyVelocity", enemy)
bodyVelocity.MaxForce = Vector3.new(4000, 4000, 4000)
bodyVelocity.Parent = enemy

local function GetClosestPlayer()
	local closestPlayer = nil
	local shortestDistance = math.huge

	for _, player in ipairs(game.Players:GetPlayers()) do
		local character = player.Character
		if character and character:FindFirstChild("HumanoidRootPart") then
			local distance = (enemy.Position - character.HumanoidRootPart.Position).Magnitude
			if distance < shortestDistance then
				closestPlayer = player
				shortestDistance = distance
			end
		end
	end
	return closestPlayer, shortestDistance
end

-- 공격 동작 수행
local function PerformAttack()
	if isAttacking then return end -- 이미 공격 중이면 무시
	if os.clock() - lastAttackTime < attackCooldown then return end -- 쿨다운 중이면 무시

	isAttacking = true
	lastAttackTime = os.clock() -- 현재 시간을 기록

	-- 공격애니메이션(크기 잠깐 키우기)
	local originalSize = enemy.Size
	enemy.Size = originalSize * 1.2 

	
	task.delay(attackTime, function()
		enemy.Size = originalSize -- 크기 복구
		isAttacking = false -- 공격 종료
	end)
end

-- 가장 가까운 플레이어를 향해 이동
local function moveTowardsClosestPlayer(deltaTime)
	if isAttacking then
		bodyVelocity.Velocity = Vector3.zero
		return
	end

	local targetPlayer, distance = GetClosestPlayer()
	if not targetPlayer then
		bodyVelocity.Velocity = Vector3.zero
		return
	end

	local playerPosition = targetPlayer.Character.HumanoidRootPart.Position
	local enemyPosition = enemy.Position

	if distance <= attackRange then
		PerformAttack()
	else
		enemy.CFrame = CFrame.new(enemyPosition, playerPosition)
		local direction = enemy.CFrame.LookVector
		bodyVelocity.Velocity = direction * speed
	end
end


local lastUpdate = 0
RunService.Stepped:Connect(function(deltaTime)
	lastUpdate += deltaTime
	if lastUpdate < 0.1 then return end -- 0.1초 간격으로 업데이트
	lastUpdate = 0

	moveTowardsClosestPlayer(deltaTime)
end)

 

테스트영상

+ Recent posts