Files
MRFishingMaster/Assets/_FishingMaster/Scripts/Fish/Base/Fish.cs
2026-02-14 16:48:33 +08:00

250 lines
6.0 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;
private 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.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;
// 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)
{
Debug.Log("未命中!");
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);
}
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;
if(controller!=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);
}
}