using System.Collections.Generic; using System.Numerics; using UnityEngine; namespace Skill_V2 { [CreateAssetMenu(fileName = "SpawnAttatchBullet", menuName = "ScriptableObject/Skill/SkillSequence/SpawnAttatchBullet")] public class SpawnAttatchBullet : SkillSequence { class BulletElement { public IBattleEntity target; public AttatchBullet bullet; public float prevDamagedTime; } [SerializeField] AttatchBullet attatchBulletPrefab; [SerializeField] int spawnCount; [SerializeField] float damageInterval = 0.5f; [SerializeField] bool resetBulletLifeTimeIfFindNewTarget; List bulletElements; BigInteger skillDmg; public override void Enter() { #if UNITY_EDITOR if (attatchBulletPrefab == null) { Logger.LogError(Owner.gameObject.name + " prefab is null"); IsDone = true; return; } #endif if(bulletElements is null) bulletElements = new List(); var nearestTarget = TargetFinder.GetNears(Owner.transform.position, Owner.TargetTags, spawnCount); for (int i = 0; i < nearestTarget.Count; i++) { BulletElement bulletElm = new BulletElement(); bulletElm.target = nearestTarget[i]; var bullet = Instantiate(attatchBulletPrefab, Owner.Caster.CenterPivot, UnityEngine.Quaternion.identity); bullet.ChangeLookDirection(Owner.LookDirection); bullet.OnAttatching += () => OnAttatching(bulletElm); bullet.OnBeforeDestroy += (bullet) => bulletElements.Remove(bulletElm); bulletElm.bullet = bullet; bullet.Fire((nearestTarget[i] as Entity).CenterPivotTransform); } skillDmg = Owner.GetSkillDamage(); IsDone = true; } public override void Stop() { for (int i = 0; i < bulletElements.Count; i++) { var targetObj = bulletElements[i]; Destroy(targetObj.bullet.gameObject); } bulletElements.Clear(); } private void OnAttatching(BulletElement bulletElm) { if (!bulletElm.target.IsBattleAvail()) { if (TargetFinder.TryFindNearest(bulletElm.bullet.CenterPivot, Owner.TargetTags, out var target, GetTargets())) { bulletElm.target = target; bulletElm.bullet.Fire((target as Entity).transform, resetBulletLifeTimeIfFindNewTarget); } else { bulletElements.Remove(bulletElm); Destroy(bulletElm.bullet.gameObject); } } else if(Time.time - bulletElm.prevDamagedTime > damageInterval) { bulletElm.prevDamagedTime = Time.time; BattleMgr.Instance.SendDamage(bulletElm.target, skillDmg, 0, 0); } } private HashSet GetTargets() { var targets = new HashSet(); for (int i = 0; i < bulletElements.Count; i++) { targets.Add(bulletElements[i].target); } return targets; } } }