using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using Sirenix.OdinInspector; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; /// /// 以撒类,控制以撒Boss /// public class YiSa : Enemy { // _____ _ _ _ // | __ \ | | | (_) // | |__) | _| |__ | |_ ___ // | ___/ | | | '_ \| | |/ __| // | | | |_| | |_) | | | (__ // |_| \__,_|_.__/|_|_|\___| /// /// 攻击用鬼魂的预制体 /// [Header("攻击用鬼魂的预制体")][FoldoutGroup("预制体")] public GameObject goust; /// /// 鬼魂攻击玩家时,生成位置离玩家的距离 /// [Header("鬼魂攻击玩家时,生成位置离玩家的距离")][FoldoutGroup("以撒")] public float atkOffsetDistance; /// /// 疯狂的鬼魂的攻击间隔时间 /// [Header("疯狂的鬼魂的攻击间隔时间")][FoldoutGroup("以撒")] public float crazyGoustTimeBetweenAttacks; /// /// 正常的鬼魂的攻击间隔时间 /// [Header("正常的鬼魂的攻击间隔时间")][FoldoutGroup("以撒")] public float normalGoustTimeBetweenAttacks; /// /// 鬼魂的粒子材质 /// [Header("鬼魂的粒子材质")][FoldoutGroup("材质")] public Material GoustMaterial; /// /// 屏幕后特效组件 /// [Header("屏幕后特效组件")] [FoldoutGroup("材质")] public Volume volume; // _____ _ _ // | __ \ (_) | | // | |__) | __ ___ ____ _| |_ ___ // | ___/ '__| \ \ / / _` | __/ _ \ // | | | | | |\ V / (_| | || __/ // |_| |_| |_| \_/ \__,_|\__\___| /// /// 攻击之间的间隔时间 /// private float timeBetweenAttacks; /// /// 返回类型为协程、参数为空的委托类型 /// private delegate IEnumerator Action(); private MyPlayer player; /// /// 目前是否处于狂暴状态 /// [Header("目前是否处于狂暴状态")][FoldoutGroup("状态")][ReadOnly] private bool isCrazy; /// /// 颜色补正,主要在狂暴系统中更改 /// private Color colorOffset; /// /// 震动动画 /// private Tweener shakeTweener; // _____ _ _ ____ _ // / ____| | | | _ \ | | // | | __ _| | | |_) | __ _ ___| | __ // | | / _` | | | _ < / _` |/ __| |/ / // | |___| (_| | | | |_) | (_| | (__| < // \_____\__,_|_|_|____/ \__,_|\___|_|\_\ void Start(){ Init(); //测试用开启 //InCrazy(); //StartCoroutine(StartAATK()); } // _ _ _ // | \ | | | | // | \| | ___ _ __ _ __ ___ __ _| | // | . ` |/ _ \| '__| '_ ` _ \ / _` | | // | |\ | (_) | | | | | | | | (_| | | // |_| \_|\___/|_| |_| |_| |_|\__,_|_| private void Init(){ //找到必要的物体和组件 player = FindObjectOfType(); //初始化攻击间隔时间 timeBetweenAttacks = normalGoustTimeBetweenAttacks; //初始化颜色补正 colorOffset = Color.white; GoustMaterial.SetColor("Color_",new Color(14,61,255)); //初始化生命值 HPLeft = HP; } /// /// 执行一次攻击 /// public IEnumerator StartAATK(){ //等待攻击间隔 yield return new WaitForSeconds(timeBetweenAttacks); //决定行动 Action action = DecideAAction(); //开始行动 StartCoroutine(action()); } /// /// 决定行动的函数 /// private Action DecideAAction(){ Action action; ///从0、1中随机生成一种 int r = Random.Range(0,2); if(r == 0) action = Rush; else action = Lighting; return action; } private IEnumerator Rush(){ yield return new WaitForEndOfFrame(); Debug.Log("以撒使用了冲撞"); //当以撒使用冲撞时 //首先构建一个生成位置,以玩家为中心,向随机位置偏移固定距离便是 Vector3 appearPos = ( //玩家位置 player.transform.position + //加上定长随机方向偏移量 new Vector3( Random.Range(-1f,1f),Random.Range(-1f,1f),0 ).normalized * atkOffsetDistance ); //在该位置生成一个鬼魂 YiSaGoust t = Instantiate( goust, appearPos, Quaternion.identity ).GetComponent(); //给鬼魂以颜色补正 t.GetComponent().DOColor(colorOffset,2f); //让鬼魂淡出 //Tweener tweener = t.GetComponent().DOFade(1,0.5f); //记录一下本次攻击的冲撞方向 Vector2 rushDir = player.transform.position - t.transform.position; //告知该鬼魂执行冲撞攻击 yield return new WaitForSeconds(1f); t.RushATK(rushDir); //ATKEnd(); } private IEnumerator Lighting(){ Debug.Log("以撒使用了落雷"); //在玩家头顶某位置召唤鬼魂 YiSaGoust t = Instantiate( goust,player.transform.position + new Vector3(0,2f,0),Quaternion.identity ).GetComponent(); yield return new WaitForEndOfFrame(); //给鬼魂以颜色补正 t.GetComponent().DOColor(colorOffset,2f); //激活鬼魂动画 t.animator.SetBool("isLightning",true); //0.5秒淡入显示鬼魂 Tweener tweener = t.GetComponent().DOFade(1,0.5f); //给玩家一秒的反应时间 yield return new WaitForSeconds(1f); t.LightningATK(); //ATKEnd(); } /// /// 攻击结束的时候触发,重新开始新一轮攻击 /// public void ATKEnd(){ if(state == State.atk) StartCoroutine(StartAATK()); } /// /// 进入狂暴状态 /// private void InCrazy(){ //修改特效粒子为红色 GoustMaterial.SetColor("Color_",new Color(255,0,0)); //修改屏幕后特效辉光为红色 StartCoroutine(SetVolumeColor(volume, 0)); //修改标记表示开始狂暴 isCrazy = true; //修改攻击间隔时间 timeBetweenAttacks = crazyGoustTimeBetweenAttacks; //修改鬼魂颜色补正 colorOffset = Color.red; //让石像震动 shakeTweener = transform.DOShakePosition(0.5f,0.1f,50,90,false,false).SetLoops(-1); } /// /// 脱离狂暴装填 /// private void OutCrazy(){ //修改特效粒子为原色 GoustMaterial.SetColor("Color_",new Color(14,61,255)); //修改屏幕后特效辉光为红色 StartCoroutine(SetVolumeColor(volume, 1)); //消除狂暴标记 isCrazy = false; //修改攻击间隔时间 timeBetweenAttacks = normalGoustTimeBetweenAttacks; //修改鬼魂颜色补正 colorOffset = Color.white; //让石像停止震动 shakeTweener.Kill(); } // ______ _ // | ____| | | // | |____ _____ _ __ | |_ // | __\ \ / / _ \ '_ \| __| // | |___\ V / __/ | | | |_ // |______\_/ \___|_| |_|\__| /// /// 当有男童被救的时候从男童触发 /// public void OnSave(Boy boy){ //当有男童被救,触发狂暴 InCrazy(); } public override void OnBeHit(MyPlayer.AtkMethod hitMethod, int hitDir){ //只有狂暴状态会受击 if(isCrazy){ //结算生命值 HPLeft -= MyPlayer.atkMethodMagnification[hitMethod]; //解除狂暴 OutCrazy(); if(CheckDead()) OnDead(); } } public override void OnDead(){ //新建一个以撒灵魂,播放其消亡动画 StartCoroutine(ShowADeadGoust()); //播放自身碎裂动画 GetComponent().SetBool("isDead",true); state = State.dead; FindObjectOfType().GetComponent().enabled = true; //上传玩家进度 FindObjectOfType().rate = (int) MyPlayer.Progress.过基; FindObjectOfType().UpdatePlayerInfo(); } /// /// //新建一个以撒灵魂,播放其消亡动画 /// private IEnumerator ShowADeadGoust(){ //在雕像上方生成一个鬼魂 YiSaGoust t = Instantiate( goust,transform.position + new Vector3(0,2f,0),Quaternion.identity ).GetComponent(); yield return new WaitForEndOfFrame(); //播放鬼魂消亡动画 t.animator.SetBool("isDead",true); t.GetComponent().DOFade(0,0.8f); yield return new WaitForSeconds(1f); Destroy(t.gameObject); } /// /// 修改屏幕后特效 /// private IEnumerator SetVolumeColor(Volume volume,float endValue) { Bloom bloom; volume.profile.TryGet(out bloom); Color color = bloom.tint.value; if (color.g > endValue) { while (color.g>endValue) { yield return new WaitForSeconds(0.05f); color.g -= 0.1f; color.b -= 0.1f; bloom.tint.SetValue(new ColorParameter(color)); } } else { while (color.g