private bool DoWeNeedToWaitForTooCloseSpider(GameObject otherSpider) { WalkStage otherWalkStage = closestSpiderController.currentWalkStage; return(otherWalkStage == WalkStage.Avoid || otherWalkStage == WalkStage.Turn || (otherWalkStage == WalkStage.Wait && DoesThisSpiderHavePriority(spiderWeAreWaitingFor))); }
private void SetWalkStage(WalkStage newWalkStage) { if (currentWalkStage != newWalkStage) { currentWalkStage = newWalkStage; if (newWalkStage == WalkStage.Wait) { timeToLeaveWait = -1; SetIdleAnim(); } else { SetWalkAnim(spiderSpecificConstants.BASE_WALK_SPEED * walkMultiplier); } } }
private void HandleWalkStage() { float borderProgress = GetBorderProgressAmount(); //We have to do this first as we'll be checking if we're in the turn stage in the next block if (borderProgress != -1 && currentWalkStage != WalkStage.Wait) { SetWalkStage(WalkStage.Turn); } else { SetBorderPriority(BorderPriorities.None); } //If there's a spider too close to us if (null != closestSpider) { switch (currentWalkStage) { case WalkStage.Forward: SetWalkStage(WalkStage.Avoid); spiderBeingAvoided = closestSpider; break; case WalkStage.Turn: if (closestSpiderController.currentWalkStage == WalkStage.Turn && DoesThisSpiderHavePriority(closestSpider)) { spiderWeAreWaitingFor = closestSpider; SetWalkStage(WalkStage.Wait); } else if (borderProgress == -1) { SetWalkStage(WalkStage.Forward); } break; case WalkStage.Avoid: if (spiderBeingAvoided != closestSpider && closestSpiderController.currentWalkStage == WalkStage.Turn) { spiderWeAreWaitingFor = closestSpider; SetWalkStage(WalkStage.Wait); } //If the spider is avoiding another spider that isn't us, the one with lower priority waits else if (closestSpiderController.currentWalkStage == WalkStage.Avoid && closestSpiderController.spiderBeingAvoided != gameObject && DoesThisSpiderHavePriority(closestSpider)) { spiderWeAreWaitingFor = closestSpider; SetWalkStage(WalkStage.Wait); } break; case WalkStage.Wait: WalkStage otherWalkStage = closestSpiderController.currentWalkStage; if (closestSpider != spiderWeAreWaitingFor && DoWeNeedToWaitForTooCloseSpider(closestSpider)) { //Then we should wait for this new spider instead timeToLeaveWait = -1; spiderWeAreWaitingFor = closestSpider; } break; } } else if (borderProgress == -1 && timeToLeaveWait == -1) { //If there are no spiders too close, we're not at the border, and not preparing to leave wait, we can walk forward normally SetWalkStage(WalkStage.Forward); spiderBeingAvoided = null; } switch (currentWalkStage) { case WalkStage.Forward: if (walkStageElapsedTime < walkStageDuration) { transform.position += transform.forward * Time.deltaTime * randomWalkSpeed; walkStageElapsedTime += Time.deltaTime; } else { SetWalkStage(WalkStage.None); NextMovementStage(); } break; case WalkStage.Turn: Vector3 tableDirection = tableCentrePosition - transform.position; float rotateSpeed = spiderSpecificConstants.BASE_BORDER_TURN_SPEED; if (walkMultiplier > 1) { rotateSpeed = rotateSpeed * walkMultiplier; } if (null != closestSpider && closestSpiderDistance < GetMaxSpiderAvoidDistanceWithScaleMult()) { rotateSpeed = rotateSpeed * (GetMaxSpiderAvoidDistanceWithScaleMult() - closestSpiderDistance) / (GetMaxSpiderAvoidDistanceWithScaleMult() - GetMinSpiderAvoidDistanceWithScaleMult()); } else { rotateSpeed = rotateSpeed * borderProgress; } TurnToTargetDirection(GetBorderTurnDirection(), walkMultiplier); transform.position += transform.forward * Time.deltaTime * randomWalkSpeed; if (debugEnabled) { Color debugColorGreen = new Color(0, 1, 0, Mathf.Clamp01(borderProgress)); Color debugColorMagenta = new Color(1, 0, 1, Mathf.Clamp01(borderProgress)); Debug.DrawRay(transform.position + debugOffset, transform.forward * DEBUG_RAY_LENGTH_MULTIPLIER, debugColorGreen); Debug.DrawRay(transform.position + debugOffset, tableDirection, debugColorMagenta); } break; case WalkStage.Avoid: float turnSpeedMultiplier; if (spiderToAvoidIsInSector) { turnSpeedMultiplier = (spiderSpecificConstants.SPIDER_AVOIDANCE_SECTOR_MAX_ANGLE - closestSpiderAngle) / (spiderSpecificConstants.SPIDER_AVOIDANCE_SECTOR_MAX_ANGLE - spiderSpecificConstants.SPIDER_AVOIDANCE_SECTOR_MIN_ANGLE); } else { turnSpeedMultiplier = (GetMaxSpiderAvoidDistanceWithScaleMult() - closestSpiderDistance) / (GetMaxSpiderAvoidDistanceWithScaleMult() - GetMinSpiderAvoidDistanceWithScaleMult()); } float turnSpeed = spiderSpecificConstants.BASE_AVOID_TURN_SPEED * walkMultiplier * turnSpeedMultiplier; TurnToTargetDirection(transform.position - closestSpider.transform.position, walkMultiplier * turnSpeedMultiplier); transform.position += transform.forward * Time.deltaTime * randomWalkSpeed; if (debugEnabled) { Color debugColorGreen = new Color(0, 1, 0, Mathf.Clamp01(turnSpeedMultiplier)); Color debugColorRed = new Color(1, 0, 0, Mathf.Clamp01(turnSpeedMultiplier)); Debug.DrawRay(transform.position + debugOffset, transform.forward * DEBUG_RAY_LENGTH_MULTIPLIER, debugColorGreen); Debug.DrawRay(transform.position + debugOffset, (transform.position - closestSpider.transform.position) * DEBUG_RAY_LENGTH_AVOID_MULTIPLIER, debugColorRed); } break; case WalkStage.Wait: WalkStage otherWalkStage = closestSpiderController.currentWalkStage; //If we haven't stopped waiting, and the spider isn't too close, or it is but we don't need to wait for it anyway if (timeToLeaveWait == -1 && (!IsSpiderTooClose(spiderWeAreWaitingFor) || !DoWeNeedToWaitForTooCloseSpider(spiderWeAreWaitingFor))) { timeToLeaveWait = Time.time + ADDITIONAL_WAIT_TIME; } if (debugEnabled) { float opacityMultiplier; if (timeToLeaveWait == -1) { opacityMultiplier = 1; } else //1 if we've just started waiting { opacityMultiplier = (timeToLeaveWait - Time.time) / ADDITIONAL_WAIT_TIME; } Color debugColorYellow = new Color(1, 0.92f, 0.016f, opacityMultiplier); Debug.DrawLine(transform.position + debugOffset, spiderWeAreWaitingFor.transform.position + debugOffset, debugColorYellow); } break; } }