// Update is called once per frame void FixedUpdate() { //Draw rays back and forth if (!mainCamera) { mainCamera = Camera.main; cameraWidth = mainCamera.aspect * mainCamera.orthographicSize; } rightOrigin = t.position + t.right * (pc2d.playerDimensions.x / 2f); hitRight = Physics2D.Raycast(rightOrigin, t.right, cameraWidth, layerMask); if (hitRight) { Debug.DrawLine(rightOrigin, hitRight.point, Color.red); distanceRight = hitRight.distance; } else { Debug.DrawLine(rightOrigin, rightOrigin + t.right * cameraWidth, Color.cyan); distanceRight = -1; } leftOrigin = t.position - t.right * (pc2d.playerDimensions.x / 2f); hitLeft = Physics2D.Raycast(leftOrigin, -t.right, cameraWidth, layerMask); if (hitLeft) { Debug.DrawLine(leftOrigin, hitLeft.point, Color.red); distanceLeft = hitLeft.distance; } else { Debug.DrawLine(leftOrigin, leftOrigin - t.right * cameraWidth, Color.cyan); distanceLeft = -1; } if (appliedState == InitialState.Explore) { if (currentState == CurrentState.Idle) { if (!statePause) { //Decide which direction to move if (distanceRight == -1 && distanceLeft == -1) { //Decide random direaction currentState = Random.Range(-10, 10) > 0 ? CurrentState.MovingRight : CurrentState.MovingLeft; } else if (distanceRight == -1 && distanceLeft >= 0) { currentState = CurrentState.MovingRight; } else if (distanceRight >= 0 && distanceLeft == -1) { currentState = CurrentState.MovingLeft; } else if (distanceRight > distanceLeft) { currentState = CurrentState.MovingRight; } else if (distanceRight < distanceLeft) { currentState = CurrentState.MovingLeft; } } } else if (currentState == CurrentState.MovingLeft) { if (!statePause && pc2d.isGrounded) { pc2d.botMovement = -1; float jumpHeightTmp = pc2d.jumpHeight * 0.25f; if (distanceLeft > 0 && distanceLeft < pc2d.playerDimensions.x) { if (hitLeft && canJump && !Physics2D.Linecast(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) - t.right * pc2d.playerDimensions.x * 2, layerMask) && Random.Range(-2, 10) > 0 ) { StartCoroutine(DoJump()); } else { if (!enemyToFollow) { StartCoroutine(StatePause(CurrentState.Idle, true)); } } } /*if(!Physics2D.Linecast(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) - t.right * pc2d.playerDimensions.x * 2)){ * Debug.DrawLine(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) - t.right * pc2d.playerDimensions.x * 2, Color.yellow); * } * else * { * Debug.DrawLine(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) - t.right * pc2d.playerDimensions.x * 2, Color.red); * }*/ //Jump if there is no groun in front groundHit = Physics2D.Raycast(leftOrigin, -t.up, pc2d.playerDimensions.y * 2.1f, layerMask); if (groundHit) { Debug.DrawLine(leftOrigin, groundHit.point, Color.red); } else { Debug.DrawLine(leftOrigin, leftOrigin - t.up * (pc2d.playerDimensions.y * 2.1f), Color.blue); if (canJump) { StartCoroutine(DoJump()); } else { //StartCoroutine(StatePause(CurrentState.MovingRight, true)); StartCoroutine(CheckEnemiesEnumerator(1, 0, false)); } } } } else if (currentState == CurrentState.MovingRight) { if (!statePause && pc2d.isGrounded) { pc2d.botMovement = 1; float jumpHeightTmp = pc2d.jumpHeight * 0.25f; if (distanceRight > 0 && distanceRight < pc2d.playerDimensions.x) { if (hitRight && canJump && !Physics2D.Linecast(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) + t.right * pc2d.playerDimensions.x * 2, layerMask) && Random.Range(-2, 10) > 0 ) { StartCoroutine(DoJump()); } else { if (!enemyToFollow) { StartCoroutine(StatePause(CurrentState.Idle, true)); } } } /*if (!Physics2D.Linecast(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) + t.right * pc2d.playerDimensions.x * 2)) * { * Debug.DrawLine(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) + t.right * pc2d.playerDimensions.x * 2, Color.yellow); * } * else * { * Debug.DrawLine(t.position + t.up * jumpHeightTmp, (t.position + t.up * jumpHeightTmp) + t.right * pc2d.playerDimensions.x * 2, Color.red); * }*/ //Jump if there is no groun in front groundHit = Physics2D.Raycast(rightOrigin, -t.up, pc2d.playerDimensions.y * 2.1f, layerMask); if (groundHit) { Debug.DrawLine(rightOrigin, groundHit.point, Color.red); } else { Debug.DrawLine(rightOrigin, rightOrigin - t.up * (pc2d.playerDimensions.y * 2.1f), Color.blue); if (canJump) { StartCoroutine(DoJump()); } else { //StartCoroutine(StatePause(CurrentState.MovingLeft, true)); StartCoroutine(CheckEnemiesEnumerator(0, 1, false)); } } } } else if (currentState == CurrentState.GoinUPLadder) { if (!statePause) { pc2d.botVerticalMovement = 1; if (!pc2d.currentLadder) { StartCoroutine(StatePause(CurrentState.Idle, true)); } } } else if (currentState == CurrentState.GoingDownLadder) { if (!statePause) { pc2d.botVerticalMovement = -1; if (!pc2d.currentLadder) { StartCoroutine(StatePause(CurrentState.Idle, true)); } } } else if (currentState == CurrentState.Attack) { if (!statePause) { if (!enemyToFollow) { StartCoroutine(StatePause(CurrentState.Idle, true)); } else { //Firing weapon if (attackTimer >= nextAttackTime) { //Check if player is above us and jump if (enemyToFollow.t.position.y > t.position.y && enemyToFollow.t.position.y - t.position.y > pc2d.playerDimensions.y * 0.95f) { if (Random.Range(-5, 10) > 0) { StartCoroutine(DoJump()); } } // pc2d.Attack(); if (botDifficulty == BotDifficulty.Easy) { attackTimer = 0; nextAttackTime = Random.Range(0.25f, 0.95f); } if (botDifficulty == BotDifficulty.Medium) { attackTimer = 0; nextAttackTime = Random.Range(0.01f, 0.37f); } if (botDifficulty == BotDifficulty.Hard) { attackTimer = 0; nextAttackTime = Random.Range(0.01f, 0.24f); } } else { attackTimer += Time.deltaTime; } if (enemyToFollow && !checkingTotalEnemies) { if (enemyToFollow.t.position.x > t.position.x && !pc2d.facingRight) { pc2d.facingRight = true; } if (enemyToFollow.t.position.x < t.position.x && pc2d.facingRight) { pc2d.facingRight = false; } attackingFromLeft = 0; attackingFromRight = 0; //Check if there too many player attacking us and run away for (int i = 0; i < detectedPlayers.Length; i++) { if (detectedPlayers[i]) { BotController2D bcTmp = detectedPlayers[i].GetComponent <BotController2D>(); if (bcTmp && bcTmp.botType != botType && bcTmp.enemyToFollow == pc2d && bcTmp.currentState == CurrentState.Attack) { if (bcTmp.t.position.x > t.position.x) { attackingFromRight++; } else { attackingFromLeft++; } } } } //If the value playerHP from PlayerController2D get too low, and the bot is being attacked, increase the probability to run away if (attackingFromRight >= 2 || attackingFromLeft >= 2 || (pc2d.playerHP < 70 && botDifficulty == BotDifficulty.Hard && (attackingFromRight > 0 || attackingFromLeft > 0)) || (pc2d.playerHP < 40 && botDifficulty == BotDifficulty.Medium && (attackingFromRight > 0 || attackingFromLeft > 0))) { StartCoroutine(CheckEnemiesEnumerator(attackingFromLeft, attackingFromRight, false)); } } } } } } if (pc2d.currentLadder && (previousLadder != pc2d.currentLadder || previousCanGoDownOnLadder != pc2d.canGoDownOnLadder || previousCanClimbLadder != pc2d.canClimbLadder)) { previousLadder = pc2d.currentLadder; previousCanGoDownOnLadder = pc2d.canGoDownOnLadder; previousCanClimbLadder = pc2d.canClimbLadder; if (!pc2d.isAttachedToLadder) { if (pc2d.canClimbLadder) { encounteredLadders++; if ((lastAttachedLadder != pc2d.currentLadder || encounteredLadders > 1) && !statePause) { if (Random.Range(-10, 10) > 0) { if (pc2d.canGoDownOnLadder) { StartCoroutine(StatePause(CurrentState.GoingDownLadder, true)); } else { StartCoroutine(StatePause(CurrentState.GoinUPLadder, true)); } } } } } else { encounteredLadders = 0; lastAttachedLadder = pc2d.currentLadder; } } trVelocity = ((t.position - previousPos).magnitude) / Time.deltaTime; previousPos = t.position; if (trVelocity < 0.01f && !statePause) { timeMotionless += Time.deltaTime; if (timeMotionless > 0.5f) { StartCoroutine(StatePause(CurrentState.Idle, true)); } } else { timeMotionless = 0; } //Detect and attack enemy players detectedPlayers = Physics2D.OverlapCircleAll(t.position, cameraWidth, playerLayerMask); if (!enemyToFollow) { if (!runAway) { if (previousDetectedPlayers.Length != detectedPlayers.Length || (previousDetectedPlayers.Length > 0 && detectedPlayers.Length > 0 && previousDetectedPlayers[0] != detectedPlayers[0])) { previousDetectedPlayers = detectedPlayers; for (int i = 0; i < detectedPlayers.Length; i++) { BotController2D bcTmp = detectedPlayers[i].GetComponent <BotController2D>(); PlayerController2D pc2dTmp = null; if (!bcTmp) { pc2dTmp = detectedPlayers[i].GetComponent <PlayerController2D>(); } if ((pc2dTmp && botType == BotType.Enemy) || (bcTmp && bcTmp.botType != botType)) { Vector3 enemyPos = bcTmp ? bcTmp.t.position : pc2dTmp.t.position; float yDistance = Mathf.Abs(enemyPos.y - t.position.y); if (yDistance < pc2d.playerDimensions.y * 2) { if (!enemyToFollow || Mathf.Abs(enemyPos.x - t.position.x) < Mathf.Abs(enemyToFollow.t.position.x - t.position.x)) { enemyToFollow = bcTmp ? bcTmp.pc2d : pc2dTmp; appliedState = InitialState.Explore; } } } } } } } else { float yDistance = enemyToFollow.t.position.y - t.position.y; float xDistance = enemyToFollow.t.position.x - t.position.x; if (Mathf.Abs(yDistance) >= pc2d.playerDimensions.y * 2 || Mathf.Abs(xDistance) > cameraWidth || !enemyToFollow.enabled) { enemyToFollow = null; } else { if (Mathf.Abs(xDistance) > pc2d.playerDimensions.x * 1.45f) { if (!statePause && pc2d.botVerticalMovement == 0) { if (xDistance > 0) { if (currentState != CurrentState.MovingRight) { statePauseCoroutine = StartCoroutine(StatePause(CurrentState.MovingRight, false)); } } else if (xDistance < 0) { if (currentState != CurrentState.MovingLeft) { statePauseCoroutine = StartCoroutine(StatePause(CurrentState.MovingLeft, false)); } } } else { StopPauseCoroutine(); } } else { if (pc2d.botVerticalMovement == 0) { if (currentState != CurrentState.Attack) { if (!statePause) { statePauseCoroutine = StartCoroutine(StatePause(CurrentState.Attack, true)); } } else { if (Mathf.Abs(xDistance) < pc2d.playerDimensions.x / 3 && !checkingTotalEnemies) { //print("Enemies are too close!!!"); StartCoroutine(CheckEnemiesEnumerator(attackingFromLeft, attackingFromRight, true)); } } } } } } }
/// <summary> /// Dismount the specified Ladder. This is used to stop /// autosticking to the same ladder you just dismounted. /// </summary> /// <param name="ladder">Ladder control to dismount.</param> public void Dismount (Ladder2D ladder){ Unparent (); dismounting = ladder.control; startedClimbing = false; }