public void DestroyObstacle() { Utilities.DebugLog("TerrainObstacle.DestroyObstacle ()"); if (this.destroyedPrefab) { GameObject destroyedObstacleGameObject = (GameObject)Instantiate(this.destroyedPrefab, this.gameObject.transform.position, this.gameObject.transform.rotation); TerrainObstacle destroyedObstacle = destroyedObstacleGameObject.GetComponent <TerrainObstacle> (); float obstacleScaleSign = Mathf.Sign(this.transform.localScale.x); destroyedObstacle.transform.localScale = new Vector3(obstacleScaleSign * destroyedObstacle.transform.localScale.x, destroyedObstacle.transform.localScale.y, destroyedObstacle.transform.localScale.z); // Enable/disable pathfinding obstruction PolyNavObstacle polyNavObstacle = destroyedObstacleGameObject.GetComponent <PolyNavObstacle> (); if (polyNavObstacle) { polyNavObstacle.enabled = this.shouldStopUnitMovementWhenDestroyed; } this.isIntact = false; this.shouldRemoveFromListAndDestroyOnNextUpdate = true; destroyedObstacle.shouldAddToListOnNextUpdate = true; } else { SpriteRenderer spriteRenderer = this.gameObject.GetComponent <SpriteRenderer> (); if (spriteRenderer) { spriteRenderer.color = new Color(1f, 1f, 1f, .2f); // 20% transparent } this.isIntact = false; } }
// Handle collisions void OnTriggerEnter2D(Collider2D other) { Utilities.DebugLog("Projectile.OnTriggerEnter2D ()"); if (this.currentState == ProjectileState.PROJECTILE_STATE_ACTIVE) { // Check collision between projectile and Unit Unit unit = other.gameObject.GetComponent <Unit> (); if (unit) { if (unit.isPlayerControlled != this.isPlayerControlled && (!this.isBallisticProjectile || this.percentTravelled > 0.9f) && unit.currentState != Unit.UnitState.UNIT_STATE_PREPARING_FOR_CLOSE_COMBAT && unit.currentState != Unit.UnitState.UNIT_STATE_CLOSE_COMBAT && unit.currentState != Unit.UnitState.UNIT_STATE_DEAD && unit.currentState != Unit.UnitState.UNIT_STATE_DISABLED) { // For bazooka only, decrease damage as it approaches its max range float attackStrength = this.attack; if (this.isBazooka) { attackStrength = attackStrength * ((1.0f - this.percentTravelled) * 0.5f + 0.5f); } unit.TakeDamage(attackStrength); if (this.tcScript) { this.tcScript.projectilesList.Remove(this); } DestroyProjectileAccordingToType(); } } // Check collision between projectile and obstacle TerrainObstacle obstacle = other.gameObject.GetComponent <TerrainObstacle> (); if (obstacle) { if (obstacle.isDestructible && (!this.isBallisticProjectile || this.percentTravelled > 0.9f) && (!this.isBazooka || this.distanceTravelled > 1.0f /*50.0f*/)) { // Stop projectile if applicable if ((obstacle.isIntact && obstacle.shouldStopExplosivesWhenIntact && this.isBallisticProjectile && this.fullBallisticShift * 1.0f < obstacle.height * 2.5f) || (obstacle.isIntact && obstacle.shouldStopFireWhenIntact && this.isFlamethrower) || (obstacle.isIntact && obstacle.shouldStopBulletsWhenIntact && !this.isBallisticProjectile && !this.isFlamethrower) || (!obstacle.isIntact && obstacle.shouldStopExposivesWhenDestroyed && this.isBallisticProjectile) || (!obstacle.isIntact && obstacle.shouldStopFireWhenDestroyed && this.isFlamethrower) || (!obstacle.isIntact && obstacle.shouldStopBulletsWhenDestroyed && !this.isBallisticProjectile && !this.isFlamethrower)) { DestroyProjectileAccordingToType(); } // Cause damage to obstacle if applicable if ((obstacle.isIntact && !obstacle.isImmuneToExplosiveDamage && this.isBallisticProjectile && this.fullBallisticShift * 1.0f < obstacle.height * 2.5f) || (obstacle.isIntact && !obstacle.isImmuneToFireDamage && this.isFlamethrower) || (obstacle.isIntact && !obstacle.isImmuneToBulletDamage && !this.isBallisticProjectile && !this.isFlamethrower)) { obstacle.TakeDamage(this.attack); } } } else { // Check collision between projectile and non-TerrainObstacle PolyNavObstacle PolyNavObstacle polyNavObstacle = other.gameObject.GetComponent <PolyNavObstacle> (); if (polyNavObstacle) { //DestroyProjectileAccordingToType (); float GENERIC_POLYNAV_OBSTACLE_HEIGHT = 200.0f; if ((!this.isBallisticProjectile || this.percentTravelled > 0.9f) && (!this.isBazooka || this.distanceTravelled > 1.0f /*50.0f*/)) { // Stop projectile if applicable if ((this.isBallisticProjectile && this.fullBallisticShift * 1.0f < GENERIC_POLYNAV_OBSTACLE_HEIGHT * 2.5f) || (this.isFlamethrower) || (!this.isBallisticProjectile && !this.isFlamethrower)) { DestroyProjectileAccordingToType(); } } } } } }
private void UpdateEnemyAIForUnit() { if (unit.isTrackedForDebug) { Utilities.DebugLog("Place breakpoint here to debug this unit."); } // Remove target if it is disabled if (unit.attackTargetGameObject) { Unit targetUnit = unit.attackTargetGameObject.GetComponent <Unit> (); if (targetUnit) { if (targetUnit.currentState == Unit.UnitState.UNIT_STATE_DEAD || targetUnit.currentState == Unit.UnitState.UNIT_STATE_DISABLED || targetUnit.currentState == Unit.UnitState.UNIT_STATE_PAUSED) { unit.attackTargetGameObject = null; unit.isIntentionallyAttackingExplosiveObstacle = false; } } else { TerrainObstacle targetObstacle = unit.attackTargetGameObject.GetComponent <TerrainObstacle> (); if (targetObstacle) { if (!targetObstacle.isIntact) { unit.attackTargetGameObject = null; unit.isIntentionallyAttackingExplosiveObstacle = false; } } } } if (unit.attackTargetGameObject || unit.isAttackTargetPositionSet) { if (unit.isMoveTargetPositionSet) { // If following a move command, keep firing at attack target, regardless of range if (unit.attackTargetGameObject) { unit.AttackPosition(unit.attackTargetGameObject.transform.position); } if (unit.isAttackTargetPositionSet) { unit.AttackPosition(unit.attackTargetPosition); } } else { if (unit.IsWithinRangeOfAttackTarget()) { // If not following a move command, attack target only once in range if (unit.unitType != Unit.UnitType.UNIT_KAMIKAZE && unit.unitType != Unit.UnitType.UNIT_BRAWLER) { unit.StopRunning(); unit.moveTargetGameObject = null; unit.isMoveTargetPositionSet = false; if (unit.attackTargetGameObject) { unit.AttackPosition(unit.attackTargetGameObject.transform.position); } if (unit.isAttackTargetPositionSet) { unit.AttackPosition(unit.attackTargetPosition); } } } else { // if (IsTimeForNextAIAction ()) { // If not following a move command, and not yet within range of attack target, move towards attack target if (unit.isAttackTargetPositionSet) { unit.MoveTowardsPoint(unit.attackTargetPosition); // MarkLastAIActionTime (); } if (unit.attackTargetGameObject) { unit.MoveTowardsTarget(unit.attackTargetGameObject); // MarkLastAIActionTime (); } // } } } } // If moving and reached target, stop. if (unit.IsWithinRangeOfMoveTarget()) { unit.StopRunning(); unit.moveTargetGameObject = null; unit.isMoveTargetPositionSet = false; } // Have AI players attack nearest enemy // Move towards new closest target if current attack or move target is dead or disabled Unit nearestEnemy = tcScript.GetNearestEnemyForUnit(unit); if (nearestEnemy /*&& GetNumMovingAIUnits () < AI_numSimultaneousActions*/ && IsTimeForNextAIAction() && !unit.isMoving) { if (!unit.attackTargetGameObject || (unit.attackTargetGameObject && unit.attackTargetGameObject != nearestEnemy.gameObject) || !unit.moveTargetGameObject || (unit.moveTargetGameObject && unit.moveTargetGameObject != nearestEnemy.gameObject)) { if (AI_shouldTargetExplosiveObstacles) { TerrainObstacle nearestExplosiveObstacle = tcScript.GetExplosiveObstacleNearPlayerUnitIfExists(); if (nearestExplosiveObstacle) { if (AI_shouldAvoidTargetingExplosiveObstaclesNearFriendlies) { float distanceToNearestFriendly = tcScript.GetDistanceOfNearestFriendlyFromObstacle(nearestExplosiveObstacle, unit.isPlayerControlled); if (distanceToNearestFriendly > AI_MIN_DISTANCE_FROM_FRIENDLY_TO_TARGET_EXPLOSIVE_OBSTACLES) { unit.attackTargetGameObject = nearestExplosiveObstacle.gameObject; unit.isIntentionallyAttackingExplosiveObstacle = true; } else { Debug.Log("NOT TARGETING BARREL!"); } } else { unit.attackTargetGameObject = nearestExplosiveObstacle.gameObject; unit.isIntentionallyAttackingExplosiveObstacle = true; //unit.MoveTowardsTarget (nearestExplosiveObstacle.gameObject); } } else { unit.attackTargetGameObject = nearestEnemy.gameObject; unit.isIntentionallyAttackingExplosiveObstacle = false; //unit.MoveTowardsTarget (nearestEnemy.gameObject); } } else { unit.attackTargetGameObject = nearestEnemy.gameObject; unit.isIntentionallyAttackingExplosiveObstacle = false; //unit.MoveTowardsTarget (nearestEnemy.gameObject); } MarkLastAIActionTime(); Utilities.DebugLog("AI: Move within firing range of nearest enemy."); } } // if (unit.IsWithinRangeOfAttackTarget () || unit.IsWithinRangeOfMoveTarget ()) { // if (unit.unitType != Unit.UnitType.UNIT_KAMIKAZE && unit.unitType != Unit.UnitType.UNIT_BRAWLER) { // // unit.StopRunning (); // unit.moveTargetGameObject = null; // unit.isMoveTargetPositionSet = false; // // TerrainObstacle nearestExplosiveObstacle = tcScript.GetExplosiveObstacleNearPlayerUnitIfExists (); // if (nearestExplosiveObstacle) { // Utilities.DebugLog ("AI: Attacking explosive obstacle near player unit."); // unit.AttackPosition (nearestExplosiveObstacle.gameObject.transform.position); // } else { // Utilities.DebugLog ("AI: Attacking nearest enemy unit."); // unit.AttackPosition (nearestEnemy.gameObject.transform.position); // } // // } // } else if (/*GetNumMovingAIUnits () < AI_numSimultaneousActions &&*/ Time.time > timeAtLastAIAction_SingleUnit + AI_delayBetweenActions_SingleUnit && Time.time > timeAtLastAIAction_AllUnits + AI_delayBetweenActions_AllUnits && !unit.isMoving) { // // if (AI_shouldTargetExplosiveObstacles) { // TerrainObstacle nearestExplosiveObstacle = tcScript.GetExplosiveObstacleNearPlayerUnitIfExists (); // if (nearestExplosiveObstacle) { // unit.MoveWithinFiringRangeOfGameObject (nearestExplosiveObstacle.gameObject); // } else { // unit.MoveWithinFiringRangeOfNearestEnemyUnit (); // } // } else { // unit.MoveWithinFiringRangeOfNearestEnemyUnit (); // //Utilities.DebugLog ("MoveWithinFiringRangeOfNearestEnemyUnit"); // } // timeAtLastAIAction_SingleUnit = Time.time; // timeAtLastAIAction_AllUnits = Time.time; // Utilities.DebugLog ("AI: Attacking explosive obstacle near player unit. (2)"); // // } }