public override void MonoTriggerEnter(GameObject gameObject, Collider2D coll) { if (coll.gameObject.Equals(GetOwnerData().GetBody())) { return; } Character ch = coll.gameObject.GetChar(); ProjectileData d = GetProjectileData(gameObject); // if projectile was saved, it means special effects are to be applied if (d != null) { if (ch == null) { Destroyable des = coll.gameObject.GetComponent <Destroyable>(); if (des == null) { ForceDestroyProjectile(d.proj); return; } if (!Owner.CanAttack(des)) { return; } } else if (!Owner.CanAttack(ch)) { return; } // missile hit target if (d.target != null) { if (coll.gameObject.Equals(d.target.GetData().GetBody())) { d.target = null; } } if (d.ignore != null && d.ignore.Equals(coll.gameObject)) { return; } if (chainEffect && !d.chained) { for (int i = 0; i < chainProjectilesCount; i++) { GameObject activeProjectile; activeProjectile = CreateSkillProjectile("projectile_00", true, d.proj.transform); if (activeProjectile != null) { Rigidbody2D rb = activeProjectile.GetComponent <Rigidbody2D>(); Vector3 nv = Quaternion.Euler(new Vector3(0, 0, Random.Range(-90, 90))) * d.rb.velocity.normalized; rb.velocity = nv * force; Object.Destroy(activeProjectile, GetProjectileLifetime(force)); if (SaveProjectiles()) { ProjectileData data = new ProjectileData(); data.proj = activeProjectile; data.target = null; data.interpolTimer = 0; data.rb = rb; data.penetratedTargets = 0; data.maxPenetrateTargets = chainPenetrations + 1; data.chained = true; data.ignore = coll.gameObject; if (chainPenetrations > 0) { data.hits = new GameObject[chainPenetrations + 1]; } if (returnBack) { data.waypoints.Push(activeProjectile.transform.position); } data.SaveHit(coll.gameObject); data.penetratedTargets++; projectiles.Add(data); MonoUpdate(rb.gameObject, true); } } } } if (d.maxPenetrateTargets > 0 && d.penetratedTargets > 0 && (penetrateChangeDamage < 0 || penetrateChangeDamage > 0)) { ApplyEffects(Owner, coll.gameObject, false, d.penetratedTargets); } else { ApplyEffects(Owner, coll.gameObject); } bool destroy = false; if (maxPenetratedTargets > 0 && d.maxPenetrateTargets > 0) { // check if penetrated too many d.penetratedTargets++; if (d.penetratedTargets >= d.maxPenetrateTargets) { destroy = true; } // find next target if (!destroy && navigateChangeTargetAfterHit) { ProjectileHitAnimation(d.proj); float angle = d.proj.transform.rotation.eulerAngles.z; if (!navigateLookOnlyForward) { /*foreach (Collider2D hit in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea)) * { * if (hit.gameObject.Equals(d.proj)) * continue; * * Character targetCh = hit.gameObject.GetChar(); * if (targetCh == null || !Owner.CanAttack(targetCh) || hit.gameObject.Equals(coll.gameObject)) * continue; * * d.target = targetCh; * AdjustToTarget(d); * break; * }*/ List <GameObject> candidates = new List <GameObject>(); foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea)) { if (c.gameObject.Equals(d.proj)) { continue; } if (d.HasHit(c.gameObject)) { continue; } if (!Utils.CanSee(c.gameObject, d.proj.transform.position)) { continue; } Character targetCh = c.gameObject.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } candidates.Add(c.gameObject); } candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position)); foreach (GameObject c in candidates) { Character targetCh = c.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } d.target = targetCh; d.SaveHit(c.gameObject); AdjustToTarget(d); break; } } else { Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y); Vector3 perpend = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position); List <GameObject> candidates = new List <GameObject>(); foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f))) { if (c.gameObject.Equals(d.proj)) { continue; } if (d.HasHit(c.gameObject)) { continue; } if (!Utils.CanSee(c.gameObject, d.proj.transform.position)) { continue; } candidates.Add(c.gameObject); break; } candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position)); foreach (GameObject c in candidates) { Character targetCh = c.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } d.target = targetCh; d.SaveHit(c.gameObject); AdjustToTarget(d); break; } } } } if (maxPenetratedTargets == 0 || destroy) { if (returnBack) { returningBack = true; AdjustToTarget(d); } else { if (explodeEffect) { GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position); explosion.GetComponent <ParticleSystem>().Play(); Object.Destroy(explosion, 2f); } DestroyProjectile(gameObject); } } } else { if (ch == null) { Destroyable des = coll.gameObject.GetComponent <Destroyable>(); if (des != null && !Owner.CanAttack(des)) { return; } } else if (!Owner.CanAttack(ch)) { return; } ApplyEffects(Owner, coll.gameObject); DestroyProjectile(gameObject); } }
public override void MonoUpdate(GameObject gameObject, bool fixedUpdate) { if (returningBack) { ProjectileData d = GetProjectileData(gameObject); if (d == null || d.proj == null) { return; } if (d.lastUpdateTime + updateInterval <= Time.time) { d.lastUpdateTime = Time.time; if (!d.hasNextWaypoint) { AdjustToTarget(d); } if (d.hasNextWaypoint) { float dist = Utils.DistanceSqr(d.nextWaypoint, d.proj.transform.position); if (dist < 2 * 2) { d.hasNextWaypoint = false; } } else { returningBack = false; if (explodeEffect) { GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position); explosion.GetComponent <ParticleSystem>().Play(); Object.Destroy(explosion, 2f); } ForceDestroyProjectile(gameObject); return; } } } if (navigateToTarget) { //if (fixedUpdate) { ProjectileData d = GetProjectileData(gameObject); if (d == null || d.proj == null) { return; } if (d.lastUpdateTime + updateInterval <= Time.time) { d.lastUpdateTime = Time.time; // find new target if (d.target == null) { //if (d.lastChooseTarget + chooseTargetInterval < Time.time) { d.lastChooseTarget = Time.time; if (!navigateLookOnlyForward) { float angle = d.proj.transform.rotation.eulerAngles.z; List <GameObject> candidates = new List <GameObject>(); foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea)) { if (c.gameObject.Equals(d.proj)) { continue; } if (d.HasHit(c.gameObject)) { continue; } if (!Utils.CanSee(c.gameObject, d.proj.transform.position)) { continue; } Character targetCh = c.gameObject.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } candidates.Add(c.gameObject); } candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position)); foreach (GameObject c in candidates) { Character targetCh = c.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } d.target = targetCh; d.SaveHit(c.gameObject); AdjustToTarget(d); break; } } else // scan only forward targets { float angle = d.proj.transform.rotation.eulerAngles.z; Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y); Vector3 perpend = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position); Debug.DrawRay(d.proj.transform.position, perpend * 10, Color.red, 1f); Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, Color.green, 1f); Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * (-navigateAimArea / 2f), Color.blue, 1f); List <GameObject> candidates = new List <GameObject>(); foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f))) { if (c.gameObject.Equals(d.proj)) { continue; } if (d.HasHit(c.gameObject)) { continue; } if (!Utils.CanSee(c.gameObject, d.proj.transform.position)) { continue; } candidates.Add(c.gameObject); } candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position)); foreach (GameObject c in candidates) { Character targetCh = c.GetChar(); if (targetCh == null || !Owner.CanAttack(targetCh)) { continue; } d.target = targetCh; d.SaveHit(c.gameObject); AdjustToTarget(d); break; } } } } if (d.target != null) { AdjustToTarget(d); } } } } }