335 lines
8.8 KiB
C#
335 lines
8.8 KiB
C#
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 = 30; // 血量改为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);
|
||
}
|
||
|
||
if (state == 4 && hp > 0 && isTimeHit && !isDie&& !isHit)
|
||
{
|
||
|
||
// 确保计时器不会变成负值
|
||
if (curTimeHit > 0)
|
||
{
|
||
curTimeHit -= Time.deltaTime;
|
||
}
|
||
|
||
if (curTimeHit <= 0 && !isHit && !isDie)
|
||
{
|
||
curTimeHit = timeHit;
|
||
ChangeHp();
|
||
}
|
||
}
|
||
}
|
||
|
||
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 / 3; // 每格4血
|
||
int remainder = hp % 3; // 余数
|
||
|
||
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 / 3f; // 余数/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);
|
||
}
|
||
} |