So I think I got it but after 6 it gets the same error:
Code:
local OpenML = require(script.OpenML)
local Ragdoll = require(script.Ragdoll)
local States = { "Distance", "Health", "Angle", "DirX", "DirZ", "Random", }
local Actions = { "Idle", "TurnLeft", "TurnRight", "MoveX", "MoveZ", "Jump" }
local turnSpeed = 20
local ActivationFunction = OpenML.ActivationFunctions.TanH
game:GetService("Players").PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character:AddTag("Character")
local ragdoll = Ragdoll.new(character)
for _, v in next, character:GetDescendants() do
if v:IsA("BasePart") then
v.CollisionGroup = "Fighter"
end
end
character.Humanoid.BreakJointsOnDeath = false
character.Humanoid.Died:Once(function()
character:RemoveTag("Character")
character.Humanoid.AutoRotate = false
ragdoll:Toggle(true)
character.HumanoidRootPart:SetNetworkOwner(player)
for _, v in next, character:GetDescendants() do
if v:IsA("BasePart") then
v.CollisionGroup = "Ragdoll"
end
end
end)
end)
end)
local tpCooldown = {}
for _, v in next, workspace.Box:GetChildren() do
if v:IsA("BasePart") then
v.Touched:Connect(function(otherPart)
if otherPart.Parent:HasTag("Character") then
if tpCooldown[otherPart.Parent.Name] then return end
otherPart.Parent:MoveTo(workspace.SpawnLocation.Position) --otherPart.Parent:PivotTo(script.Rig:GetPivot() * CFrame.new((math.random() * 2 - 1) * 35, 0, (math.random() * 2 - 1) * 35))
tpCooldown[otherPart.Parent.Name] = true
task.wait(1)
tpCooldown[otherPart.Parent.Name] = false
end
print(tpCooldown)
end)
end
end
local function perform360Raycast(humanoidRootPart)
local debug = true
local rayLength = 50 -- Set the length of the rays
local numberOfRays = 36 -- Number of rays to cast (360 degrees / 10 degrees per ray)
local detectedObjects = {}
for i = 0, numberOfRays - 1 do
local angle = math.rad(i * (360 / numberOfRays))
local direction = CFrame.fromEulerAnglesYXZ(0, angle, 0).LookVector
local rayOrigin = humanoidRootPart.Position
local rayDirection = direction * rayLength
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {humanoidRootPart.Parent, humanoidRootPart.Parent:FindFirstChild("RaycastParts")} -- Ignore the NPC itself
raycastParams.RespectCanCollide = true
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
table.insert(detectedObjects, {
Part = raycastResult.Instance,
Position = raycastResult.Position,
Normal = raycastResult.Normal,
Distance = raycastResult.Distance,
Direction = direction -- Store the direction of the ray
})
end
if debug then
for _, object in humanoidRootPart.Parent.RaycastParts:GetChildren() do
if object:IsA("Part") then
if object.Name == tostring(i) then
object:Destroy()
end
end
end
if raycastResult then
local debugPart = Instance.new("Part", humanoidRootPart.Parent.RaycastParts)
debugPart.Name = i
debugPart.Anchored = true
debugPart.CanCollide = false
debugPart.CanQuery = false
debugPart.CanTouch = false
debugPart.Size = Vector3.one * 1.5
debugPart.Position = raycastResult.Position
debugPart.Material = raycastResult.Material
debugPart.BrickColor = BrickColor.new("Lime green")
debugPart.Shape = Enum.PartType.Ball
end
end
if i < 6 then
break
end
end
return detectedObjects
end
for i = 1, 1 do
task.spawn(function()
while task.wait() do
local rig = script.Rig:Clone()
rig.Name = "AI-"..i
rig:AddTag("Character")
rig:MoveTo(workspace.SpawnLocation.Position) --rig:PivotTo(rig:GetPivot() * CFrame.new((math.random() * 2 - 1) * 35, 0, (math.random() * 2 - 1) * 35))
rig.Parent = workspace
local humanoid = rig.Humanoid
local humanoidRootPart = rig.HumanoidRootPart
local ragdoll = Ragdoll.new(rig)
humanoid.Died:Once(function()
rig:RemoveTag("Character")
rig.HumanoidRootPart.AngularVelocity.Enabled = false
--rig.ClassicSword.SwordScript.Enabled = false
ragdoll:Toggle(true)
for _, v in next, rig:GetDescendants() do
if v:IsA("BasePart") then
v.CollisionGroup = "Ragdoll"
end
end
task.wait(3)
rig:Destroy()
end)
local function avoidObstacles(humanoidRootPart, detectedObjects)
local avoidanceThreshold = 10 -- Distance threshold for obstacle avoidance
local avoidanceForce = Vector3.zero -- Initialize the avoidance force
for _, obj in ipairs(detectedObjects) do
if obj.Distance < avoidanceThreshold then
-- Calculate the opposite direction to move away from the obstacle
local avoidanceDirection = -obj.Direction / obj.Distance
avoidanceForce = avoidanceForce + avoidanceDirection
end
end
if avoidanceForce.Magnitude > 0 then
avoidanceForce = avoidanceForce.Unit -- Normalize the force vector
humanoid:Move(avoidanceForce) -- Move the NPC in the avoidance direction
end
end
-- Integrate this into your existing loop
while true and rig.Parent and humanoid.Health > 0 do
local detectedObjects = perform360Raycast(humanoidRootPart)
-- Process detected objects here for obstacle avoidance
avoidObstacles(humanoidRootPart, detectedObjects)
local NeuralNetwork = setmetatable(OpenML.Resources.MLP.new({ #States + #detectedObjects, 10, 10, 10, #Actions }, function()
return (math.random() * 2 - 1) * 1.5
end), { __index = OpenML.Algorithms.Propagator })
local DQL = OpenML.Resources.DQL.new()
local startingLearningRate = 0.00015
local maxLearningRate = 0.0015
local learningRateMultiplier = 1.00015
local learningRate = startingLearningRate
DQL.OnForwardPropagation = function(state) return NeuralNetwork:ForwardPropagation(state, ActivationFunction) end
DQL.OnBackPropagation = function(activations, target) return NeuralNetwork:BackPropagation(activations, target, { ActivationFunction = ActivationFunction, LearningRate = learningRate }) end
-- Continue with your existing code
learningRate = math.max(math.min(learningRate * learningRateMultiplier, maxLearningRate) % maxLearningRate, startingLearningRate)
local deltaTime = task.wait()
local characters = game:GetService("CollectionService"):GetTagged("Character")
local character, closestDistance = nil, math.huge
for _, v in next, characters do
--if v == rig or not v:FindFirstChild("HumanoidRootPart") then continue end
local distance = (rig:GetPivot().Position - v.HumanoidRootPart.Position).Magnitude
if distance < closestDistance then
character, closestDistance = v, distance
end
end
if character then
local positionDifference: Vector3 = (character:GetPivot().Position - workspace.Goal.Position) --(character.HumanoidRootPart.Position - humanoidRootPart.Position)
local distance = positionDifference.Magnitude / 50
local angleDot = positionDifference.Unit:Dot(humanoidRootPart.CFrame.LookVector)
local unitPositionDifferenceXZ = (positionDifference * Vector3.new(1, 0, 1)).Unit
local environment = { distance, 1 - humanoid.Health/humanoid.MaxHealth, angleDot, unitPositionDifferenceXZ.X, unitPositionDifferenceXZ.Z, math.random() }
for _, object in detectedObjects do
if #detectedObjects < 6 then
if object.Part.Parent == workspace then
table.insert(environment, tonumber(1))
elseif object.Part.Parent == character or object.Part.Parent == character:FindFirstChild("RaycastParts") then
table.insert(environment, tonumber(-1))
elseif object.Part.Parent == nil then
table.insert(environment, tonumber(0))
end
end
--print(environment)
end
print(environment)
local activations = NeuralNetwork:ForwardPropagation(environment, ActivationFunction)
local lastActivationLayer = activations[#activations]
humanoidRootPart:PivotTo(
humanoidRootPart:GetPivot()
* CFrame.fromEulerAnglesXYZ(0, deltaTime * turnSpeed * lastActivationLayer[2], 0)
* CFrame.fromEulerAnglesXYZ(0, -deltaTime * turnSpeed * lastActivationLayer[3], 0)
)
humanoidRootPart.AssemblyAngularVelocity = --.AngularVelocity.AngularVelocity =
Vector3.yAxis * (turnSpeed * lastActivationLayer[2] - turnSpeed * lastActivationLayer[3])
if lastActivationLayer[1] < 0.5 then
humanoid:Move(Vector3.new(lastActivationLayer[4] - 0.5, 0, lastActivationLayer[5] - 0.5).Unit)
end
if lastActivationLayer[6] > 0.5 then
humanoid.Jump = true
end
DQL:Learn{
State = environment,
Action = 1,
Reward = (distance > 3 and lastActivationLayer[1] > 0.5 and 1 or -1)
}
local rightAngleDot = positionDifference.Unit:Dot(humanoidRootPart.CFrame.RightVector)
DQL:Learn{
State = environment,
Action = 2,
Reward = ((-rightAngleDot) + 0.05)
}; DQL:Learn{
State = environment,
Action = 3,
Reward = ((rightAngleDot) + 0.05)
};
DQL:Learn{
State = environment,
Action = 4,
Reward = (positionDifference.Unit.X - humanoid.MoveDirection.X) - 0.5,
}; DQL:Learn{
State = environment,
Action = 5,
Reward = (positionDifference.Unit.Z - humanoid.MoveDirection.Z) - 0.5,
};
DQL:Learn{
State = environment,
Action = 6,
Reward = lastActivationLayer[6] > 0.5 and humanoid.Health/humanoid.MaxHealth < 0.2 and 0.5 or -0.5,
};
end
end
task.wait(3)
end
end)
end