302 lines
7.6 KiB
C#
302 lines
7.6 KiB
C#
using System;
|
||
using DragonLi.Core;
|
||
using FluffyUnderware.Curvy;
|
||
using UnityEngine;
|
||
using FluffyUnderware.Curvy.Controllers;
|
||
using Random = UnityEngine.Random;
|
||
|
||
public enum FishState
|
||
{
|
||
Alive,
|
||
Captured, // 已被捕捉,等待结算
|
||
Removed // 已彻底移除
|
||
}
|
||
|
||
public class Fish : MonoBehaviour
|
||
{
|
||
//public Animator animator;
|
||
public Collider collider;
|
||
public FishData Data { get; private set; }
|
||
|
||
private SplineController controller;
|
||
private bool dead;
|
||
|
||
private FishGroup fishGroup;
|
||
|
||
// 🌟 新增
|
||
private Vector3 localOffset;
|
||
private Transform modelRoot;
|
||
|
||
public FishState state = FishState.Alive;
|
||
private bool unregisterCalled = false;
|
||
|
||
public virtual void Start()
|
||
{
|
||
modelRoot = transform.GetChild(0);
|
||
}
|
||
|
||
public void Init(
|
||
FishData data,
|
||
CurvySpline spline,
|
||
FishGroup curGroup = null,
|
||
Vector3 offset = default)
|
||
{
|
||
Data = data;
|
||
fishGroup = curGroup;
|
||
localOffset = offset;
|
||
// 用一个子节点来偏移(非常关键)
|
||
|
||
if (data.FishId == 11)
|
||
{
|
||
|
||
}
|
||
else
|
||
{
|
||
SetCollider(spline);
|
||
}
|
||
|
||
GameManager.Ins.fishSpawner.RegisterFish(this);
|
||
}
|
||
|
||
public void SetCollider(CurvySpline spline)
|
||
{
|
||
controller = GetComponent<SplineController>();
|
||
if(controller==null)
|
||
return;
|
||
|
||
// 确保控制器已启用(从对象池取出时可能被禁用)
|
||
controller.enabled = true;
|
||
|
||
controller.Spline = spline;
|
||
if (Data.FishId == 12)
|
||
{
|
||
controller.Spline = GameInit.Ins.surroundSpline;
|
||
AngelHouse();
|
||
}
|
||
|
||
controller.Speed = Data.Speed/GameManager.Ins.fishSpawner.fishSpeed;
|
||
controller.Position = 0;
|
||
controller.Play();
|
||
|
||
controller.OnEndReached.AddListener((c) =>
|
||
{
|
||
OnSplineEnd();
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 天使马
|
||
/// </summary>
|
||
public void AngelHouse()
|
||
{
|
||
GameManager.Ins.PlaySound3D("天使马出场",transform);
|
||
}
|
||
|
||
public void Shark()
|
||
{
|
||
|
||
}
|
||
|
||
void LateUpdate()
|
||
{
|
||
if (dead || controller == null || modelRoot == null) return;
|
||
|
||
// 检查 Spline 是否为 null,避免对象池回收时报错
|
||
if (controller.Spline == null) return;
|
||
|
||
// SplineController 已经更新完 transform
|
||
Vector3 right = transform.right;
|
||
Vector3 up = transform.up;
|
||
Vector3 forward = transform.forward;
|
||
|
||
modelRoot.localPosition =
|
||
right * localOffset.x +
|
||
up * localOffset.y +
|
||
forward * (localOffset.z*2f);
|
||
}
|
||
|
||
public void OnHit(float gunLevel)
|
||
{
|
||
if (state != FishState.Alive)
|
||
return;
|
||
|
||
// 🌟 清晰的命中率计算
|
||
float taxRate = 0.05f; // 5% 抽税
|
||
float actualHitRate = gunLevel * (1 - taxRate)/ Data.CoinValue; // 实际命中率(扣除抽税)
|
||
float hitProbability =Data.FishId>=8? actualHitRate * 100f+2.5f:actualHitRate * 100f; // 转换为百分比概率
|
||
|
||
// 🌟 更直观的随机判断
|
||
float randomValue = Random.Range(0f, 100f);
|
||
// 如果随机值大于命中概率,则未命中
|
||
if (randomValue > hitProbability)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 🌟 进入捕捉状态
|
||
state = FishState.Captured;
|
||
|
||
// 停止移动 & 碰撞
|
||
if(controller != null)
|
||
controller.enabled = false;
|
||
if (collider)
|
||
collider.enabled = false;
|
||
|
||
// 从全局容器移除
|
||
SafeUnregister();
|
||
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
SpawnCoinPile();
|
||
if (Data.FishId == 12)
|
||
GameManager.Ins.CreateFireworks(transform.position);
|
||
RemoveInternal();
|
||
}, 1.5f);
|
||
}
|
||
|
||
public void OnSplineEnd()
|
||
{
|
||
if (state != FishState.Alive)
|
||
return;
|
||
|
||
RemoveInternal();
|
||
}
|
||
|
||
void RemoveInternal()
|
||
{
|
||
if (state == FishState.Removed)
|
||
return;
|
||
|
||
state = FishState.Removed;
|
||
|
||
SafeUnregister();
|
||
|
||
transform.parent = null;
|
||
|
||
FishValueLevel level = FishValueHelper.GetValueLevel(Data);
|
||
FishSpawner.Instance.OnHighFishRemoved(level);
|
||
|
||
if (fishGroup != null)
|
||
fishGroup.CheckAllFish();
|
||
if(Data.FishId == 12)
|
||
GameManager.Ins.ClearItem();
|
||
|
||
//Destroy(gameObject);
|
||
// 使用对象池回收,而不是销毁
|
||
Destroy(gameObject);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置对象状态以便回收到对象池
|
||
/// </summary>
|
||
public void ResetForPool()
|
||
{
|
||
// 重置状态
|
||
state = FishState.Alive;
|
||
dead = false;
|
||
unregisterCalled = false;
|
||
fishGroup = null;
|
||
localOffset = Vector3.zero;
|
||
Data = null;
|
||
|
||
// 重置 SplineController - 注意顺序:先禁用,再停止,最后清理
|
||
if (controller != null)
|
||
{
|
||
// 先禁用组件,防止在清理过程中触发更新
|
||
controller.enabled = false;
|
||
|
||
// 移除事件监听,避免回调触发
|
||
controller.OnEndReached.RemoveAllListeners();
|
||
|
||
// 停止控制器
|
||
controller.Stop();
|
||
|
||
// 最后清空 Spline
|
||
controller.Spline = null;
|
||
}
|
||
|
||
// 重置碰撞器
|
||
if (collider != null)
|
||
{
|
||
collider.enabled = true;
|
||
}
|
||
|
||
// 重置模型位置
|
||
if (modelRoot != null)
|
||
{
|
||
modelRoot.localPosition = Vector3.zero;
|
||
}
|
||
}
|
||
|
||
void SafeUnregister()
|
||
{
|
||
if (unregisterCalled)
|
||
return;
|
||
|
||
unregisterCalled = true;
|
||
GameManager.Ins.fishSpawner.UnregisterFish(this);
|
||
}
|
||
|
||
void SpawnCoinPile()
|
||
{
|
||
FishValueLevel level = FishValueHelper.GetValueLevel(Data);
|
||
|
||
float mul = CoinMultiplier.GetMultiplier(level);
|
||
|
||
int baseCoin = Data.CoinCount;
|
||
|
||
// 🌟 轻微随机
|
||
float random = Random.Range(0.9f, 1.1f);
|
||
|
||
int finalCoin = Mathf.RoundToInt(baseCoin * mul * random);
|
||
|
||
GameObject pileGO = Instantiate(
|
||
GameManager.Ins.coinPilePre,
|
||
modelRoot.transform.position,
|
||
Quaternion.identity
|
||
);
|
||
|
||
pileGO.GetComponent<CoinPileController>()
|
||
.Init(
|
||
GameInit.Ins.self.RightHand,
|
||
Data.CoinCount
|
||
);
|
||
GameInit.Ins.self.AddScore(Data.CoinValue);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 调整鱼的游速
|
||
/// </summary>
|
||
public void SetSpeed()
|
||
{
|
||
if(state!= FishState.Alive)
|
||
return;
|
||
// 检查 controller 和 Spline 是否有效
|
||
if(controller != null && controller.Spline != null && Data != null)
|
||
controller.Speed = Data.Speed/GameManager.Ins.fishSpawner.fishSpeed;
|
||
}
|
||
|
||
public void DieFish()
|
||
{
|
||
if(state != FishState.Alive)
|
||
return;
|
||
// 🌟 进入捕捉状态
|
||
state = FishState.Captured;
|
||
|
||
// 停止移动 & 碰撞
|
||
if(controller!=null)
|
||
controller.enabled = false;
|
||
if (collider)
|
||
collider.enabled = false;
|
||
|
||
// 从全局容器移除(此时已经不参与任何逻辑)
|
||
SafeUnregister();
|
||
|
||
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
|
||
{
|
||
SpawnCoinPile();
|
||
RemoveInternal();
|
||
}, 1.5f);
|
||
}
|
||
}
|