public override void Fire(Transform weaponTrans, Vector3 direction, int sortingLayer, out float recoil) { lastFire_ = Time.time; recoil = 0.0f; GameManager.Instance.PlayerScript.HolyTalk(); var pos = GameManager.Instance.PlayerTrans.position; const float Radius = 5.0f; GameManager.Instance.MakeFlash(pos, Radius * 5f); GameManager.Instance.MakePoof(pos, 1, Radius * 1f); GameManager.Instance.ShakeCamera(1.0f); AudioManager.Instance.PlayClip(AudioManager.Instance.PlayerAudioSource, FireAudio, volumeScale: 1.0f); int aliveCount = BlackboardScript.GetEnemies(pos, Radius); for (int i = 0; i < aliveCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.Enemies[idx]; var dir = enemy.transform.position - pos; float distance = dir.magnitude + 0.0001f; dir /= distance; dir.Normalize(); var force = (Radius - distance) * dir * 0.25f; enemy.AddForce(force); enemy.SetSlowmotion(); } }
// TODO PE: NOT EXPLOSION! SOMETHING COOL! IEnumerator ExplodeCo() { isExploding_ = true; while (true) { var pos = trans_.position; GameManager.Instance.MakeFlash(pos, new Color(0.4f, 0.4f, 0.2f), Radius * 1.5f); float force = 0.1f; int aliveCount = BlackboardScript.GetEnemies(pos, Radius); for (int i = 0; i < aliveCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.Enemies[idx]; enemy.SetSlowmotion(); // enemy.AddForce((enemy.transform.position - pos) * force); } // Kill player if very close, else just push float playerDist = BlackboardScript.DistanceToPlayer(pos); if (playerDist < Radius * 0.2f) { GameManager.Instance.PlayerScript.KillPlayer(); } else if (playerDist < 1.0f) { GameManager.Instance.PlayerScript.AddForce((GameManager.Instance.PlayerTrans.position - pos) * 0.25f); } yield return(new WaitForSeconds(0.4f)); } }
public static int Swing(Vector3 where, float damage, float radius, AudioClip clipHit, AudioClip clipMiss, out float recoil) { recoil = -0.2f; ProjectileManager.Instance.DeflectSource = where; ProjectileManager.Instance.DoDeflect = true; ProjectileManager.Instance.DeflectRadius = radius; int aliveCount = BlackboardScript.GetEnemies(where, radius); var clip = aliveCount == 0 ? clipMiss : clipHit; AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.PlayerAudioSource, clip); for (int i = 0; i < aliveCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.Enemies[idx]; enemy.SetSlowmotion(); enemy.ApplyDamage(damage, enemy.transform.position - where, 1.0f, true); } return(aliveCount); }
IEnumerator ExplodeCo(float delay) { float explodeTime = Time.time + delay; float flashOffset = UnityEngine.Random.value; while (Time.time < explodeTime) { material_.SetFloat(flashParamId_, 0.6f + (Mathf.Sin(((Time.time + flashOffset) * 10) + 1.0f) * 0.5f) * 0.25f); yield return(null); } const float ExplodeRadius = 3.0f; AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.MiscAudioSource, AudioManager.Instance.AudioData.LivingBombExplode); GameManager.Instance.MakeCircle(transform_.position, ExplodeRadius); GameManager.Instance.MakePoof(transform_.position, 2, ExplodeRadius * 0.2f); GameManager.Instance.ShakeCamera(0.4f); int aliveCount = BlackboardScript.GetEnemies(transform_.position, ExplodeRadius); bool isFirstHit = true; for (int i = 0; i < aliveCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.Enemies[idx]; if (enemy != this) { enemy.OnLivingBombHit(livingBombDamage_ * 0.9f, isFirstHit); isFirstHit = false; } } if (BlackboardScript.DistanceToPlayer(transform_.position) < ExplodeRadius * 0.5f) { GameManager.Instance.PlayerScript.KillPlayer(); } ApplyDamage(livingBombDamage_, RndUtil.RandomInsideUnitCircle().normalized, 0.25f, true); }
IEnumerator ThrowCo(Vector3 from, Vector3 to) { shadowRenderer_.enabled = false; var fuseEmission = fuseParticles_.emission; fuseEmission.enabled = true; float length = (to - from).magnitude; float force = Mathf.Min(5.0f, length); float velocityY = 1.0f * force; float downForce = -25.0f; float speed = 5.0f * force; float fuseT0 = Time.time; float fuseT1 = fuseT0 + FuseTime; Vector3 dir = (to - from).normalized; Vector3 pos = from; float offsetY = 0; audioSource_.clip = AudioManager.Instance.AudioData.BombFuseBurn; audioSource_.volume = 0.5f * AudioManager.Instance.MasterVolume; audioSource_.Play(); while (Time.time < fuseT1) { float delta = Time.deltaTime; Vector3 showPos = pos; showPos.y += offsetY; trans_.position = showPos; bombRenderer_.sortingOrder = (Mathf.RoundToInt(trans_.position.y * 100f)); bombMaterial_.SetFloat(flashParamId_, (Mathf.Sin((Time.time * 15) + 1.0f) * 0.5f) * 0.75f); offsetY += velocityY * delta; velocityY += downForce * delta; if (offsetY <= 0) { shadowRenderer_.enabled = true; velocityY = -velocityY * 0.5f; } pos += dir * speed * Time.deltaTime; speed *= 1.0f - (5.0f * delta); yield return(null); } fuseEmission.enabled = false; audioSource_.clip = AudioManager.Instance.AudioData.BombExplode; audioSource_.volume = 1.0f * AudioManager.Instance.MasterVolume; audioSource_.Play(); GameManager.Instance.MakeFlash(pos, Radius * 1.5f); GameManager.Instance.MakePoof(pos, 6, Radius * 1.5f); GameManager.Instance.ShakeCamera(4.0f); int deadCount = BlackboardScript.GetDeadEnemies(pos, Radius); for (int i = 0; i < deadCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.DeadEnemies[idx]; enemy.AddForce((enemy.transform.position - pos) * 0.25f); // enemy.Explode(2.0f + Random.value * 2); } int aliveCount = BlackboardScript.GetEnemies(pos, Radius); for (int i = 0; i < aliveCount; ++i) { int idx = BlackboardScript.Matches[i].Idx; ActorBase enemy = BlackboardScript.Enemies[idx]; enemy.ApplyDamage(Damage, enemy.transform.position - pos, 1.0f, true); } for (int i = 0; i < 10; ++i) { Vector2 rnd = RndUtil.RandomInsideUnitCircle() * Radius * 0.5f; Vector3 flamePos = pos; flamePos.x += rnd.x; flamePos.y += rnd.y; GameManager.Instance.EmitFlame(flamePos, Random.value + 0.5f); yield return(null); } // Kill player if very close, else just push float playerDist = BlackboardScript.DistanceToPlayer(pos); if (playerDist < 3.0f) { GameManager.Instance.PlayerScript.AddForce((GameManager.Instance.PlayerTrans.position - pos) * 0.1f); } Hide(); }
void TickBasicProjectiles(float delta) { removeListBasic_.Clear(); float time = Time.time; for (int i = 0; i < basicProjectiles_.Count; ++i) { var p = basicProjectiles_[i]; if (p.IsLastFrame) { if (p.CurrentTarget != null && p.StickySoundRepeater != null) { p.StickySoundRepeater.StopClip(); } removeListBasic_.Add(p); } else { bool outOfTime = p.DieTime > 0.0f && time >= p.DieTime; bool endOfDistance = p.DistanceTraveled >= p.MaxDistance; if (!p.IsLastFrame && (endOfDistance || outOfTime)) { p.SpriteInfo.Renderer.color = Color.white; p.IsLastFrame = true; } if (p.IsFirstFrame) { p.IsFirstFrame = false; } float frameSpeed = p.Speed * delta * Timers.EnemyTimer; Vector3 movement = p.Direction * frameSpeed; if (p.ReflectOnEdges) { float newX = p.Position.x + movement.x; float newY = p.Position.y + movement.y; if (newX < -arenaBoundsX_ || newX > arenaBoundsX_) { movement = new Vector3(-movement.x, movement.y, 0.0f); p.Direction = new Vector3(-p.Direction.x, p.Direction.y, 0.0f); } if (newY < -arenaBoundsY_ || newY > arenaBoundsY_) { movement = new Vector3(movement.x, -movement.y, 0.0f); p.Direction = new Vector3(p.Direction.x, -p.Direction.y, 0.0f); } } p.Position += movement; if (p.StickToTarget && p.CurrentTarget != null) { if (p.CurrentTarget.Hp <= 0) { // Target we are stuck to died. Scan for a new one close by or continue moving if nothing found. if (p.StickySoundRepeater != null) { p.StickySoundRepeater.StopClip(); } p.CurrentTarget = null; int idxClosest = BlackboardScript.GetIdxClosestEnemy(p.Position, 1.5f, 5); if (idxClosest >= 0) { var closeEnemy = BlackboardScript.Enemies[idxClosest]; p.Direction = (closeEnemy.transform.position - p.Position).normalized; } else { // Maintain direction } } else { // Keep sticking to target at specific offset p.Position = p.CurrentTarget.transform.position + p.StickOffset; p.CurrentTarget.SetSlowmotion(0.5f); Vector3 damageDirection = (p.StickOffset * -1).normalized; p.CurrentTarget.ApplyDamage(p.Damage, damageDirection, 0.25f, false); GameManager.Instance.TriggerBlood(p.Position + damageDirection * 0.2f, 8.0f, floorBloodRnd: 0.1f); GameManager.Instance.ShakeCamera(0.1f); } } else if (p.Type == ProjectileType.HarmsEnemies) { // TODO PE: This should be changed to colliders. Might enable walls too? // Find enemies hit by projectile if (BlackboardScript.GetEnemies(p.Position, p.Radius, 1) > 0) { int matchIdx = BlackboardScript.Matches[0].Idx; ActorBase enemy = BlackboardScript.Enemies[matchIdx]; if (p.StickToTarget) { // Begin sticking to target p.CurrentTarget = enemy; p.StickOffset = (p.SpriteInfo.Transform.position - enemy.transform.position) * 0.9f; if (p.StickySoundRepeater != null) { p.StickySoundRepeater.StartClipWithRandomPitch(p.CollisionSound); } else { AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.MiscAudioSource, p.CollisionSound); } } float damage = Basic.CalcDamage(p); if (p.CustomCollisionResponse != null) { p.CustomCollisionResponse(p, enemy, damage, p.Direction); } else { GameManager.Instance.DamageEnemy(enemy, damage, p.Direction, p.Force); } if (p.DieOnCollision) { removeListBasic_.Add(p); } if (p.ReflectOnCollision) { if (UnityEngine.Random.value < 0.5f) { p.Direction = Vector3.Reflect(p.Direction, Vector3.up); } else { p.Direction = Vector3.Reflect(p.Direction, Vector3.right); } } } } else if (p.Type == ProjectileType.HarmsPlayer && DoDeflect) { Vector3 dir = p.Position - DeflectSource; float distance = dir.magnitude; if (distance <= DeflectRadius) { // Projectile deflected dir.Normalize(); p.Direction = Vector3.Reflect(p.Direction, dir) * 3; float rot_z = Mathf.Atan2(p.Direction.y, p.Direction.x) * Mathf.Rad2Deg; p.SpriteInfo.Transform.rotation = Quaternion.Euler(0f, 0f, rot_z); p.Color = new Color(0.8f, 1.0f, 1.0f); p.SpriteInfo.Renderer.color = p.Color; p.Type = ProjectileType.HarmsEnemies; p.SpriteInfo.Transform.gameObject.layer = LayerFromProjectileType(p.Type); } } if (p.RotationSpeed > 0.0f) { p.SpriteInfo.Transform.rotation = Quaternion.Euler(0.0f, 0.0f, Time.time * (p.CurrentTarget == null ? p.RotationSpeed : p.RotationSpeedWhenStuck)); } if (p.SwayFactor > 0.0f) { Vector3 perpendicular = new Vector3(-p.Direction.y, p.Direction.x, 0).normalized; p.SpriteInfo.Transform.position = p.Position + (Mathf.Sin(Time.time * 10) * p.SwayFactor * perpendicular); } else { p.SpriteInfo.Transform.position = p.Position; } p.DistanceTraveled += frameSpeed; } } DoDeflect = false; for (int i = 0; i < removeListBasic_.Count; ++i) { ProjectileCache.Instance.ReturnSprite(removeListBasic_[i].SpriteInfo); removeListBasic_[i].Reset(); projectileCache_.ReturnObject(removeListBasic_[i]); basicProjectiles_.Remove(removeListBasic_[i]); } }
public override void Fire(Transform weaponTrans, Vector3 direction, int sortingLayer, out float recoil) { lastFire_ = Time.time; recoil = 0.1f; Color color = new Color(0.8f, 0.6f, 0.1f); Vector3 worldMuzzle = weaponTrans.TransformPoint(Muzzle); worldMuzzle += -direction * 0.2f; // Start a little behind muzzle because its very unfun missing an enemy that is too close GameManager.Instance.MakeFlash(worldMuzzle); GameManager.Instance.MakePoof(worldMuzzle, 2); AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.PlayerAudioSource, FireAudio); ProjectileManager.Basic basic = ProjectileManager.Instance.GetProjectile(); basic.SpriteInfo = ProjectileCache.Instance.GetSprite(); basic.Speed = 100.0f; basic.Damage = 450.0f; basic.MaxDistance = 80.0f; basic.Radius = 0.1f; Vector3 scale = basic.SpriteInfo.Transform.localScale; scale.x = 1.0f; scale.y = 1.0f; scale.z = 1.0f; basic.SpriteInfo.Transform.localScale = scale; basic.Position = worldMuzzle; basic.SpriteInfo.Renderer.sprite = BulletSprite; basic.SpriteInfo.Renderer.sortingLayerID = sortingLayer; basic.Direction = direction; basic.Color = color; basic.DieTime = 0.0f; basic.Type = ProjectileManager.ProjectileType.HarmsNothing; float rot_z = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; basic.SpriteInfo.Transform.rotation = Quaternion.Euler(0f, 0f, rot_z); ProjectileManager.Instance.Fire(basic); // TODO PE: Spherecast will return sorted list // Sniper immediately hits the full line. Since we sort by distance we have to allow a large number of hits or we might not include closest in match list. float damage = basic.Damage; int count = BlackboardScript.GetEnemies(worldMuzzle, worldMuzzle + direction * 1000, 50); // Copy matches to local array. Sort it by distance. List <BlackboardScript.HitMatch> matches = new List <BlackboardScript.HitMatch>(BlackboardScript.Matches.Take(count)); var ordered = matches.OrderBy(hit => hit.Distance).Take(5).ToList(); for (int i = 0; i < ordered.Count; ++i) { BlackboardScript.HitMatch match = ordered[i]; ActorBase enemy = BlackboardScript.Enemies[match.Idx]; float enemyDamage = Mathf.Min(enemy.Hp, damage); GameManager.Instance.DamageEnemy(enemy, enemyDamage, direction, 1.0f, match.IsHeadshot); damage -= enemyDamage; if (damage <= 0) { break; } } }