/// <summary> /// Initializes the bomb /// </summary> protected virtual void Initialization() { _bombDuration = new WaitForSeconds(BombDelayBeforeExplosion); _explosionDuration = new WaitForSeconds(BombExplosionActiveDuration); _additionalDelayBeforeDestruction = new WaitForSeconds(BombAdditionalDelayBeforeDestruction); // randomize model rotation BombModel.transform.eulerAngles = new Vector3(0f, Random.Range(0f, 360f), 0f); // we grab our collider and make it a trigger _boxCollider = this.gameObject.MMGetComponentNoAlloc <BoxCollider>(); _boxCollider.isTrigger = true; // we create our damage zones _damageAreaEast = CreateDamageArea("East"); _damageAreaWest = CreateDamageArea("West"); _damageAreaSouth = CreateDamageArea("South"); _damageAreaNorth = CreateDamageArea("North"); _damageAreaCenter = CreateDamageArea("Center"); // center damage area setup _damageAreaSize.x = GridManager.Instance.GridUnitSize / 2f; _damageAreaSize.y = GridManager.Instance.GridUnitSize / 2f; _damageAreaSize.z = GridManager.Instance.GridUnitSize / 2f; _damageAreaPosition = this.transform.position + Vector3.up * GridManager.Instance.GridUnitSize / 2f; _damageAreaCenter.gameObject.transform.position = _damageAreaPosition; _damageAreaCenter.gameObject.MMFGetComponentNoAlloc <BoxCollider>().size = _damageAreaSize; }
/// <summary> /// Sets the projectile's owner. /// </summary> /// <param name="newOwner">New owner.</param> public virtual void SetOwner(GameObject newOwner) { _owner = newOwner; DamageOnTouch damageOnTouch = this.gameObject.MMGetComponentNoAlloc <DamageOnTouch>(); if (damageOnTouch != null) { damageOnTouch.Owner = newOwner; damageOnTouch.Owner = newOwner; if (!DamageOwner) { damageOnTouch.IgnoreGameObject(newOwner); } } }
/// <summary> /// On awake, we store the initial speed of the object /// </summary> protected virtual void Awake() { _facingRightInitially = ProjectileIsFacingRight; _initialSpeed = Speed; _health = GetComponent <Health> (); _collider = GetComponent <Collider> (); _collider2D = GetComponent <Collider2D>(); _spriteRenderer = GetComponent <SpriteRenderer> (); _damageOnTouch = GetComponent <DamageOnTouch>(); _rigidBody = GetComponent <Rigidbody> (); _rigidBody2D = GetComponent <Rigidbody2D> (); _initialInvulnerabilityDurationWFS = new WaitForSeconds(InitialInvulnerabilityDuration); if (_spriteRenderer != null) { _initialFlipX = _spriteRenderer.flipX; } _initialLocalScale = transform.localScale; }
/// <summary> /// Creates a directed damage area /// </summary> /// <param name="name"></param> /// <returns></returns> protected virtual DamageOnTouch CreateDamageArea(string name) { GameObject damageAreaGameObject = new GameObject(); damageAreaGameObject.SetActive(false); damageAreaGameObject.transform.SetParent(this.transform); damageAreaGameObject.name = "ExplodudesBombDamageArea" + name; damageAreaGameObject.layer = LayerMask.NameToLayer("Enemies"); DamageOnTouch damageOnTouch = damageAreaGameObject.AddComponent <DamageOnTouch>(); damageOnTouch.DamageCaused = BombDamage; damageOnTouch.TargetLayerMask = DamageLayerMask; damageOnTouch.DamageTakenEveryTime = 0; damageOnTouch.InvincibilityDuration = 0f; damageOnTouch.DamageTakenEveryTime = 10; BoxCollider colllider = damageAreaGameObject.AddComponent <BoxCollider>(); colllider.isTrigger = true; return(damageOnTouch); }
/// <summary> /// Creates the damage area. /// </summary> protected virtual void CreateDamageArea() { _damageArea = new GameObject(); _damageArea.name = this.name + "DamageArea"; _damageArea.transform.position = this.transform.position; _damageArea.transform.rotation = this.transform.rotation; _damageArea.transform.SetParent(this.transform); _damageArea.layer = this.gameObject.layer; if (DamageAreaShape == MeleeDamageAreaShapes.Rectangle) { _boxCollider2D = _damageArea.AddComponent <BoxCollider2D>(); _boxCollider2D.offset = AreaOffset; _boxCollider2D.size = AreaSize; _damageAreaCollider2D = _boxCollider2D; _damageAreaCollider2D.isTrigger = true; } if (DamageAreaShape == MeleeDamageAreaShapes.Circle) { _circleCollider2D = _damageArea.AddComponent <CircleCollider2D>(); _circleCollider2D.transform.position = this.transform.position + this.transform.rotation * AreaOffset; _circleCollider2D.radius = AreaSize.x / 2; _damageAreaCollider2D = _circleCollider2D; _damageAreaCollider2D.isTrigger = true; } if ((DamageAreaShape == MeleeDamageAreaShapes.Rectangle) || (DamageAreaShape == MeleeDamageAreaShapes.Circle)) { Rigidbody2D rigidBody = _damageArea.AddComponent <Rigidbody2D>(); rigidBody.isKinematic = true; rigidBody.sleepMode = RigidbodySleepMode2D.NeverSleep; } if (DamageAreaShape == MeleeDamageAreaShapes.Box) { _boxCollider = _damageArea.AddComponent <BoxCollider>(); _boxCollider.center = AreaOffset; _boxCollider.size = AreaSize; _damageAreaCollider = _boxCollider; _damageAreaCollider.isTrigger = true; } if (DamageAreaShape == MeleeDamageAreaShapes.Sphere) { _sphereCollider = _damageArea.AddComponent <SphereCollider>(); _sphereCollider.transform.position = this.transform.position + this.transform.rotation * AreaOffset; _sphereCollider.radius = AreaSize.x / 2; _damageAreaCollider = _sphereCollider; _damageAreaCollider.isTrigger = true; } if ((DamageAreaShape == MeleeDamageAreaShapes.Box) || (DamageAreaShape == MeleeDamageAreaShapes.Sphere)) { Rigidbody rigidBody = _damageArea.AddComponent <Rigidbody>(); rigidBody.isKinematic = true; } _damageOnTouch = _damageArea.AddComponent <DamageOnTouch>(); _damageOnTouch.SetGizmoSize(AreaSize); _damageOnTouch.SetGizmoOffset(AreaOffset); _damageOnTouch.TargetLayerMask = TargetLayerMask; _damageOnTouch.DamageCaused = DamageCaused; _damageOnTouch.DamageCausedKnockbackType = Knockback; _damageOnTouch.DamageCausedKnockbackForce = KnockbackForce; _damageOnTouch.InvincibilityDuration = InvincibilityDuration; if (!CanDamageOwner) { _damageOnTouch.IgnoreGameObject(Owner.gameObject); } }
/// <summary> /// Explodes in one of the 4 directions /// </summary> /// <param name="hit"></param> /// <param name="damageArea"></param> /// <param name="explosion"></param> /// <param name="angle"></param> protected virtual void DirectedExplosion(RaycastHit hit, DamageOnTouch damageArea, ParticleSystem explosion, float angle) { float hitDistance = hit.distance; // if what we find has a Health component, it's gonna be destroyed and needs to be covered by the explosion if (hit.collider.gameObject.MMFGetComponentNoAlloc <Health>() != null) { hitDistance += GridManager.Instance.GridUnitSize; } // if what we find has a Bomb component, it's gonna be destroyed and needs to be covered by the explosion _otherBomb = hit.collider.gameObject.MMFGetComponentNoAlloc <ExplodudesBomb>(); if ((_otherBomb != null) && (hitDistance <= BombDistanceInGridUnits)) { hitDistance += GridManager.Instance.GridUnitSize; // we detonate the other bomb _otherBomb.Detonate(); } // if we're colliding with an obstacle, we stop this explosion if (hitDistance <= GridManager.Instance.GridUnitSize / 2f) { return; } // otherwise we explode // we compute the size of the explosion float explosionLength; float adjustedDistance = hitDistance - GridManager.Instance.GridUnitSize / 2f; float maxExplosionLength = BombDistanceInGridUnits * GridManager.Instance.GridUnitSize; explosionLength = Mathf.Min(adjustedDistance, maxExplosionLength); explosionLength -= GridManager.Instance.GridUnitSize / 2f; // we set our damage size and position _damageAreaSize.x = GridManager.Instance.GridUnitSize / 2f; _damageAreaSize.y = GridManager.Instance.GridUnitSize / 2f; _damageAreaSize.z = explosionLength; _damageAreaPosition = this.transform.position + (hit.point - (this.transform.position + RaycastOffset)).normalized * (explosionLength / 2f + GridManager.Instance.GridUnitSize / 2f) + Vector3.up * GridManager.Instance.GridUnitSize / 2f; damageArea.gameObject.transform.position = _damageAreaPosition; damageArea.gameObject.transform.LookAt(this.transform.position + Vector3.up * (GridManager.Instance.GridUnitSize / 2f)); // we activate our damage area damageArea.gameObject.SetActive(true); damageArea.gameObject.MMFGetComponentNoAlloc <BoxCollider>().size = _damageAreaSize; // we activate our VFX explosion explosion.gameObject.SetActive(true); explosion.transform.position = _damageAreaPosition; ParticleSystem.ShapeModule shape = explosion.shape; shape.scale = new Vector3(0.1f, 0.1f, explosionLength); shape.rotation = new Vector3(0f, angle, 0f); // we trigger a bomb event MMGameEvent.Trigger("Bomb"); }