Files
AliceBall/Assets/_Alice/Scripts/Enemy/Enemy.cs

338 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
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;
using System.Collections;
using System.Collections.Generic;
using BehaviorDesigner.Runtime;
using DG.Tweening;
using DragonLi.Core;
using UnityEngine;
using UnityEngine.UI;
public enum EnemyState
{
Show,
Ide,
}
public class Enemy : MonoBehaviour
{
public Animator animator;
public int state;
public BehaviorTree tree;
public GameObject playerPre;
public GameObject dieExPre;
public GameObject boxPre;
public GameObject[] gems;
public GameObject leaveEffect;
public GameObject hpObj;
public Transform hand;
public Transform body;
public GameObject[] box;
public Image[] hpImage;
public bool isHit;
public bool isDie;
public bool isTimeHit;
public float timeHit;
public float curTimeHit;
public int maxHp;
public int hp;
public void Init()
{
maxHp = 20; // 血量改为40
timeHit = 10;
curTimeHit = 10;
hp = maxHp;
isDie = false;
isHit = false;
isTimeHit = true;
curTimeHit = timeHit; // 重置计时器
playerPre.SetActive(true);
tree.RegisterEvent("DownGem",ShowBox);
tree.RegisterEvent("ShowBox",ShowAllBox);
tree.RegisterEvent("EnemyAttack",PlayAttack);
tree.RegisterEvent("ShowHpUI",ShowHpUI);
hpObj.SetActive(false);
dieExPre.SetActive(false);
foreach (var item in gems)
{
item.SetActive(false);
}
foreach (var item in box)
{
item.SetActive(false);
}
boxPre.transform.localPosition=Vector3.zero;
}
public void Show()
{
ShowLeaveEx();
playerPre.SetActive(true);
}
public void SetState(int curState)
{
state = curState;
}
public void ShowAllBox()
{
boxPre.transform.localPosition=Vector3.zero;
foreach (var item in box)
{
item.SetActive(false);
}
animator.SetTrigger("showBox");
int curTaskId = GameManager.Ins.taskManager.curTaskId;
switch (curTaskId)
{
case 0:
boxPre.transform.DOLocalMoveX(-0.9f,0.5f);
break;
case 1:
break;
case 2:
boxPre.transform.DOLocalMoveX(0.9f,0.5f);
break;
}
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
for (int i = 0; i < box.Length; i++)
{
box[i].SetActive(i>=GameManager.Ins.taskManager.curTaskId);
}
},2);
}
public void ShowBox()
{
int curTaskId = GameManager.Ins.taskManager.curTaskId;
// 添加边界检查
if (curTaskId < 0 || curTaskId >= gems.Length)
{
Debug.LogError($"ShowBox: curTaskId {curTaskId} 超出范围 [0-{gems.Length - 1}]");
return;
}
gems[curTaskId].SetActive(true);
animator.SetTrigger("showBox");
// 添加box数组的边界检查
if (curTaskId >= 0 && curTaskId < box.Length)
{
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
box[curTaskId].GetComponent<Animator>().SetBool("isOpen", true);
}, 2);
}
else
{
Debug.LogError($"ShowBox: curTaskId {curTaskId} 超出box数组范围 [0-{box.Length - 1}]");
}
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
DownGem();
}, 5);
}
public void ShowHpUI()
{
hpObj.SetActive(true);
UpdateHpUI();
}
public void DownGem()
{
int curTaskId = GameManager.Ins.taskManager.curTaskId;
animator.SetTrigger("downGem");
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
gems[curTaskId].SetActive(false);
},1f);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
box[curTaskId].GetComponent<Animator>().SetBool("isOpen",false);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
GameManager.Ins.taskManager.CreateBox(box[curTaskId].transform.position,box[curTaskId].transform.eulerAngles,curTaskId,TaskBoxType.TaskStartBox);
Leave();
},1f);
},2f);
}
public void Leave()
{
playerPre.SetActive(false);
foreach (var item in box)
{
item.SetActive(false);
}
ShowLeaveEx();
GameManager.Ins.PlaySound3DRPC("1.26", transform);
// 添加延迟,确保任务状态稳定后再开始新任务
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
// 再次检查当前任务索引是否有效
if (GameManager.Ins.taskManager.curTaskId < GameManager.Ins.taskManager.tasks.Count)
{
GameManager.Ins.taskManager.StartTask();
}
else
{
Debug.Log("所有任务已完成,不再开始新任务");
}
}, 0.5f); // 添加0.5秒延迟
}
public void ShowLeaveEx()
{
leaveEffect.SetActive(true);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
leaveEffect.SetActive(false);
},2f);
}
private void Update()
{
// 平滑朝向玩家
Vector3 targetDir = GameLocal.Ins.self.transform.position - transform.position;
targetDir.y = 0f;
if (targetDir != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(targetDir);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2f);
}
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if (state == 4 && hp > 0 && isTimeHit && !isDie && !isHit)
{
// 确保计时器不会变成负值
if (curTimeHit > 0)
{
curTimeHit -= Time.deltaTime;
}
if (curTimeHit <= 0 && !isHit && !isDie)
{
curTimeHit = timeHit;
ChangeHp();
}
}
}, 60);
}
public void PlayAttack()
{
animator.SetTrigger("Attack");
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if(isHit)
return;
GameManager.Ins.CreateEggBullet(hand.position);
},1);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if(isHit)
return;
GameManager.Ins.CreateEggBullet(hand.position);
},2);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if(isHit)
return;
GameManager.Ins.CreateEggBullet(hand.position);
},3);
}
public void Hit()
{
isHit = true;
animator.SetTrigger("hit");
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
isHit = false;
},2);
ChangeHp();
}
public void ChangeHp()
{
hp = Mathf.Max(hp - 1, 0);
UpdateHpUI();
if(hp <= 0)
Die();
}
private void UpdateHpUI()
{
// 计算整格每格4血和是否还有余数
int fullCount = hp / 2; // 每格4血
int remainder = hp % 2; // 余数
for (int i = 0; i < hpImage.Length; i++)
{
if (i < fullCount)
{
// 整格
hpImage[i].enabled = true;
hpImage[i].fillAmount = 1f;
}
else if (i == fullCount && remainder > 0)
{
// 部分填充(根据余数计算填充量)
hpImage[i].enabled = true;
hpImage[i].fillAmount = remainder / 2f; // 余数/4得到填充比例
}
else
{
// 隐藏或空格
hpImage[i].enabled = false;
}
}
}
public void Die()
{
if (isDie)
{
return;
}
isDie = true;
animator.SetTrigger("die");
GameManager.Ins.PlaySound3DRPC("1.49",transform,true);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
animator.gameObject.SetActive(false);
hpObj.SetActive(false);
dieExPre.SetActive(true);
},1.5f);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
dieExPre.SetActive(false);
},4.5f);
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
GameManager.Ins.StartGameEnd();
},3f);
}
}