339 lines
12 KiB
C#
339 lines
12 KiB
C#
using System;
|
|
using System.Collections;
|
|
using Obvious.Soap;
|
|
using ShiningGames.UFS2;
|
|
using UFS2.ScriptableObjects;
|
|
using UltimateWater;
|
|
using UnityEngine;
|
|
using Voxus.Random;
|
|
|
|
namespace UFS2.Gameplay
|
|
{
|
|
public class FishSpawner : MonoBehaviour
|
|
{
|
|
[Range(0f, 100f)]
|
|
public int InstantiateCount = 1;
|
|
|
|
public int FishPoolMaxSize = 100;
|
|
|
|
[SerializeField]
|
|
private LevelFishData LevelFishData;
|
|
|
|
[SerializeField]
|
|
private Vector3Variable player_CurrentPosition;
|
|
|
|
[SerializeField]
|
|
private FloatVariable lineTension;
|
|
|
|
public bool IsTriggerCollider;
|
|
|
|
public GameObject ObjectPool;
|
|
|
|
private float lastSpawnTime;
|
|
|
|
private const float spawnCooldown = 1f;
|
|
|
|
public static event Action<FishEntity, int> OnSpawnFish;
|
|
|
|
public static event Action<FishEntity> OnDespawnFish;
|
|
|
|
public static event Action OnStartFishesSpawned;
|
|
|
|
private void OnEnable()
|
|
{
|
|
FishEntity.OnPostSpitOutBait += FishEntity_OnPostSpitOutBait;
|
|
FishEntity.OnOldFishKill += FishEntity_OnPostSpitOutBait;
|
|
MultiplayerFishSpawner.OnNetworkedFishSpawn += MultiplayerFishSpawner_OnNetworkedFishSpawn;
|
|
MultiplayerFishSpawner.OnNetworkedFishDelete += MultiplayerFishSpawner_OnNetworkedFishDelete;
|
|
MultiplayerFishSpawner.OnFishDeleteAfterInteraction += MultiplayerFishSpawner_OnFishDeleteAfterInteraction;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
FishEntity.OnPostSpitOutBait -= FishEntity_OnPostSpitOutBait;
|
|
FishEntity.OnOldFishKill -= FishEntity_OnPostSpitOutBait;
|
|
MultiplayerFishSpawner.OnNetworkedFishSpawn -= MultiplayerFishSpawner_OnNetworkedFishSpawn;
|
|
MultiplayerFishSpawner.OnNetworkedFishDelete -= MultiplayerFishSpawner_OnNetworkedFishDelete;
|
|
MultiplayerFishSpawner.OnFishDeleteAfterInteraction -= MultiplayerFishSpawner_OnFishDeleteAfterInteraction;
|
|
}
|
|
|
|
private void FishEntity_OnPostSpitOutBait(FishEntity fish)
|
|
{
|
|
if (!MultiplayerFishSpawner.IsSlave)
|
|
{
|
|
InstantiateNewFish(1);
|
|
}
|
|
}
|
|
|
|
private void MultiplayerFishSpawner_OnNetworkedFishSpawn(MultiplayerFishSpawner.NetworkedFish networkedFish)
|
|
{
|
|
if (MultiplayerFishSpawner.IsSlave)
|
|
{
|
|
networkedFish.fishEntity = InstantiateNewFish(networkedFish.fishID, networkedFish.fishWeight, networkedFish.position, networkedFish.targetAreaID);
|
|
}
|
|
}
|
|
|
|
private void MultiplayerFishSpawner_OnNetworkedFishDelete(MultiplayerFishSpawner.NetworkedFish networkedFish)
|
|
{
|
|
if (MultiplayerFishSpawner.IsSlave)
|
|
{
|
|
FishEntity fishEntity = networkedFish.fishEntity;
|
|
if (fishEntity != null)
|
|
{
|
|
FishSpawner.OnDespawnFish?.Invoke(fishEntity);
|
|
fishEntity.gameObject.Destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MultiplayerFishSpawner_OnFishDeleteAfterInteraction()
|
|
{
|
|
if (!MultiplayerFishSpawner.IsSlave)
|
|
{
|
|
InstantiateNewFish(1);
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
int count = ((!MultiplayerFishSpawner.IsSlave) ? LevelFishData.StartCount : 0);
|
|
InstantiateNewFish(count);
|
|
StartCoroutine(WaitForStartFishGenerated(count));
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
InstantiateExtraFish();
|
|
}
|
|
|
|
private IEnumerator WaitForStartFishGenerated(int count)
|
|
{
|
|
OnSpawnFish += FishSpawner_OnSpawnFish;
|
|
while (count > 0)
|
|
{
|
|
yield return null;
|
|
}
|
|
FishSpawner.OnStartFishesSpawned?.Invoke();
|
|
OnSpawnFish -= FishSpawner_OnSpawnFish;
|
|
void FishSpawner_OnSpawnFish(FishEntity obj, int levelFishDataIndex)
|
|
{
|
|
count--;
|
|
}
|
|
}
|
|
|
|
public static void Despawn(FishEntity fish)
|
|
{
|
|
FishSpawner.OnDespawnFish?.Invoke(fish);
|
|
}
|
|
|
|
public void KillFishes()
|
|
{
|
|
FishEntity[] componentsInChildren = ObjectPool.GetComponentsInChildren<FishEntity>();
|
|
foreach (FishEntity fishEntity in componentsInChildren)
|
|
{
|
|
FishSpawner.OnDespawnFish?.Invoke(fishEntity);
|
|
fishEntity.gameObject.Destroy();
|
|
}
|
|
}
|
|
|
|
public void InstantiateExtraFish()
|
|
{
|
|
if (MultiplayerFishSpawner.IsMaster)
|
|
{
|
|
int count = Singleton<FishEntityManager>.Instance.CullTransforms.Count;
|
|
int count2 = Singleton<FishEntityManager>.Instance.AllFishes.Count;
|
|
int num = LevelFishData.StartCount;
|
|
if (count >= 7)
|
|
{
|
|
num = 70;
|
|
}
|
|
if (count >= 14)
|
|
{
|
|
num = 120;
|
|
}
|
|
if (count2 < num && Time.time - lastSpawnTime >= 1f)
|
|
{
|
|
lastSpawnTime = Time.time;
|
|
InstantiateNewFish(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
public FishEntity InstantiateNewFish(int fishIndex, float weight, Vector3 position, int targetAreaID)
|
|
{
|
|
if (fishIndex < 0 || fishIndex >= LevelFishData.FishesSetting.Count)
|
|
{
|
|
Debug.LogError("Invalid fish index specified for spawning.");
|
|
return null;
|
|
}
|
|
LevelFishData.FishDataHelper fishDataHelper = LevelFishData.FishesSetting[fishIndex];
|
|
GameObject original = fishDataHelper.FishData.LoadFishResource(weight);
|
|
GameObject gameObject = new GameObject("FishObject " + fishDataHelper.FishData.Name + " " + weight);
|
|
GameObject gameObject2 = UnityEngine.Object.Instantiate(original, gameObject.transform);
|
|
gameObject2.transform.localPosition = Vector3.zero;
|
|
gameObject2.transform.localRotation = Quaternion.identity;
|
|
Transform jointAnchor = gameObject2.GetComponent<FFish>().jointAnchor;
|
|
Transform transform = gameObject2.GetComponentInChildren<SpringJoint>().transform;
|
|
if (transform.TryGetComponent<Collider>(out var component))
|
|
{
|
|
UnityEngine.Object.Destroy(component);
|
|
}
|
|
Collider[] componentsInChildren = gameObject2.GetComponentsInChildren<Collider>();
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
componentsInChildren[i].isTrigger = true;
|
|
}
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFishRagDoll>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFish>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponentInChildren<SpringJoint>());
|
|
Rigidbody[] componentsInChildren2 = gameObject2.GetComponentsInChildren<Rigidbody>();
|
|
for (int i = 0; i < componentsInChildren2.Length; i++)
|
|
{
|
|
UnityEngine.Object.Destroy(componentsInChildren2[i]);
|
|
}
|
|
FishTargetArea fishTargetArea = FishTargetBaker.Instance.Areas[targetAreaID];
|
|
LocalAvoidance localAvoidance = gameObject.AddComponent<LocalAvoidance>();
|
|
localAvoidance.TailRag = transform;
|
|
localAvoidance.Target = fishTargetArea.GetRandomTarget(fishDataHelper.FishData.BehaviourType).Transform;
|
|
FishEntity fishEntity = gameObject.AddComponent<FishEntity>();
|
|
FishPhysics fishPhysics = gameObject.AddComponent<FishPhysics>();
|
|
gameObject.AddComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
|
gameObject.AddComponent<FishScanner>();
|
|
gameObject2.GetComponent<Animator>().cullingMode = AnimatorCullingMode.CullCompletely;
|
|
fishPhysics.ImportData(fishDataHelper.FishData, weight);
|
|
fishEntity.InitializeData(fishDataHelper.FishData, weight);
|
|
fishEntity.Player_CurrentPosition = player_CurrentPosition;
|
|
fishEntity.CurrentArea = fishTargetArea;
|
|
fishEntity.transform.position = position;
|
|
fishEntity.transform.parent = ObjectPool.transform;
|
|
fishEntity.JointAnchor = jointAnchor;
|
|
FishSpawner.OnSpawnFish?.Invoke(fishEntity, fishIndex);
|
|
return fishEntity;
|
|
}
|
|
|
|
public GameObject InstantiateFishDummy(int fishIndex, float weight, Vector3 position)
|
|
{
|
|
if (fishIndex < 0 || fishIndex >= LevelFishData.FishesSetting.Count)
|
|
{
|
|
Debug.LogError("Invalid fish index specified for spawning.");
|
|
return null;
|
|
}
|
|
LevelFishData.FishDataHelper fishDataHelper = LevelFishData.FishesSetting[fishIndex];
|
|
GameObject original = fishDataHelper.FishData.LoadFishResource(weight);
|
|
GameObject gameObject = new GameObject("FishObject " + fishDataHelper.FishData.Name + " " + weight);
|
|
gameObject.transform.position = position;
|
|
GameObject gameObject2 = UnityEngine.Object.Instantiate(original, gameObject.transform);
|
|
gameObject2.transform.localPosition = Vector3.zero;
|
|
gameObject2.transform.localRotation = Quaternion.identity;
|
|
_ = gameObject2.GetComponent<FFish>().jointAnchor;
|
|
if (gameObject2.GetComponentInChildren<SpringJoint>().transform.TryGetComponent<Collider>(out var component))
|
|
{
|
|
UnityEngine.Object.Destroy(component);
|
|
}
|
|
Collider[] componentsInChildren = gameObject2.GetComponentsInChildren<Collider>();
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
UnityEngine.Object.Destroy(componentsInChildren[i]);
|
|
}
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFishRagDoll>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFish>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponentInChildren<SpringJoint>());
|
|
Rigidbody[] componentsInChildren2 = gameObject2.GetComponentsInChildren<Rigidbody>();
|
|
for (int i = 0; i < componentsInChildren2.Length; i++)
|
|
{
|
|
UnityEngine.Object.Destroy(componentsInChildren2[i]);
|
|
}
|
|
gameObject2.GetComponent<Animator>().cullingMode = AnimatorCullingMode.CullCompletely;
|
|
gameObject2.transform.localScale = fishDataHelper.FishData.GetFishScale(weight);
|
|
return gameObject;
|
|
}
|
|
|
|
public void InstantiateNewFish(int count)
|
|
{
|
|
StartCoroutine(Spawn());
|
|
IEnumerator Spawn()
|
|
{
|
|
yield return null;
|
|
RandomGaussian randomGenerator = new RandomGaussian(0.2f, 0.4f);
|
|
randomGenerator.SetSeed(UnityEngine.Random.value);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
LevelFishData.FishDataHelper randomFishDataToSpawn = LevelFishData.GetRandomFishDataToSpawn();
|
|
int arg = LevelFishData.FishesSetting.IndexOf(randomFishDataToSpawn);
|
|
Vector2 weight = randomFishDataToSpawn.Weight;
|
|
float t = Mathf.Clamp01(randomGenerator.Get());
|
|
float weight2 = Mathf.Lerp(weight.x, weight.y, t);
|
|
GameObject original = randomFishDataToSpawn.FishData.LoadFishResource(weight2);
|
|
GameObject gameObject = new GameObject("FishObject " + randomFishDataToSpawn.FishData.Name + " " + weight2);
|
|
GameObject gameObject2 = UnityEngine.Object.Instantiate(original, gameObject.transform);
|
|
gameObject2.transform.localPosition = Vector3.zero;
|
|
gameObject2.transform.localRotation = Quaternion.identity;
|
|
Transform jointAnchor = gameObject2.GetComponent<FFish>().jointAnchor;
|
|
Transform transform = gameObject2.GetComponentInChildren<SpringJoint>().transform;
|
|
if (transform.TryGetComponent<Collider>(out var component))
|
|
{
|
|
UnityEngine.Object.Destroy(component);
|
|
}
|
|
Collider[] componentsInChildren = gameObject2.GetComponentsInChildren<Collider>();
|
|
for (int j = 0; j < componentsInChildren.Length; j++)
|
|
{
|
|
componentsInChildren[j].isTrigger = true;
|
|
}
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFishRagDoll>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponent<FFish>());
|
|
UnityEngine.Object.Destroy(gameObject2.GetComponentInChildren<SpringJoint>());
|
|
Rigidbody[] componentsInChildren2 = gameObject2.GetComponentsInChildren<Rigidbody>();
|
|
for (int j = 0; j < componentsInChildren2.Length; j++)
|
|
{
|
|
UnityEngine.Object.Destroy(componentsInChildren2[j]);
|
|
}
|
|
LocalAvoidance localAvoidance = gameObject.AddComponent<LocalAvoidance>();
|
|
localAvoidance.TailRag = transform;
|
|
FishEntity fishEntity = gameObject.AddComponent<FishEntity>();
|
|
FishPhysics fishPhysics = gameObject.AddComponent<FishPhysics>();
|
|
gameObject.AddComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
|
gameObject.AddComponent<FishScanner>();
|
|
Animator component2 = gameObject2.GetComponent<Animator>();
|
|
FishTarget startFishTarget = GetStartFishTarget(randomFishDataToSpawn.FishData.FishDeepType);
|
|
localAvoidance.Target = startFishTarget.Transform;
|
|
component2.cullingMode = AnimatorCullingMode.CullCompletely;
|
|
fishPhysics.ImportData(randomFishDataToSpawn.FishData, weight2);
|
|
fishEntity.InitializeData(randomFishDataToSpawn.FishData, weight2);
|
|
fishEntity.Player_CurrentPosition = player_CurrentPosition;
|
|
fishEntity.CurrentArea = startFishTarget.Area;
|
|
fishEntity.transform.position = startFishTarget.Transform.position;
|
|
fishEntity.transform.parent = ObjectPool.transform;
|
|
fishEntity.JointAnchor = jointAnchor;
|
|
FishSpawner.OnSpawnFish?.Invoke(fishEntity, arg);
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private FishTarget GetStartFishTarget(FishDeepType deepType)
|
|
{
|
|
FishTarget fishTarget = null;
|
|
fishTarget = deepType switch
|
|
{
|
|
FishDeepType.Overall => FishTargetBaker.GetRandomOverallTarget(),
|
|
FishDeepType.Bottom => FishTargetBaker.GetRandomBottomTarget(),
|
|
FishDeepType.Surface => FishTargetBaker.GetRandomSurfaceTarget(),
|
|
_ => FishTargetBaker.GetRandomOverallTarget(),
|
|
};
|
|
if (fishTarget == null)
|
|
{
|
|
fishTarget = FishTargetBaker.GetRandomOverallTarget();
|
|
}
|
|
if (fishTarget == null)
|
|
{
|
|
fishTarget = FishTargetBaker.GetRandomBottomTarget();
|
|
}
|
|
if (fishTarget == null)
|
|
{
|
|
fishTarget = FishTargetBaker.GetRandomSurfaceTarget();
|
|
}
|
|
return fishTarget;
|
|
}
|
|
}
|
|
}
|