Files
MinFt/Client/Assets/Scripts/Aquarium/FishManager.cs
2026-04-27 12:07:32 +08:00

223 lines
7.7 KiB
C#

using asap.core;
using cfg;
using System;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.Rendering.DebugUI;
using Random = UnityEngine.Random;
public class FishManager : MonoBehaviour
{
[SerializeField] private GameObject fishPrefab;
public Vector3 tankSize;
private Vector3 _tankCenter = Vector3.zero;
public Vector3 tankCenter => _tankCenter;
[Header("Fish Parameters")]
public float avoidRadius;
public float alignRadius;
public float obstacleDetectionRadius;
public float avoidance, alignment, cohesion, trigger, obstacle, areaConstrain, maxVel, minVel, angularAcc, magnitudeAcc, dvLerp;
public float zMoveRatio = 0.4f;
private Vector3 HalfSize => tankSize / 2;
public Dictionary<int, GameObject> fishUnDownloadAlter;
Dictionary<int, List<FishMovement>> _fishGroups = new Dictionary<int, List<FishMovement>>();
[NonSerialized]
public List<FishMovement> allFish = new List<FishMovement>();
[NonSerialized]
public List<GameObject> obstacleGo = new List<GameObject>();
public float MaxLoadTime { set; get; } = 50;
private void Start()
{
_tankCenter = transform.position;
fishPrefab.gameObject.SetActive(false);
}
/// <summary>
/// 初始鱼群
/// </summary>
/// <param name="mutantMaterial"> 是否变异 变异材质 </param>
/// <param name="fishItemID">鱼的item ID</param>
/// <param name="count">鱼当前剩余的数量</param>
/// <param name="groupId">鱼群分组</param>
///
public void AddFish(Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye,
AquariumSlotData slotData, int count, int groupId)
{
if (_fishGroups.ContainsKey(groupId))
{
return;
}
var fishGroup = new List<FishMovement>();
_fishGroups[groupId] = fishGroup;
Tables tables = GContext.container.Resolve<Tables>();
Item item = tables.TbItem.GetOrDefault(slotData.fishItemID);
var fishData = tables.TbFishData.GetOrDefault(item.RedirectID);
float startSizeZ = (slotData.aquariumFishID - 1) * zMoveRatio * tankSize.z;
var position = GetRandomPositionAndRotation(startSizeZ);
var rot = Random.rotation;
for (int i = 0; i < count; i++)
{
var go = Instantiate(fishPrefab, position + Random.onUnitSphere, rot, transform);
go.SetActive(true);
go.name = $"fish{groupId}_{i}";
var movement = go.GetComponent<FishMovement>();
movement.index = i;
movement.groupId = groupId;
float mutantScale = 1;
if (i < slotData.mutants)
{
mutantScale = tables.TbFishMutant.AquariumScale[fishData.Quality - 1];
}
go.transform.localScale = Vector3.one * fishData.AquariumMinScale * mutantScale;
movement.Init(this, slotData, startSizeZ, fishData, mutantScale);
fishGroup.Add(movement);
allFish.Add(movement);
}
LoadFish(fishGroup, mutantMaterial, fxLeftEye, fxRightEye);
}
public void AddFish(Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye,
AquariumSlotData slotData,string cardLv, int count, int groupId, int huntResult, int dropID)
{
if (_fishGroups.ContainsKey(groupId))
{
return;
}
AddFish(mutantMaterial, fxLeftEye, fxRightEye,
slotData, count, groupId);
var fishGroup = _fishGroups[groupId];
Tables tables = GContext.container.Resolve<Tables>();
AquariumFish aquariumFish = tables.TbAquariumFish.GetOrDefault(slotData.aquariumFishID);
for (int i = 0; i < fishGroup.Count; i++)
{
fishGroup[i].SetReward(aquariumFish, cardLv, huntResult, dropID);
}
}
async void LoadFish(List<FishMovement> fishMovements, Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye)
{
for (int i = 0; i < fishMovements.Count; i++)
{
if (fishMovements[i] == null || fishMovements[i].isResult)
{
return;
}
await fishMovements[i].LoadFish(mutantMaterial, fxLeftEye, fxRightEye);
}
}
private Vector3 GetRandomPositionAndRotation(float startSizeZ)
{
var HalfSize = tankSize / 2;
var pos = new Vector3(
x: UnityEngine.Random.Range(-HalfSize.x, HalfSize.x),
y: UnityEngine.Random.Range(-HalfSize.y, HalfSize.y) / 2,
z: UnityEngine.Random.Range(-HalfSize.z, HalfSize.z));
pos += tankCenter;
pos.z += startSizeZ;
return pos;
}
public void RemoveFish(int groupId)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return;
}
if (fishGroup.Count > 0)
{
for (int i = 0; i < fishGroup.Count; i++)
{
Destroy(fishGroup[i].gameObject);
allFish.Remove(fishGroup[i]);
}
}
_fishGroups.Remove(groupId);
}
public void SetFishScale(int groupId, float scale, int mutants, float aquariumScale)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return;
}
if (fishGroup.Count > 0)
{
for (int i = 0; i < fishGroup.Count; i++)
{
if (i < mutants)
{
fishGroup[i].transform.localScale = Vector3.one * scale * aquariumScale;
}
else
{
fishGroup[i].transform.localScale = Vector3.one * scale;
}
}
}
}
public FishMovement GetFish(int groupId)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return null;
}
if (fishGroup.Count > 0)
{
return fishGroup[0];
}
return null;
}
public void AllEscape()
{
for (int i = 0; i < allFish.Count; i++)
{
allFish[i].AllEscape();
}
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
_tankCenter = transform.position;
Gizmos.color = Color.cyan;
// Gizmos.DrawCube(_tankCenter, tankSize);
var halfSize = tankSize / 2;
// Define the 8 vertices of the cube
var vertices = new Vector3[8]
{
_tankCenter + new Vector3(-halfSize.x, -halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, -halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, -halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, -halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, halfSize.y, halfSize.z)
};
// Draw bottom square
Gizmos.DrawLine(vertices[0], vertices[1]);
Gizmos.DrawLine(vertices[1], vertices[2]);
Gizmos.DrawLine(vertices[2], vertices[3]);
Gizmos.DrawLine(vertices[3], vertices[0]);
// Draw top square
Gizmos.DrawLine(vertices[4], vertices[5]);
Gizmos.DrawLine(vertices[5], vertices[6]);
Gizmos.DrawLine(vertices[6], vertices[7]);
Gizmos.DrawLine(vertices[7], vertices[4]);
// Draw vertical edges
Gizmos.DrawLine(vertices[0], vertices[4]);
Gizmos.DrawLine(vertices[1], vertices[5]);
Gizmos.DrawLine(vertices[2], vertices[6]);
Gizmos.DrawLine(vertices[3], vertices[7]);
}
#endif
}