using System.Collections; using System.Collections.Generic; using Unity.MLAgents; using UnityEngine; using UnityEngine.Serialization; [System.Serializable] public class PlayerState { public int playerIndex; [FormerlySerializedAs("agentRB")] public Rigidbody agentRb; public Vector3 startingPos; public AgentSoccer agentScript; public float ballPosReward; } public class SoccerFieldArea : MonoBehaviour { public GameObject ball; [FormerlySerializedAs("ballRB")] [HideInInspector] public Rigidbody ballRb; public GameObject ground; public GameObject centerPitch; SoccerBallController m_BallController; public List playerStates = new List(); [HideInInspector] public Vector3 ballStartingPos; public GameObject goalTextUI; [HideInInspector] public bool canResetBall; EnvironmentParameters m_ResetParams; void Awake() { canResetBall = true; if (goalTextUI) { goalTextUI.SetActive(false); } ballRb = ball.GetComponent(); m_BallController = ball.GetComponent(); m_BallController.area = this; ballStartingPos = ball.transform.position; m_ResetParams = Academy.Instance.EnvironmentParameters; } IEnumerator ShowGoalUI() { if (goalTextUI) goalTextUI.SetActive(true); yield return new WaitForSeconds(.25f); if (goalTextUI) goalTextUI.SetActive(false); } public void GoalTouched(AgentSoccer.Team scoredTeam) { foreach (var ps in playerStates) { if (ps.agentScript.team == scoredTeam) { ps.agentScript.AddReward(1 + ps.agentScript.timePenalty); } else { ps.agentScript.AddReward(-1); } ps.agentScript.EndEpisode(); //all agents need to be reset if (goalTextUI) { StartCoroutine(ShowGoalUI()); } } } public void ResetBall() { var randomX = Random.Range(-2.0f, 2.0f); var randomZ = Random.Range(-2.0f, 2.0f); ball.transform.position = ballStartingPos + new Vector3(randomX, 0f, randomZ); ballRb.velocity = Vector3.zero; ballRb.angularVelocity = Vector3.zero; var ballScale = m_ResetParams.GetWithDefault("ball_scale", 0.015f); ballRb.transform.localScale = new Vector3(ballScale, ballScale, ballScale); } }