I mainly have this issue:
it finds the player, continues to move, then gets punished for leaving the player, then wiggles out of the punish zone. how would I teach it to stay and stare at the player?
updated version of the script
local OpenML = require(game.ServerScriptService.OpenML)
local States = {'NearGround',"ProperlyOrientated", "TooHigh", "Target"}
local Actions = {
"Thrust",
"Propeller_X", "Propeller_Z",
}
local ActivationFunction = OpenML.ActivationFunctions.TanH
local learningRate = .2
local Drone = script.Parent.Torso
local Eye = script.Parent.Eye.HitBox
local NewAI = setmetatable(OpenML.Resources.MLP.new({ #States, 10, 10, 10, #Actions }, function()
return (math.random() * 2 - 1) * 1.5
end), { __index = OpenML.Algorithms.Propagator})
local DQL = OpenML.Algorithms.DQL.new()
DQL.OnForwardPropagation = function(state) return NewAI:ForwardPropagation(state, ActivationFunction) end
DQL.OnBackPropagation = function(activations, target) return NewAI:BackPropagation(activations, target, { ActivationFunction = ActivationFunction, LearningRate = learningRate }) end
function SimplifiyPrediction(Prediction)
if typeof(Prediction[1]) == "number" then
return Prediction
end
local NewPrediction = {}
for I, Slot in ipairs(Prediction) do
local Average = 0
for _, Number in ipairs(Slot) do
Average += Number
end
NewPrediction[I] = Average / #Slot
end
return NewPrediction
end
Eye.Touched:Connect(function()
end)
function NearGround()
local Raycast = workspace:Raycast(script.Parent.Torso.Position, Vector3.new(0, -5, 0))
if Raycast then
return 1
end
return 0
end
local function clampPrediction(prediction)
for i = 1, #prediction do
prediction[i] = math.clamp(prediction[i], -1, 1)
end
return prediction
end
function GetTarget()
local Eye = script.Parent.Eye.HitBox
local HasTarget = 0
for _, Part in Eye:GetTouchingParts() do
if Part.Name == "TargetPart" then
HasTarget = 1
end
end
local Target = workspace.Target
if HasTarget == 0 then
Target = nil
end
return HasTarget, Target
end
local FrontLeft = script.Parent.FrontLeftPropeller
local BackLeft = script.Parent.BackLeftPropeller
local FrontRight = script.Parent.FrontRightPropeller
local BackRight = script.Parent.BackRightPropeller
local Propellers = {
["FrontLeft"] = {
FrontLeft.Attachment.AlignOrientation,
FrontLeft.Attachment.AlignPosition,
},
["BackLeft"] = {
BackLeft.Attachment.AlignOrientation,
BackLeft.Attachment.AlignPosition,
},
["FrontRight"] = {
FrontRight.Attachment.AlignOrientation,
FrontRight.Attachment.AlignPosition,
},
["BackRight"] = {
BackRight.Attachment.AlignOrientation,
BackRight.Attachment.AlignPosition,
},
}
local LastEnviroment = nil
local LastUpdateTick = tick()
local LastTargetValue = 0
task.wait(3)
local LastDronePosition = Drone.Position
while true do
local NearGround = NearGround()
local TooHigh = if script.Parent.Torso.Position.Y > 40 then 1 else 0
local ProperlyOrientated = 1
local TargetValue, Target = GetTarget()
local enviroment = {NearGround, ProperlyOrientated, TooHigh, TargetValue}
if LastEnviroment == nil then
LastEnviroment = enviroment
end
local _, Prediction = NewAI:ForwardPropagation(enviroment, ActivationFunction)
local StillFlyingValue = 137.5
if Prediction[1] then
local thrust = Prediction[1] * 5 -- small adjustment range
Propellers.FrontLeft[2].VectorVelocity = Vector3.new(0, thrust, 0)
Propellers.FrontRight[2].VectorVelocity = Vector3.new(0, thrust, 0)
Propellers.BackLeft[2].VectorVelocity = Vector3.new(0, thrust, 0)
Propellers.BackRight[2].VectorVelocity = Vector3.new(0, thrust, 0)
end
if Prediction[2] and Prediction[3] then
local X = math.clamp(Prediction[2], -1, 1) * 10
local Z = math.clamp(Prediction[3], -1, 1) * 10
Propellers.FrontLeft[1].CFrame = CFrame.Angles(math.rad(X), 0, math.rad(-Z))
Propellers.FrontRight[1].CFrame = CFrame.Angles(math.rad(X), 0, math.rad(-Z))
Propellers.BackLeft[1].CFrame = CFrame.Angles(math.rad(X), 0, math.rad(-Z))
Propellers.BackRight[1].CFrame = CFrame.Angles(math.rad(X), 0, math.rad(-Z))
local Y = Propellers.FrontLeft[2].VectorVelocity.Y
Propellers.FrontLeft[2].VectorVelocity = Vector3.new(X, Y, Z)
Propellers.FrontRight[2].VectorVelocity = Vector3.new(X, Y, Z)
Propellers.BackLeft[2].VectorVelocity = Vector3.new(X, Y, Z)
Propellers.BackRight[2].VectorVelocity = Vector3.new(X, Y, Z)
end
local maxSafeHeight = 30
local currentHeight = Drone.Position.Y
local HeightReward = -math.max(0, (currentHeight - maxSafeHeight)) * 0.05
if currentHeight > (maxSafeHeight + 10) then
HeightReward = -1
end
local TargetReward = if TargetValue == 0 then -1 else 1
if TargetReward == -1 then
local HoldingStillAmount = 0
if Prediction[1] < .1 and Prediction[1] > -.1 then
HoldingStillAmount += 1
end
if Prediction[2] < .1 and Prediction[2] > -.1 then
HoldingStillAmount += 1
end
if HoldingStillAmount == 2 then
TargetReward = -1
else
TargetReward = 0
end
end
if Target then
local distanceToPlayer = (Drone.Position - Target.PrimaryPart.Position).Magnitude
local maxDistance = 100
TargetReward = 5
local lastDistance = (LastDronePosition - Target.PrimaryPart.Position).Magnitude
if distanceToPlayer < lastDistance then
TargetReward += 5
end
end
if LastTargetValue == 1 and TargetValue == 0 and Drone.Position.Magnitude - LastDronePosition.Magnitude < 1 then
TargetReward = -5
TargetValue = 1
DQL:Learn {
State = enviroment,
LastState = LastEnviroment,
Action = 2,
Reward = TargetReward
}
DQL:Learn {
State = enviroment,
LastState = LastEnviroment,
Action = 3,
Reward = TargetReward
}
end
print(TargetReward)
if (tick() - LastUpdateTick) > .5 then
DQL:Learn {
State = enviroment,
LastState = LastEnviroment,
Action = 1,
Reward = HeightReward
}
DQL:Learn {
State = enviroment,
LastState = LastEnviroment,
Action = 2,
Reward = TargetReward
}
DQL:Learn {
State = enviroment,
LastState = LastEnviroment,
Action = 3,
Reward = TargetReward
}
LastUpdateTick = tick()
end
LastTargetValue = TargetValue
LastDronePosition = Drone.Position
task.wait()
end