353 lines
8.4 KiB
C#
353 lines
8.4 KiB
C#
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<SchoolChild> _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<ModelViewerObject>();
|
|
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<SchoolChild>();
|
|
if (schoolChild == null)
|
|
{
|
|
schoolChild = transform.gameObject.AddComponent<SchoolChild>();
|
|
}
|
|
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));
|
|
}
|
|
}
|