private IEnumerator MakeAttack(WanderScript target) { target.GetAttacked(this); float timer = 0f; while (!target.dead) { timer += Time.deltaTime; if (timer > attackSpeed) { target.TakeDamage(power); timer = 0f; } yield return(null); } if (!string.IsNullOrEmpty(attackingStates[currentState].animationBool)) { animator.SetBool(attackingStates[currentState].animationBool, false); } DecideNextState(false); }
private void ChaseAnimal(WanderScript prey) { Vector3 target = prey.transform.position; prey.BeginChase(this); int fastestMovementState = 0; for (int i = 0; i < movementStates.Length; i++) { if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed) { fastestMovementState = i; } } currentState = fastestMovementState; if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } if (useNavMesh) { StartCoroutine(ChaseState(prey)); } else { StartCoroutine(NonNavMeshChaseState(prey)); } }
private void AttackAnimal(WanderScript target) { attacking = true; if (logChanges) { Debug.Log(string.Format("{0}: Attacking {1}!", gameObject.name, target.gameObject.name)); } if (useNavMesh) { navMeshAgent.SetDestination(transform.position); } else { targetLocation = transform.position; } if (attackingStates.Length > 0) { currentState = Random.Range(0, attackingStates.Length); if (!string.IsNullOrEmpty(attackingStates[currentState].animationBool)) { animator.SetBool(attackingStates[currentState].animationBool, true); } } StartCoroutine(MakeAttack(target)); }
private void NonNavMeshRunAwayFromAnimal(WanderScript predator) { moving = true; Quaternion startRotation = transform.rotation; transform.rotation = Quaternion.LookRotation(transform.position - predator.transform.position); targetLocation = transform.position + transform.forward * 5f; transform.rotation = startRotation; if (constainedToWanderZone && Vector3.Distance(targetLocation, origin) > wanderZone) { targetLocation = RandonPointInRange(); } int fastestMovementState = 0; for (int i = 0; i < movementStates.Length; i++) { if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed) { fastestMovementState = i; } } currentState = fastestMovementState; if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } StartCoroutine(NonNavMeshRunAwayState(targetLocation, predator)); }
private IEnumerator RunAwayState(Vector3 target, WanderScript predator) { navMeshAgent.speed = movementStates[currentState].moveSpeed; navMeshAgent.angularSpeed = movementStates[currentState].turnSpeed; navMeshAgent.SetDestination(target); float timeMoving = 0f; while ((navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance || timeMoving < 0.1f) && timeMoving < stamina) { timeMoving += Time.deltaTime; yield return(null); } navMeshAgent.SetDestination(transform.position); if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } if (timeMoving > stamina || predator.dead || Vector3.Distance(transform.position, predator.transform.position) > awareness) { BeginIdleState(); } else { RunAwayFromAnimal(predator); } }
private IEnumerator ChaseState(WanderScript prey) { moving = true; navMeshAgent.speed = movementStates[currentState].moveSpeed; navMeshAgent.angularSpeed = movementStates[currentState].turnSpeed; navMeshAgent.SetDestination(prey.transform.position); float timeMoving = 0f; bool gotAway = false; while ((navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance || timeMoving < 0.1f) && timeMoving < stamina) { navMeshAgent.SetDestination(prey.transform.position); timeMoving += Time.deltaTime; if (Vector3.Distance(transform.position, prey.transform.position) < 2f) { if (logChanges) { Debug.Log(string.Format("{0}: Caught prey ({1})!", gameObject.name, prey.gameObject.name)); } if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } AttackAnimal(prey); yield break; } if (constainedToWanderZone && Vector3.Distance(transform.position, origin) > wanderZone) { gotAway = true; navMeshAgent.SetDestination(transform.position); break; } yield return(null); } navMeshAgent.SetDestination(transform.position); if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } if (timeMoving > stamina || prey.dead || Vector3.Distance(transform.position, prey.transform.position) > scent || gotAway) { BeginIdleState(); } else { ChaseAnimal(prey); } }
private void BeginChase(WanderScript chasingAnimal) { if (attacking) { return; } StartCoroutine(ChaseCheck(chasingAnimal)); }
private void GetAttacked(WanderScript attacker) { if (attacking) { return; } if (logChanges) { Debug.Log(string.Format("{0}: Getting attacked by {1}!", gameObject.name, attacker.gameObject.name)); } StopAllCoroutines(); StartCoroutine(TurnToLookAtTarget(attacker.transform)); if (ScriptableAnimalStats.agression > 0) { if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } AttackAnimal(attacker); } else { if (moving) { if (useNavMesh) { navMeshAgent.SetDestination(transform.position); } else { targetLocation = transform.position; } if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } moving = false; } else { if (currentState < idleStates.Length && idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool)) { animator.SetBool(idleStates[currentState].animationBool, false); } else { animator.SetBool(movementStates[currentState].animationBool, false); } } } }
private IEnumerator ChaseCheck(WanderScript chasingAnimal) { while (Vector3.Distance(transform.position, chasingAnimal.transform.position) > awareness) { yield return(new WaitForSeconds(0.5f)); } StopAllCoroutines(); if (moving) { if (useNavMesh) { navMeshAgent.SetDestination(transform.position); } else { targetLocation = transform.position; } if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } moving = false; } else { if (currentState < idleStates.Length && idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool)) { animator.SetBool(idleStates[currentState].animationBool, false); } else { animator.SetBool(movementStates[currentState].animationBool, false); } } // BUG FIX - 这里频繁调用,在SpatialOS下,可能会导致堆栈溢出。Aug.1.2019. Liu Gang. //DecideNextState(false); }
private IEnumerator NonNavMeshRunAwayState(Vector3 target, WanderScript predator) { currentTurnSpeed = movementStates[currentState].turnSpeed; float walkTime = 0f; float timeUntilAbortWalk = Vector3.Distance(transform.position, target) / movementStates[currentState].moveSpeed; float currentStamina = stamina; while (Vector3.Distance(transform.position, target) > contingencyDistance && walkTime < timeUntilAbortWalk && stamina > 0) { characterController.SimpleMove(transform.TransformDirection(Vector3.forward) * movementStates[currentState].moveSpeed); Vector3 relativePos = target - transform.position; Quaternion rotation = Quaternion.LookRotation(relativePos); transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * (currentTurnSpeed / 10)); currentTurnSpeed += Time.deltaTime; walkTime += Time.deltaTime; stamina -= Time.deltaTime; yield return(null); } targetLocation = Vector3.zero; if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } if (stamina <= 0 || predator.dead || Vector3.Distance(transform.position, predator.transform.position) > awareness) { BeginIdleState(); } else { NonNavMeshRunAwayFromAnimal(predator); } }
private void RunAwayFromAnimal(WanderScript predator) { moving = true; Quaternion startRotation = transform.rotation; transform.rotation = Quaternion.LookRotation(transform.position - predator.transform.position); Vector3 areaAwayFromPredator = transform.position + transform.forward * 5f; NavMeshHit hit; NavMesh.SamplePosition(areaAwayFromPredator, out hit, 5, 1 << NavMesh.GetAreaFromName("Walkable")); Vector3 target = hit.position; transform.rotation = startRotation; if (constainedToWanderZone && Vector3.Distance(target, origin) > wanderZone) { target = RandonPointInRange(); } int fastestMovementState = 0; for (int i = 0; i < movementStates.Length; i++) { if (movementStates[i].moveSpeed > movementStates[fastestMovementState].moveSpeed) { fastestMovementState = i; } } currentState = fastestMovementState; if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } StartCoroutine(RunAwayState(target, predator)); }
private IEnumerator NonNavMeshChaseState(WanderScript prey) { moving = true; targetLocation = prey.transform.position; currentTurnSpeed = movementStates[currentState].turnSpeed; float walkTime = 0f; bool gotAway = false; float timeUntilAbortWalk = Vector3.Distance(transform.position, targetLocation) / movementStates[currentState].moveSpeed; float currentStamina = stamina; while (Vector3.Distance(transform.position, targetLocation) > contingencyDistance && walkTime < timeUntilAbortWalk && stamina > 0) { characterController.SimpleMove(transform.TransformDirection(Vector3.forward) * movementStates[currentState].moveSpeed); targetLocation = prey.transform.position; Vector3 relativePos = targetLocation - transform.position; Quaternion rotation = Quaternion.LookRotation(relativePos); transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * (currentTurnSpeed / 10)); currentTurnSpeed += Time.deltaTime; walkTime += Time.deltaTime; stamina -= Time.deltaTime; if (Vector3.Distance(transform.position, prey.transform.position) < 2f) { if (logChanges) { Debug.Log(string.Format("{0}: Caught prey ({1})!", gameObject.name, prey.gameObject.name)); } if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } AttackAnimal(prey); yield break; } if (constainedToWanderZone && Vector3.Distance(transform.position, origin) > wanderZone) { gotAway = true; targetLocation = transform.position; break; } yield return(null); } targetLocation = Vector3.zero; if (!string.IsNullOrEmpty(movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } if (stamina <= 0 || prey.dead || Vector3.Distance(transform.position, prey.transform.position) > scent || gotAway) { BeginIdleState(); } else { ChaseAnimal(prey); } }