private IEnumerator RunAwayState(Vector3 target, Common_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 MakeAttack(Common_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 (attackingStates.Length > 0 && !string.IsNullOrEmpty(attackingStates[currentState].animationBool)) { if (animator.parameters.Any(x => x.name == attackingStates[currentState].animationBool)) { animator.SetBool(attackingStates[currentState].animationBool, false); } } attackingEvent.Invoke(); StopAllCoroutines(); DecideNextState(false); }
private void AttackAnimal(Common_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; } currentState = Random.Range(0, attackingStates.Length); if (attackingStates.Length > 0) { if (!string.IsNullOrEmpty(attackingStates[currentState].animationBool)) { if (animator.parameters.Any(x => x.name == attackingStates[currentState].animationBool)) { animator.SetBool(attackingStates[currentState].animationBool, true); } } } StartCoroutine(MakeAttack(target)); }
private IEnumerator ChaseState(Common_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(Common_WanderScript chasingAnimal) { if (attacking) { return; } StartCoroutine(ChaseCheck(chasingAnimal)); }
private void GetAttacked(Common_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 (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 (idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool)) { animator.SetBool(idleStates[currentState].animationBool, false); } } } }
private IEnumerator ChaseCheck(Common_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)) { if (animator.parameters.Any(x => x.name == movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, false); } } moving = false; } else { if (idleStates.Length - 1 >= currentState) { if (idleStates.Length > 0 && !string.IsNullOrEmpty(idleStates[currentState].animationBool)) { if (animator.parameters.Any(x => x.name == idleStates[currentState].animationBool)) { animator.SetBool(idleStates[currentState].animationBool, false); } } } } DecideNextState(false); }
private void RunAwayFromAnimal(Common_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)) { if (animator.parameters.Any(x => x.name == movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } } StartCoroutine(RunAwayState(target, predator)); }
private void ChaseAnimal(Common_WanderScript prey) { Vector3 target = prey.transform.position; prey.BeginChase(this); if (movementStates.Length <= 0) { Debug.Log("Movement states length is 0"); this.enabled = false; return; } 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)) { if (animator.parameters.Any(x => x.name == movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } } if (useNavMesh) { StartCoroutine(ChaseState(prey)); } else { StartCoroutine(NonNavMeshChaseState(prey)); } }
private IEnumerator NonNavMeshRunAwayState(Vector3 target, Common_WanderScript predator) { currentTurnSpeed = movementStates[currentState].turnSpeed; float walkTime = 0f; float timeUntilAbortWalk = Vector3.Distance(transform.position, target) / movementStates[currentState].moveSpeed; 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)) { if (animator.parameters.Any(x => x.name == 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 NonNavMeshRunAwayFromAnimal(Common_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)) { if (animator.parameters.Any(x => x.name == movementStates[currentState].animationBool)) { animator.SetBool(movementStates[currentState].animationBool, true); } } StartCoroutine(NonNavMeshRunAwayState(targetLocation, predator)); }
private IEnumerator NonNavMeshChaseState(Common_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; 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); } }
public override void OnInspectorGUI() { Common_WanderScript myWanderScript = (Common_WanderScript)target; serializedObject.Update(); //Get Lists SerializedProperty idleStates = serializedObject.FindProperty("idleStates"); SerializedProperty movementStates = serializedObject.FindProperty("movementStates"); SerializedProperty attackingStates = serializedObject.FindProperty("attackingStates"); SerializedProperty deathStates = serializedObject.FindProperty("deathStates"); //Death Unity Event SerializedProperty deathEvent = serializedObject.FindProperty("deathEvent"); SerializedProperty attackingEvent = serializedObject.FindProperty("attackingEvent"); SerializedProperty idleEvent = serializedObject.FindProperty("idleEvent"); SerializedProperty movementEvent = serializedObject.FindProperty("movementEvent"); //Get Strings SerializedProperty species = serializedObject.FindProperty("species"); //Get Stats SerializedProperty stats = serializedObject.FindProperty("stats"); //Get AI Controls SerializedProperty wanderSize = serializedObject.FindProperty("wanderZone"); SerializedProperty awareness = serializedObject.FindProperty("awareness"); SerializedProperty scent = serializedObject.FindProperty("scent"); SerializedProperty constainedToWanderZone = serializedObject.FindProperty("constainedToWanderZone"); SerializedProperty nonAgressiveTowards = serializedObject.FindProperty("nonAgressiveTowards"); SerializedProperty surfaceRotationSpeed = serializedObject.FindProperty("surfaceRotationSpeed"); SerializedProperty matchSurfaceRotation = serializedObject.FindProperty("matchSurfaceRotation"); ///DEBUG SerializedProperty logChanges = serializedObject.FindProperty("logChanges"); SerializedProperty showGizmos = serializedObject.FindProperty("showGizmos"); SerializedProperty drawWanderRange = serializedObject.FindProperty("drawWanderRange"); SerializedProperty drawScentRange = serializedObject.FindProperty("drawScentRange"); SerializedProperty drawAwarenessRange = serializedObject.FindProperty("drawAwarenessRange"); //Load a Texture (Assets/Resources/Textures/texture01.png) var mainTexture = Resources.Load <Texture2D>("WanderScriptLogo"); //Main Image GUILayout.BeginHorizontal(); if (GUILayout.Button(mainTexture)) { Application.OpenURL("https://assetstore.unity.com/?q=Polyperfect&orderBy=0"); } GUILayout.EndHorizontal(); //Draw The Species Name EditorGUILayout.PropertyField(species); EditorGUILayout.PropertyField(stats); if (GUILayout.Button("Show Animation States", GUILayout.MaxWidth(Screen.width - 30))) { AnimationStates = !AnimationStates; } if (AnimationStates) { GUILayout.BeginHorizontal(); //GUILayout.Label(idleTexture); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(idleStates, true); GUILayout.BeginHorizontal(); //GUILayout.Label(movementTexture); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(movementStates, true); GUILayout.BeginHorizontal(); //GUILayout.Label(attackingTexture); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(attackingStates, true); GUILayout.BeginHorizontal(); //GUILayout.Label(deathTexture); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(deathStates, true); } if (GUILayout.Button("Show State Unity Events", GUILayout.MaxWidth(Screen.width - 30))) { StateEvents = !StateEvents; } if (StateEvents) { var width = GUILayout.MaxWidth(Screen.width); EditorGUILayout.PropertyField(idleEvent, width); EditorGUILayout.PropertyField(movementEvent, width); EditorGUILayout.PropertyField(attackingEvent, width); EditorGUILayout.PropertyField(deathEvent, width); } if (GUILayout.Button("Show AI Controls", GUILayout.MaxWidth(Screen.width - 30))) { AIControls = !AIControls; } if (AIControls) { GUILayout.BeginHorizontal(); //GUILayout.Label(AITexture); GUILayout.EndHorizontal(); EditorGUILayout.PropertyField(wanderSize); EditorGUILayout.PropertyField(awareness); EditorGUILayout.PropertyField(scent); EditorGUILayout.PropertyField(constainedToWanderZone); EditorGUILayout.PropertyField(nonAgressiveTowards, true); EditorGUILayout.PropertyField(matchSurfaceRotation, true); EditorGUILayout.PropertyField(surfaceRotationSpeed, true); } if (GUILayout.Button("Show DEBUG Options", GUILayout.MaxWidth(Screen.width - 30))) { DEBUGToggle = !DEBUGToggle; } if (DEBUGToggle) { EditorGUILayout.PropertyField(logChanges); EditorGUILayout.PropertyField(showGizmos); EditorGUILayout.PropertyField(drawWanderRange); EditorGUILayout.PropertyField(drawScentRange); EditorGUILayout.PropertyField(drawAwarenessRange, true); } serializedObject.ApplyModifiedProperties(); //DrawDefaultInspector(); }