Files
FutureMen2/Assets/_FutureMen2/Scripts/Enemy/OctopusBoss/Tentacle.cs
2026-01-29 17:34:43 +08:00

311 lines
8.4 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.
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using DragonLi.Core;
using UnityEngine;
public class Tentacle : Enemy
{
public float upIndex;
private float downIndex=-7;
public GameObject model;
public GameObject atkEx;
public Animator animator;
public EnemyBoneHit[] skill1BoneHits;
public EnemyBoneHit[] skill1ExBoneHits;
public EnemyBoneHit[] skill2BoneHits;
private Vector3 _startPos;
private bool isAttacking;
private Quaternion _originRot;
private float rotateSpeed = 180f; // 每秒旋转角度
private void Start()
{
_startPos = transform.position;
atkEx.SetActive(false);
foreach (var item in skill1BoneHits)
{
item.gameObject.SetActive(false);
}
foreach (var item in skill2BoneHits)
{
item.gameObject.SetActive(false);
}
foreach (var item in skill1ExBoneHits)
{
item.gameObject.SetActive(false);
}
bloodSlider.gameObject.SetActive(false);
skill1ExBoneHits[0].transform.localScale=new Vector3(skill1ExBoneHits[0].transform.localScale.x, 10, skill1ExBoneHits[0].transform.localScale.z);
skill1ExBoneHits[0].transform.localPosition=new Vector3(skill1ExBoneHits[0].transform.localPosition.x,0, 10);
}
public override void SetData(EnemyData data)
{
base.SetData(data);
enemyState = EnemyState.Show;
health = Data.Hp_CS1;
maxHealth = Data.Hp_CS1;
bloodSlider.SetName("巨妖触手");
isDead = false;
isShowEnd = false;
}
public override void EndShow()
{
enemyState = EnemyState.Idle;
bloodSlider.gameObject.SetActive(true);
}
void PlayIdle()
{
if(isDead)
return;
animator.SetInteger("state",0);
enemyState = EnemyState.Idle;
GameManager.Ins.PlaySound3D("1.18",transform);
}
public IEnumerator Attack(bool isFurious)
{
if (isAttacking||isDead)
yield break;
isAttacking = true;
// ⭐ 记录初始朝向
_originRot = transform.rotation;
GameManager.Ins.PlaySound3D("1.8",transform);
// 0⃣ 攻击前转向玩家
yield return RotateToPlayer();
// 1⃣ 前摇
yield return new WaitForSeconds(0.8f);
// 2⃣ 播放攻击动画
animator.SetInteger("state",1);
BeginAttack();
enemyState = EnemyState.NormalAttack;
yield return new WaitForSeconds(1.72f);
GameManager.Ins.PlaySound3D("1.9",transform,true);
// 4⃣ 攻击判定 / 特效
DoAttackHit(isFurious);
// 5⃣ 等动画播完
yield return new WaitForSeconds(3.2f);
// ⭐ 攻击结束后转回
//yield return RotateBack();
// 6⃣ 切回 Idle
PlayIdle();
EndAttack();
isAttacking = false;
}
int GetCurrentFrame(int layer = 0)
{
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(layer);
AnimatorClipInfo[] clipInfos = animator.GetCurrentAnimatorClipInfo(layer);
if (clipInfos.Length == 0)
return 0;
AnimationClip clip = clipInfos[0].clip;
float normalizedTime = stateInfo.normalizedTime % 1f; // 防止循环动画溢出
float currentTime = normalizedTime * clip.length;
int currentFrame = Mathf.FloorToInt(currentTime * clip.frameRate);
return currentFrame;
}
float GetCurrentClipLength(int layer = 0)
{
AnimatorClipInfo[] clipInfos = animator.GetCurrentAnimatorClipInfo(layer);
if (clipInfos.Length == 0)
return 0f;
return clipInfos[0].clip.length;
}
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;
}
}
IEnumerator RotateBack()
{
while (Quaternion.Angle(transform.rotation, _originRot) > 1f)
{
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
_originRot,
rotateSpeed * Time.deltaTime
);
yield return null;
}
}
public override void EndAttack()
{
base.EndAttack();
foreach (var item in skill1BoneHits)
{
item.gameObject.SetActive(false);
}
foreach (var item in skill1ExBoneHits)
{
item.gameObject.SetActive(true);
}
}
void DoAttackHit(bool isFurious)
{
// 开启攻击特效
atkEx.SetActive(true);
enemyState = EnemyState.SpikeAttack;
foreach (var item in skill1BoneHits)
{
item.gameObject.SetActive(true);
item.SetDamage(isFurious? Data.Atk_1B: Data.Atk_1P);
}
foreach (var item in skill1ExBoneHits)
{
item.gameObject.SetActive(true);
item.SetDamage(isFurious? Data.Atk_1B: Data.Atk_1P);
}
// 一小段时间后关闭特效
StartCoroutine(HideAtkEx());
}
IEnumerator HideAtkEx()
{
yield return new WaitForSeconds(1f);
atkEx.SetActive(false);
}
public void Hide()
{
GameManager.Ins.PlaySound3D("1.15",transform,true);
bloodSlider.gameObject.SetActive(false);
model.transform.DOMoveY(downIndex, 1f).OnComplete(() =>
{
model.SetActive(false);
});
}
public override void Hit()
{
if(enemyState!= EnemyState.Idle)
return;
animator.SetTrigger("hit");
}
public void Spike(Vector3 pos)
{
model.SetActive(true);
model.transform.position = new Vector3(pos.x, downIndex, pos.z);
animator.SetInteger("state",2);
BeginAttack();
foreach (var item in skill2BoneHits)
{
item.SetDamage(Data.Atk_3);
}
model.transform.DOMoveY(upIndex,1).SetEase(Ease.OutBounce).OnComplete(() =>
{
CoroutineTaskManager.Instance.WaitSecondTodo(() =>
{
if(isDead)
return;
EndAttack();
model.transform.DOMoveY(downIndex,1).SetEase(Ease.OutBounce).OnComplete(() =>
{
transform.position=new Vector3(_startPos.x,downIndex,_startPos.z);
model.transform.localPosition=Vector3.zero;
PlayIdle();
transform.DOMoveY(upIndex,1).SetEase(Ease.OutBounce);
});
}, 3f);
});
}
public void RefreshToBoss()
{
if(isDead)
return;
_startPos=transform.position;
model.SetActive(true);
model.transform.DOLocalMoveY(upIndex, 1).OnComplete(() =>
{
bloodSlider.gameObject.SetActive(true);
});
}
public override void ChangeHp(float value, object info, Transform _sender)
{
if(enemyState== EnemyState.Show)
return;
base.ChangeHp(value, info, _sender);
if(isDead)
return;
GameManager.Ins.PlaySound3D("1.10",transform);
}
public override void Dead()
{
base.Dead();
health = 0;
animator.SetBool("isDie",true);
GameManager.Ins.PlaySound3D("1.11",transform,true);
transform.parent = null;
StopAllCoroutines();
}
public override void Update()
{
base.Update();
Transform player = GameManager.Ins.player.transform;
if (!player) return;
Vector3 dir = player.position - transform.position;
dir.y = 0;
if (dir.sqrMagnitude < 0.0001f)
return;
Quaternion targetRot = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.RotateTowards(
transform.rotation,
targetRot,
rotateSpeed * Time.deltaTime
);
}
}