250 lines
6.0 KiB
C#
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);
|
|
}
|
|
}
|