using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using UnityEngine; using UnityEngine.InputSystem; public class HerdController : MonoBehaviour { [SerializeField] private GameObject Prefab; [SerializeField] private int HerdCount = 50; [SerializeField] private Transform SpawnPoint; [SerializeField] private float WaitTime; [SerializeField] public Transform Centre; private float lastTime; public List Herd; private Vector2 recievedInput; public GameStateController GameState; public BallController Ball; void Start() { GameState = FindObjectOfType(); SpawnHerd(); } //Recieved movement input from player private void OnMovement(InputValue value) { Vector2 input = value.Get(); if (input.magnitude > 0) input = input.normalized; Herd.ForEach(p => p.SetMovement(input)); recievedInput = input; Ball.GetInput(input); } private void OnSprint(InputValue value) { int input = (int)value.Get(); Debug.Log("Sprint: " + input); if (input == 1) { Ball.EatHorse = true; Ball.transform.position = Centre.position; } else { Ball.EatHorse = false; } } private Vector3 GetCentre() { Vector3 centreofMass = Vector3.zero; int CountedHorses = 0; foreach (PlayerController horse in Herd) { if (horse.isGrounded || Time.time < 5) { centreofMass += horse.transform.position; CountedHorses++; } } if (CountedHorses != 0) { return centreofMass / CountedHorses; } else { return Vector3.one; } } [ContextMenu("Spawn")] private void SpawnHerd() { float radius = 0; GameObject prefabExample = Instantiate(Prefab); Bounds bound = prefabExample.GetBounds(); Debug.Log(bound.size); Destroy(prefabExample); if (Herd != null) Herd.ForEach(p => Destroy(p)); Herd = new List(); for (int i = 0; i < HerdCount; i++) { int SpawnAttempt = 0; while (true) { Vector3 position = Vector3.ProjectOnPlane(Random.onUnitSphere, Vector3.up) * radius; Quaternion rotation = Quaternion.identity; if (SpawnPoint != null) position += SpawnPoint.position; if (SpawnPositionValid(position, rotation, bound)) { GameObject newObject = Instantiate(Prefab, position, rotation, transform); foreach (MeshRenderer mr in newObject.GetComponentsInChildren()) { mr.material.color = new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1); } Herd.Add(newObject.GetComponent()); break; } SpawnAttempt++; if (SpawnAttempt % 10 == 0) { radius += bound.size.magnitude; } if (SpawnAttempt == 100) break; } } Debug.Log("Total Spawned: " + Herd.Count); } public void FixedUpdate() { if (recievedInput.magnitude > 0 && lastTime + WaitTime < Time.time) { Herd.ForEach(p => p.MoveObject(WaitTime)); lastTime = Time.time; } if (Herd?.Count > 0) { Bounds bound = new Bounds(Herd[0].transform.position, Vector3.zero); Vector3 centreofMass = Vector3.zero; int CountedHorses = 0; foreach (PlayerController horse in Herd) { if (horse.isGrounded || Time.time < 5) { bound.Encapsulate(horse.transform.position); centreofMass += horse.transform.position; CountedHorses++; } } if (CountedHorses != 0) { Centre.position = centreofMass / CountedHorses; Centre.localScale = bound.size * 0.75f; } } else { GameState.LoseState(); } } public void RemoveHorse(PlayerController horse) { Herd.Remove(horse); Destroy(horse.gameObject); } private bool SpawnPositionValid(Vector3 position, Quaternion rotation, Bounds bound) { Collider[] colliders = Physics.OverlapBox(position, bound.extents, rotation); Debug.DrawLine(position, position + Vector3.up); foreach (Collider col in colliders) { if (col.GetComponentInChildren()) return false; if (col.GetComponentInParent()) return false; } return true; } }