using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class SchoolController : MonoBehaviour { public SchoolChild[] _childPrefab; public bool _groupChildToNewTransform; public Transform _groupTransform; public string _groupName = string.Empty; public bool _groupChildToSchool; public int _childAmount = 250; public float _spawnSphere = 3f; public float _spawnSphereDepth = 3f; public float _spawnSphereHeight = 1.5f; public float _childSpeedMultipler = 2f; public float _minSpeed = 6f; public float _maxSpeed = 10f; public AnimationCurve _speedCurveMultiplier = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public float fishScaleMultiplier = 1f; public float _minScale = 0.7f; public float _maxScale = 1f; public float _minDamping = 1f; public float _maxDamping = 2f; public float _waypointDistance = 1f; public float _minAnimationSpeed = 2f; public float _maxAnimationSpeed = 4f; public float _randomPositionTimerMax = 10f; public float _randomPositionTimerMin = 4f; public float _acceleration = 0.025f; public float _brake = 0.01f; public float _positionSphere = 25f; public float _positionSphereDepth = 5f; public float _positionSphereHeight = 5f; public bool _childTriggerPos; public bool _forceChildWaypoints; public bool _autoRandomPosition; public float _forcedRandomDelay = 1.5f; public float _schoolSpeed; public List _roamers; public Vector3 _posBuffer; public Vector3 _posOffset; public bool _avoidance; public float _avoidAngle = 0.35f; public float _avoidDistance = 1f; public float _avoidSpeed = 75f; public float _stopDistance = 0.5f; public float _stopSpeedMultiplier = 2f; public LayerMask _avoidanceMask = -1; public bool _push; public float _pushDistance; public float _pushForce = 5f; public SchoolBubbles _bubbles; public int _updateDivisor = 1; public float _newDelta; public int _updateCounter; public int _activeChildren; public float maxSkew = 15f; public void Start() { _posBuffer = base.transform.position + _posOffset; _schoolSpeed = Random.Range(1f, _childSpeedMultipler); Invoke("AutoRandomWaypointPosition", RandomWaypointTime()); } public void Update() { if (_activeChildren > 0) { if (_updateDivisor > 1) { _updateCounter++; _updateCounter %= _updateDivisor; _newDelta = Time.deltaTime * (float)_updateDivisor; } else { _newDelta = Time.deltaTime; } } } public void InstantiateGroup() { if (!(_groupTransform != null)) { GameObject gameObject = new GameObject(); _groupTransform = gameObject.transform; _groupTransform.position = base.transform.position; if (_groupName != string.Empty) { gameObject.name = _groupName; } else { gameObject.name = base.transform.name + " Fish Container"; } } } public SchoolChild GetFish(FishManager.FishKept fish) { return _roamers.First((SchoolChild x) => x.fishInstanceID == fish.instanceID); } public SchoolChild GetFirstFish() { if (_roamers == null) { return null; } if (_roamers.Count <= 0) { return null; } return _roamers[0]; } public SchoolChild GetNextFish(FishManager.FishKept fish) { return GetNeighbourFish(fish, true); } public SchoolChild GetPreviousFish(FishManager.FishKept fish) { return GetNeighbourFish(fish, false); } public int GetSchoolSize() { return _roamers.Count; } private SchoolChild GetNeighbourFish(FishManager.FishKept fish, bool next) { int index = 0; for (int i = 0; i < _roamers.Count; i++) { if (_roamers[i].fishInstanceID == fish.instanceID) { index = ((!next) ? ((i != 0) ? (i - 1) : (_roamers.Count - 1)) : ((i != _roamers.Count - 1) ? (i + 1) : 0)); break; } } return _roamers[index]; } public SchoolChild AddFish(FishManager.FishKept fish) { Fish fish2 = Object.Instantiate(fish.GetFishDefinition().fishPrefab); Utilities.SetLayerRecursively(fish2.gameObject, LayerMask.NameToLayer("Bait")); ModelViewerObject component = fish2.GetComponent(); component.Initialize(); component.enabled = false; if (fish2.mainMaterialId == 0) { fish2.rigRenderer.material = fish2.watchMaterial; } else { fish2.rigRenderer.materials[fish2.mainMaterialId] = fish2.watchMaterial; } fish2.transform.localScale = Vector3.one * fish.length * fishScaleMultiplier; Transform transform = new GameObject(fish2.name + "_Parent").transform; transform.position = Vector3.zero; transform.rotation = Quaternion.identity; fish2.transform.SetParent(transform); fish2.transform.localPosition = Vector3.zero; fish2.transform.localRotation = Quaternion.identity; Vector3 vector = -AquariumUtilities.RecursiveFindChild(fish2.transform, "ResizeParent").localPosition; fish2.transform.localPosition = new Vector3(vector.x * fish2.transform.localScale.x, vector.y * fish2.transform.localScale.y, vector.z * fish2.transform.localScale.z); SchoolChild schoolChild = transform.gameObject.GetComponent(); if (schoolChild == null) { schoolChild = transform.gameObject.AddComponent(); } schoolChild.fishInstanceID = fish.instanceID; schoolChild._spawner = this; schoolChild.FishKept = fish; _roamers.Add(schoolChild); AddChildToParent(transform); return schoolChild; } private IEnumerator SetPivot(Fish fishInstance) { yield return null; Vector3 pivotShift = fishInstance.transform.parent.position - fishInstance.rigRenderer.bounds.center; fishInstance.transform.localPosition = new Vector3(pivotShift.x * fishInstance.transform.localScale.x, pivotShift.y * fishInstance.transform.localScale.y, pivotShift.z * fishInstance.transform.localScale.z); } public void RemoveFish(FishManager.FishKept fish) { SchoolChild fish2 = GetFish(fish); _roamers.Remove(fish2); fish.aquarium = -1; Object.Destroy(fish2.gameObject); } public void RemoveAllFish() { foreach (SchoolChild roamer in _roamers) { Object.Destroy(roamer.gameObject); } _roamers.Clear(); } public void AddFish(int amount) { if (_groupChildToNewTransform) { InstantiateGroup(); } for (int i = 0; i < amount; i++) { int num = Random.Range(0, _childPrefab.Length); SchoolChild schoolChild = Object.Instantiate(_childPrefab[num]); schoolChild._spawner = this; _roamers.Add(schoolChild); AddChildToParent(schoolChild.transform); } } public void AddChildToParent(Transform obj) { if (_groupChildToSchool) { obj.parent = base.transform; } else if (_groupChildToNewTransform) { obj.parent = _groupTransform; } } public void RemoveFish(int amount) { SchoolChild schoolChild = _roamers[_roamers.Count - 1]; _roamers.RemoveAt(_roamers.Count - 1); Object.Destroy(schoolChild.gameObject); } public void UpdateFishAmount() { if (_childAmount >= 0 && _childAmount < _roamers.Count) { RemoveFish(1); } else if (_childAmount > _roamers.Count) { AddFish(1); } } public void SetRandomWaypointPosition() { _schoolSpeed = Random.Range(1f, _childSpeedMultipler); Vector3 zero = Vector3.zero; zero.x = Random.Range(0f - _positionSphere, _positionSphere) + base.transform.position.x; zero.z = Random.Range(0f - _positionSphereDepth, _positionSphereDepth) + base.transform.position.z; zero.y = Random.Range(0f - _positionSphereHeight, _positionSphereHeight) + base.transform.position.y; _posBuffer = zero; if (_forceChildWaypoints) { for (int i = 0; i < _roamers.Count; i++) { _roamers[i].Wander(Random.value * _forcedRandomDelay); } } } public void AutoRandomWaypointPosition() { if (_autoRandomPosition && _activeChildren > 0) { SetRandomWaypointPosition(); } CancelInvoke("AutoRandomWaypointPosition"); Invoke("AutoRandomWaypointPosition", RandomWaypointTime()); } public float RandomWaypointTime() { return Random.Range(_randomPositionTimerMin, _randomPositionTimerMax); } public void OnDrawGizmos() { if (!Application.isPlaying && _posBuffer != base.transform.position + _posOffset) { _posBuffer = base.transform.position + _posOffset; } Gizmos.color = Color.blue; Gizmos.DrawWireCube(_posBuffer, new Vector3(_spawnSphere * 2f, _spawnSphereHeight * 2f, _spawnSphereDepth * 2f)); Gizmos.color = Color.cyan; Gizmos.DrawWireCube(base.transform.position, new Vector3(_positionSphere * 2f + _spawnSphere * 2f, _positionSphereHeight * 2f + _spawnSphereHeight * 2f, _positionSphereDepth * 2f + _spawnSphereDepth * 2f)); } }