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

198 lines
6.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using DragonLi.Core;
using UnityEngine;
public class SharkFish : Fish
{
[Header("鲨鱼设置")]
[NonSerialized]
public float patrolRadius = 8f; // 巡逻半径
[NonSerialized]
public float patrolSpeed = 0.5f; // 巡逻速度
[NonSerialized]
public float attackSpeed = 4f; // 攻击速度
[NonSerialized]
public float attackInterval = 10f; // 攻击间隔
[Header("攻击设置")]
public float attackDistance = 1.5f; // 攻击距离
public float retreatDistance = 5f; // 撤退距离
public Animator animator;
private Transform player;
private SharkState currentState;
private float attackTimer;
private int showTime;
private float curShowTime;
private Vector3 circleCenter;
// 鲨鱼状态枚举
private enum SharkState
{
Patrolling, // 圆形巡逻
Attacking, // 攻击玩家
Retreating // 撤退
}
public override void Start()
{
base.Start();
player = GameManager.Ins.player.transform;
currentState = SharkState.Patrolling;
// 攻击间隔改为20-30秒随机
attackInterval = UnityEngine.Random.Range(20f, 30f);
attackTimer = attackInterval;
circleCenter = player.position;
showTime = 60;
StartCoroutine(SharkAI());
}
IEnumerator SharkAI()
{
// 鲨鱼存活且显示时间未到1分钟时继续循环
while (curShowTime <= showTime && state == FishState.Alive)
{
switch (currentState)
{
case SharkState.Patrolling:
animator.SetInteger("state",0);
yield return StartCoroutine(PatrolBehavior());
break;
case SharkState.Attacking:
animator.SetInteger("state",1);
yield return StartCoroutine(AttackBehavior());
break;
case SharkState.Retreating:
animator.SetInteger("state",0);
yield return StartCoroutine(RetreatBehavior());
break;
}
curShowTime += Time.deltaTime;
yield return new WaitForEndOfFrame(); // 关键:等待一帧
}
OnSplineEnd();
}
// 圆形巡逻行为
IEnumerator PatrolBehavior()
{
float angle = 0f;
while (attackTimer > 0 && currentState == SharkState.Patrolling)
{
attackTimer -= Time.deltaTime;
// 更新圆形中心点为玩家当前位置
circleCenter = player.position;
// 圆形运动
angle += patrolSpeed * Time.deltaTime;
Vector3 targetPosition = circleCenter + new Vector3(
Mathf.Cos(angle) * patrolRadius,
0,
Mathf.Sin(angle) * patrolRadius
);
// 计算移动方向(前进方向)
Vector3 moveDirection = (targetPosition - transform.position).normalized;
// 如果移动方向不为零,让鲨鱼面向前进方向
if (moveDirection != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 5f * Time.deltaTime);
}
// 平滑移动到目标位置
transform.position = Vector3.Lerp(transform.position, targetPosition, 2f * Time.deltaTime);
yield return null;
}
if (attackTimer <= 0)
{
currentState = SharkState.Attacking;
// 重置计时器为20-30秒随机
attackInterval = UnityEngine.Random.Range(20f, 30f);
attackTimer = attackInterval;
}
}
// 攻击行为
IEnumerator AttackBehavior()
{
Vector3 attackDirection = (player.position - transform.position).normalized;
float attackStartTime = Time.time;
float maxAttackDuration = 3f;
while (currentState == SharkState.Attacking)
{
// 朝向玩家
transform.rotation = Quaternion.LookRotation(attackDirection);
// 冲向玩家
transform.position += attackDirection * attackSpeed * Time.deltaTime;
GameManager.Ins.PlaySound3D("鲨鱼袭击",transform,true);
// 检查是否到达攻击距离
float distanceToPlayer = Vector3.Distance(transform.position, player.position);
if (distanceToPlayer <= attackDistance)
{
// 攻击玩家
AttackPlayer();
currentState = SharkState.Retreating;
break;
}
// 防止攻击时间过长
if (Time.time - attackStartTime > maxAttackDuration)
{
currentState = SharkState.Retreating;
break;
}
yield return null;
}
}
// 撤退行为
IEnumerator RetreatBehavior()
{
Vector3 retreatDirection = (transform.position - player.position).normalized;
float retreatStartTime = Time.time;
float retreatDuration = 2f;
while (Time.time - retreatStartTime < retreatDuration && currentState == SharkState.Retreating)
{
// 远离玩家撤退
transform.position += retreatDirection * patrolSpeed * Time.deltaTime;
yield return null;
}
// 回到巡逻状态
currentState = SharkState.Patrolling;
}
// 攻击玩家
void AttackPlayer()
{
// 触发屏幕特效
EventDispatcher.TriggerEvent("PlayerHit",0);
}
void OnDrawGizmosSelected()
{
// 绘制巡逻范围
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(circleCenter, patrolRadius);
// 绘制攻击距离
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, attackDistance);
}
}