Currently, I am rotating bots to face and shoot at the player by setting the bots PrimaryPart CFrame and using CFrame.lookAt. While this works, it messes with the animations of the bot. I recently found a post that used a BodyGryo, however with that being depicted, how would I do this?
use AlignOrientation instead
https://developer.roblox.com/en-us/api-reference/class/AlignOrientation
How do I make it less finicky? They turn (kinda), but its more like a flip left or right, but the bot doesn’t really look at the player…
https://gyazo.com/3460b6de7811a64d214906a003cd5623
its hard to tell there kinda dark and stuff but seems the bot ai maybe trying to rotate the humanoid as you are using AlignO
you could turn off auto rotate on the humoid and then in the bot ai just set the alignO when the bot goes toward a new location
Are you editing the rotation via a LocalScript or via the Server? I wouldn’t recommend the Server if that’s what you’re doing because if you do it via a LocalScript, it shouldn’t interfere with the animations at all and it’ll also make it less laggy in general if you’re planning to make lots of bots look at players at once
I’d use a RemoteEvent and then something like this to make it run every frame and be as smooth as possible:
local RunService = game:GetService("RunService")
RunService.RenderStepped:Connect(function()
bot:SetPrimaryPartCFrame(bot.Position, player.PrimaryPart.CFrame)
end)
I wasn’t aware that doing it on the client wouldn’t interrupt the animations. Sounds promising, I will try that when I hop back on later tonight.
Client Only:
local RS = game:GetService("RunService")
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local vecFlat = Vector3.new(1,0,1) -- used to remove y titling and sliding
RS.RenderStepped:Connect(function()
bot:SetPrimaryPartCFrame(bot.PrimaryPart.Position, char.PrimaryPart.Position * vecFlat)
end)
The above code is for a local script, if you wanted to make it work on the server you would have to replace RS.RenderStepped with RS.Heartbeat. You would also have to use a different method for finding the character.
With that said, I highly recommend you use a server script and allocate the network ownership to the nearest player.
Server (Preferred):
local PLR = game:GetService("Players")
local RS = game:GetService("RunService")
local function FindNearestPlayer(bot)
local nearestPlr, nearestDist
for _, plr in pairs(PLR:GetPlayers()) -- try using ipairs instead for efficiency
local char = plr.Character
local dist = plr:DistanceFromCharacter(bot.PrimaryPart.Position)
if char and dist then
if dist < nearestDist then
nearestPlr = plr
nearestDist = dist
end
end
end
return nearestPlr, nearestDist
end
local vecFlat = Vector3.new(1,0,1)
RS.Heartbeat:Connect(function()
for _, bot in pairs(bots) do
local plr, dist = FindNearestPlayer(bot)
local char = plr.Character
if char and char.Humanoid.Health > 0 then
bot:SetNetworkOwner(plr)
bot:SetPrimaryPartCFrame(bot.PrimaryPart.Position, char.PrimaryPart.Position * vecFlat)
end
end
end)
I’ve included a simple function that finds the nearest player to the bot based on magnitude. Every frame the code will update the nearest player for each bot and assign network ownership of that bot to the nearest player.
If you’re using custom animations I would advise you to use hum.Animator:LoadAnimation()
instead of hum:LoadAnimation()
. The animator is better built to handle animation tasks and replicates cleanly.
Hope this helps!
Alright so it mostly works, however setting the CFrame is causing the bots to run in place while they are shooting (which is where the CFrame is being set).
https://gyazo.com/b735fe1979cd8aee1124fed4b1a567c6
It’s been a few days so you might have forgotten about this post, so this reply is a reminder.
Have you managed to resolve this?
I’m trying to find a solution to this but BodyGyro seems like the only actual solution, since AlignPosition and CFrame are just not it.