Hello dear Developers! I am here with an issue about my projectile.
My issue is that the NPC, misses the shot at the player, when the player does a quick turn before the NPC throws the ball, and it usually throws the ball on future position of a player, but it becomes inaccurate shot when the player does a quick turn back. NPC, also can miss the shot, when player just moves on a curved circle path on same position, forcing the projectile to go left/right direction which is the “future position of a player”.
I’ve tried to research about how can I make NPC’s reaction time better or how to make NPC check if player will do a quick turn.
Here is my script, how it works.
local npc = script.Parent
local animator = npc.Humanoid.Animator
local animation = animator.BALLTHROW
local loadAnim = animator:LoadAnimation(animation)
local isAnimPlay = false
local npcHum = npc:WaitForChild("Humanoid")
function EnemyNear()
local nearestPlr = nil
local shortestDistance = 125
for _, plr in pairs(game.Players:GetPlayers()) do
if plr.Character and plr.Character:FindFirstChild("HumanoidRootPart") then
local distance = (npc.HumanoidRootPart.Position - plr.Character.HumanoidRootPart.Position).magnitude
if distance <= shortestDistance then
nearestPlr = plr
shortestDistance = distance
end
end
end
return nearestPlr
end
function throw()
local EnemyPos = EnemyNear()
if EnemyPos then
local StartPos = npc.Torso.BallSpawn.Position
local Root = EnemyPos.Character.HumanoidRootPart
local t = 1.65
local EnemyPosNoY = Vector3.new(Root.Position.X, Root.Position.Y, Root.Position.Z)
local EnemyVelNoY = Vector3.new(Root.AssemblyLinearVelocity.X, 0, Root.AssemblyLinearVelocity.Z)
local HeightDiff = Root.Position.Y - StartPos.Y
local HeightFac = 1 + math.max(0, HeightDiff * 0.05)
local Thrown = EnemyPosNoY + (EnemyVelNoY / t) - StartPos
local BaseDuration = math.log(1.001 + Thrown.Magnitude * 0.006)
local Duration = BaseDuration * HeightFac
StartPos = npc.Torso.BallSpawn.Position + npc.Torso.BallSpawn.AssemblyLinearVelocity * Duration
Thrown = EnemyPosNoY + (EnemyVelNoY / t) - StartPos
local Multiplier = 1
local SuperBallclone = game.ServerStorage["BALL!"]:Clone()
local Force = Thrown / Duration + Vector3.new(0, workspace.Gravity * Duration * 0.5, 0)
SuperBallclone.Parent = workspace
SuperBallclone.Position = StartPos
SuperBallclone:ApplyImpulse(Force * SuperBallclone.AssemblyMass)
SuperBallclone:SetNetworkOwner(nil)
local onceHit = false
SuperBallclone.Touched:Connect(function(hit, hum)
local hitHum = hit.Parent:FindFirstChild("Humanoid")
if hitHum and hitHum ~= npcHum and not onceHit then
hitHum:TakeDamage(11.00707)
onceHit = true
task.wait(1)
onceHit = false
end
end)
end
end
while true do
if EnemyNear() then
loadAnim:Play()
end
wait(0.4700707)
throw()
wait(1)
end
Please do not touch the numbers inside of task.wait(), task.wait(0.4700707) is a reference number.
I recommend only checking the throw() function, as it is the function is responsible for projectile’s throw.
Note that I am not a good scripter, and sometimes I cannot some scripts that developers recommend me.
Overall I would like to see not that much of a complicated solution to this issue but rather a slightly understandable solution.