Files
FutureMen2/Assets/_FutureMen2/Scripts/Actions/OctopusActions.cs

339 lines
8.3 KiB
C#
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.Collections;
using System.Collections.Generic;
using BehaviorDesigner.Runtime.Tasks;
using DragonLi.Core;
using UnityEngine;
public class OctopusTentacleAtk : Action
{
public int attackCount;
private OctopusBoss boss;
private bool isFinished;
public override void OnStart()
{
boss = GetComponent<OctopusBoss>();
isFinished = false;
boss.ResetSkill1();
StartCoroutine(Attack());
}
public override TaskStatus OnUpdate()
{
return isFinished ? TaskStatus.Success : TaskStatus.Running;
}
IEnumerator Attack()
{
var list = boss.GetAliveTentacles();
list.Shuffle();
if (list.Count == 0)
{
isFinished = true;
yield break;
}
// 🔥 狂暴4 条一起
if (attackCount == 4)
{
int index = 0;
while (index < list.Count)
{
int count = Mathf.Min(4, list.Count - index);
yield return AttackGroup(list, index, count, true);
if (boss.isDead)
yield break;
index += count;
}
}
// 🔹 普通2 条一组
else
{
int index = 0;
while (index < list.Count)
{
int count = Mathf.Min(2, list.Count - index);
yield return AttackGroup(list, index, count, false);
if (boss.isDead)
yield break;
index += count;
}
}
isFinished = true;
}
IEnumerator AttackGroup(
List<Tentacle> list,
int startIndex,
int count,
bool isFurious
)
{
List<Coroutine> coroutines = new();
for (int i = 0; i < count; i++)
{
coroutines.Add(
StartCoroutine(list[startIndex + i].Attack(isFurious))
);
}
// ⏳ 等这一组全部攻击完成
foreach (var c in coroutines)
{
if (boss.isDead)
yield break;
yield return c;
}
// 组与组之间稍微停顿(可调)
yield return new WaitForSeconds(0.5f);
}
}
//技能2 吐墨水
public class OctopusSprayAttack : Action
{
private OctopusBoss boss;
private bool isFinished;
private float rotateSpeed = 360f; // 每秒旋转角度
public override void OnStart()
{
boss = GetComponent<OctopusBoss>();
isFinished = false;
boss.ResetSkill2();
StartCoroutine(Spray());
}
public override TaskStatus OnUpdate()
{
return isFinished ? TaskStatus.Success : TaskStatus.Running;
}
IEnumerator Spray()
{
// 1⃣ 显示特效
boss.sprayEx.SetActive(true);
GameManager.Ins.PlaySound3D("1.14",transform,true);
Transform player = GameManager.Ins.player.transform;
// 2⃣ 锁定玩家方向(只转 Y
Vector3 dir = player.position - boss.sprayRoot.position;
dir.y = 0;
Quaternion startRot = Quaternion.LookRotation(dir);
// 3⃣ 决定扫射方向
float sign = Random.value > 0.5f ? 1f : -1f;
Quaternion endRot = startRot * Quaternion.Euler(0, boss.sprayAngle * sign, 0);
boss.sprayRoot.rotation = startRot;
// 4⃣ 扫射
float timer = 0f;
while (timer < boss.sprayDuration&& !boss.isDead)
{
float t = timer / boss.sprayDuration;
boss.sprayRoot.rotation = Quaternion.Slerp(startRot, endRot, t);
timer += Time.deltaTime;
yield return null;
}
// 5⃣ 关闭特效
boss.sprayEx.SetActive(false);
yield return RotateToPlayer();
isFinished = true;
}
IEnumerator RotateToPlayer()
{
Transform player = GameManager.Ins.player.transform;
Vector3 dir = player.position - transform.position;
dir.y = 0;
if (dir.sqrMagnitude < 0.01f)
yield break;
Quaternion targetRot = Quaternion.LookRotation(dir);
while (Quaternion.Angle(transform.rotation, targetRot) > 1f)
{
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
targetRot,
rotateSpeed * Time.deltaTime
);
yield return null;
}
}
}
//技能3 触手突刺
public class OctopusSpikeAttack : Action
{
private OctopusBoss boss;
private bool isFinished;
public override void OnStart()
{
boss = GetComponent<OctopusBoss>();
isFinished = false;
boss.ResetSkill2();
boss.ResetSkill1();
StartCoroutine(Spike());
}
public override TaskStatus OnUpdate()
{
return isFinished ? TaskStatus.Success : TaskStatus.Running;
}
IEnumerator Spike()
{
var list = boss.GetAliveTentacles();
if (list.Count == 0)
{
isFinished = true;
yield break;
}
foreach (var t in list)
t.Hide();
yield return new WaitForSeconds(2f);
float playerDiameter = 0.5f * 2f;
float redCircleDiameter = playerDiameter * 3f;
var points = SpikeAreaGenerator.Generate(
GameManager.Ins.player.transform.position,
list.Count,
2.5f,
5f,
redCircleDiameter
);
for (int i = 0; i < list.Count; i++)
{
GameManager.Ins.CreateEnemySkillTip(points[i].ReflectVectorXOZ(),2.5f);
}
// TODO生成红圈提示
yield return new WaitForSeconds(3f);
GameInit.Ins.PlayAudio("1.16",transform,true);
for (int i = 0; i < list.Count; i++)
{
list[i].Spike(points[i]);
}
yield return new WaitForSeconds(6f);
isFinished = true;
}
}
public class OctopusTeleport : Action
{
private OctopusBoss boss;
private bool isFinished;
[Header("Move Config")]
public float moveDuration = 2f;
public float hideDuration = 0.5f;
private float rotateSpeed = 360f; // 每秒旋转角度
public override void OnStart()
{
boss = GetComponent<OctopusBoss>();
isFinished = false;
boss.ResetTeleport();
StartCoroutine(TeleportMove());
}
public override TaskStatus OnUpdate()
{
return isFinished ? TaskStatus.Success : TaskStatus.Running;
}
IEnumerator TeleportMove()
{
// 1⃣ 触手下沉
var tentacles = boss.GetAliveTentacles();
foreach (var t in tentacles)
t.Hide();
yield return new WaitForSeconds(hideDuration);
// 2⃣ 选目标点
Transform target = boss.teleportPoints[
Random.Range(0, boss.teleportPoints.Length)
];
Vector3 startPos = boss.transform.position;
Vector3 endPos = target.position;
// 3⃣ 朝向目标
Vector3 lookDir = endPos - startPos;
lookDir.y = 0;
if (lookDir.sqrMagnitude > 0.01f)
boss.transform.rotation = Quaternion.LookRotation(lookDir);
// 4⃣ 平滑移动
float timer = 0f;
while (timer < moveDuration)
{
timer += Time.deltaTime;
float t = timer / moveDuration;
boss.transform.position = Vector3.Lerp(startPos, endPos, t);
yield return null;
}
boss.transform.position = endPos;
yield return RotateToPlayer();
// 5⃣ 触手刷新 / 再出现
foreach (var t in tentacles)
t.RefreshToBoss();
isFinished = true;
}
IEnumerator RotateToPlayer()
{
Transform player = GameManager.Ins.player.transform;
Vector3 dir = player.position - transform.position;
dir.y = 0;
if (dir.sqrMagnitude < 0.01f)
yield break;
Quaternion targetRot = Quaternion.LookRotation(dir);
while (Quaternion.Angle(transform.rotation, targetRot) > 1f)
{
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
targetRot,
rotateSpeed * Time.deltaTime
);
yield return null;
}
}
}