Files
MRFishingMaster/Assets/_FishingMaster/Scripts/Fish/Base/Fish.cs

302 lines
7.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}