AlignPosition & AlignOrientation for Boss Battle AI

I’m making a boss NPC for my boss battle arena that should stay in one place and lock onto the player during most of the fight. Since BodyGyros and BodyPositions are deprecated, I turned to using AlignPositions and AlignOrientations to hopefully achieve the result that I want. My issue currently is that nothing is being changed when the player tries moving around for AlignOrientation and the same with AlignPosition when I try moving the boss manually. I don’t know if it has to do with my code, my choice of using AlignPosition & AlignOrientation, or potentially external reasons like part anchoring. I am unsure if my implementation is accurate or not.

(This video shown is done locally, but doing it on the server does the same thing)

Boss AI Script:

--[[ OUTLINE:
1. as soon as this script is enabled:
	-give the boss a health bar and send it to the client
	(done)->>enable the animation script for the boss and loop the init animation
	
2. Some bosses will have a weak point phase and others won't so make variables for that
3. Make a loop that constantly locks onto the player until a move is being performed
4. The first main while loop will be the boss throwing punches at the player until he stops
]]

print('AI script enabled')

local RunService = game:GetService("RunService")

local RS = game:GetService("ReplicatedStorage")
local ShowBossHealth = RS:WaitForChild("ShowBossHealth")

local bossChar = script.Parent
local bossHum = bossChar:WaitForChild("Humanoid")
local bossHRP = bossChar:WaitForChild("HumanoidRootPart")

local player = game.Players:GetPlayers()[1]

local bossMap = bossChar.Parent
local centerLock = bossMap:WaitForChild("Assets"):WaitForChild("CenterLock")

local HAS_WEAK_SPOT = false
local PHASE_1_PUNCHES = math.random(3,4)
local PHASE_1_PUNCH_TIME = 5

local phase1Active = true
local phase1ChargingPunch = false
local phase2Active = false

--Attach the boss in the center using AlignPosition
local alignPosition = Instance.new("AlignPosition")
alignPosition.Parent = bossHRP
alignPosition.ApplyAtCenterOfMass = true
local posAttach0 = Instance.new("Attachment", bossHRP)
posAttach0.Name = "PosAttachment0"

local posAttach1 = Instance.new("Attachment", centerLock)
posAttach1.Name = "PosAttachment1"

alignPosition.Attachment0 = posAttach0
alignPosition.Attachment1 = posAttach1


--Create an alignOrientation so that the boss can constantly lock onto the player
local alignOrientation = Instance.new("AlignOrientation")
alignOrientation.Parent = bossHRP

local alignAttach0 = Instance.new("Attachment", bossHRP)
alignAttach0.Name = "AlignAttachment0"

local alignAttach1 = Instance.new("Attachment", player.Character.HumanoidRootPart)
alignAttach1.Name = "AlignAttachment1"

alignOrientation.Attachment0 = alignAttach0
alignOrientation.Attachment1 = alignAttach1
alignOrientation.Enabled = false

--give the boss a health bar for all players
ShowBossHealth:FireAllClients(bossChar, bossHum)


--Local Functions for phase 1
local function Phase1PunchCountdown(lockOnTime)
	print('activate phase1 punch countdown')
	
	while phase1ChargingPunch == false do
		wait(lockOnTime)
		phase1ChargingPunch = true
	end
end

-->> at this point, I don't really know what I'm doing with LockOntoPlayer
local function LockOntoPlayer()
	print('activate lock onto player')
	alignOrientation.Enabled = true
	--local connection = nil
	--connection = RunService.Heartbeat:Connect(function(step)
		--alignOrientation.Attachment0.Orientation = alignOrientation.Attachment1.Orientation
	--end)
	
	--local connection = nil
	
	--while phase1ChargingPunch == false do
		--lock onto player
		--wait()
		--alignOrientation.Attachment0.WorldCFrame = CFrame.new(bossHRP.Position, player.Character.HumanoidRootPart.Position)
		--[[connection = RunService.Heartbeat:Connect(function(step)
			wait(1)
			alignOrientation.Attachment0.Orientation = player.Character.HumanoidRootPart.Orientation
		end)]]
	--end
	--connection:Disconnect()
	repeat wait() until phase1ChargingPunch == true
	--connection:Disconnect()
	alignOrientation.Enabled = false
end

--Main loop for the 1st phase (which is locking onto the player and sometimes throwing punches)
print('activate main loop for boss')
while phase1Active do
	
	--constantly lock onto the player
	local lockOnTime = math.random(10, 15)
	coroutine.wrap(LockOntoPlayer)()
	
	coroutine.wrap(Phase1PunchCountdown)(lockOnTime)
	
	wait(999999) -- for testing
end
2 Likes

If you’re just trying to replace BodyPosition and BodyGyro, i.e. you want to just set the Position and CFrame (orientation) to some value, you should use the OneAttachment mode.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.