|
using System; |
|
using UnityEngine; |
|
using UnityEngine.Serialization; |
|
|
|
namespace Unity.MLAgents |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[AddComponentMenu("ML Agents/Decision Requester", (int)MenuGroup.Default)] |
|
[RequireComponent(typeof(Agent))] |
|
[DefaultExecutionOrder(-10)] |
|
public class DecisionRequester : MonoBehaviour |
|
{ |
|
|
|
|
|
|
|
[Range(1, 20)] |
|
[Tooltip("The frequency with which the agent requests a decision. A DecisionPeriod " + |
|
"of 5 means that the Agent will request a decision every 5 Academy steps.")] |
|
public int DecisionPeriod = 5; |
|
|
|
|
|
|
|
|
|
|
|
|
|
[Range(0, 19)] |
|
[Tooltip("Indicates when to requests a decision. By changing this value, the timing " + |
|
"of decision can be shifted even among agents with the same decision period. " + |
|
"The value can be from 0 to DecisionPeriod - 1.")] |
|
public int DecisionStep = 0; |
|
|
|
|
|
|
|
|
|
|
|
[Tooltip("Indicates whether or not the agent will take an action during the Academy " + |
|
"steps where it does not request a decision. Has no effect when DecisionPeriod " + |
|
"is set to 1.")] |
|
[FormerlySerializedAs("RepeatAction")] |
|
public bool TakeActionsBetweenDecisions = true; |
|
|
|
[NonSerialized] |
|
Agent m_Agent; |
|
|
|
|
|
|
|
|
|
public Agent Agent |
|
{ |
|
get => m_Agent; |
|
} |
|
|
|
internal void Awake() |
|
{ |
|
Debug.Assert(DecisionStep < DecisionPeriod, "DecisionStep must be between 0 and DecisionPeriod - 1."); |
|
m_Agent = gameObject.GetComponent<Agent>(); |
|
Debug.Assert(m_Agent != null, "Agent component was not found on this gameObject and is required."); |
|
Academy.Instance.AgentPreStep += MakeRequests; |
|
} |
|
|
|
void OnDestroy() |
|
{ |
|
if (Academy.IsInitialized) |
|
{ |
|
Academy.Instance.AgentPreStep -= MakeRequests; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
public struct DecisionRequestContext |
|
{ |
|
|
|
|
|
|
|
public int AcademyStepCount; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
void MakeRequests(int academyStepCount) |
|
{ |
|
var context = new DecisionRequestContext |
|
{ |
|
AcademyStepCount = academyStepCount |
|
}; |
|
|
|
if (ShouldRequestDecision(context)) |
|
{ |
|
m_Agent?.RequestDecision(); |
|
} |
|
|
|
if (ShouldRequestAction(context)) |
|
{ |
|
m_Agent?.RequestAction(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual bool ShouldRequestDecision(DecisionRequestContext context) |
|
{ |
|
return context.AcademyStepCount % DecisionPeriod == DecisionStep; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual bool ShouldRequestAction(DecisionRequestContext context) |
|
{ |
|
return TakeActionsBetweenDecisions; |
|
} |
|
} |
|
} |
|
|