Here is an ai for seagulls. They fly around, land, and take off similar to actual birds. A world can easily be populated with these birds to bring more "life" into the environment.
Full Code Here
// Code by Nick Barber using System.Collections; using System.Collections.Generic; using UnityEngine; public class SeagullAi : MonoBehaviour { float RNG; Vector3 FlyingDirection; Vector3 landingPoint; Vector3 LandingRot; Vector3 TakeoffDirection; bool flying; bool landing; public float Speed; public float YawSpeed; public float PitchSpeed; public Transform player; void Start(){ StartCoroutine(Timer()); } IEnumerator Timer(){ //run every second, randomly generates a vector and float for use in navigation and rng do{ RaycastHit hit; Vector3 groundview = transform.TransformDirection(Vector3.down); float newyaw; if (transform.position.y < 8 || Physics.Raycast(transform.position, groundview, out hit, 20)){ //too close to ground newyaw = -10.0f; } else if (transform.position.y > 80){ // too high newyaw = 5.0f; } else{ newyaw = Random.Range(-5.0f, 5.0f); } FlyingDirection = new Vector3(newyaw, Random.Range(0, 360),0); RNG = Random.Range(0, 100); //used for percent chance yield return new WaitForSeconds(1); } while (1==1); } void FixedUpdate(){ if (flying){ Speed = 10; if (RNG > 90 && transform.position.y > 20 && Vector3.Distance(transform.position, player.position) > 20){ //randomly choose a landing point, if the timing is correct, you arnt near the player, and you are high enough in the sky FindLandingPoint(); GetComponent().Play("Armature|Wing Flap"); } //Flying maths Vector3 NewAngle = new Vector3(Mathf.LerpAngle(transform.eulerAngles.x, FlyingDirection.x, Time.deltaTime * PitchSpeed), Mathf.LerpAngle(transform.eulerAngles.y, FlyingDirection.y, Time.deltaTime * YawSpeed), 0); transform.eulerAngles = NewAngle; transform.Translate(Vector3.forward * Time.deltaTime * Speed); } else if (landing){ Speed = 8; if (Vector3.Distance(transform.position, landingPoint) > 0.1f){ //rotate and fly towards desired landing position while you are not close enough to land Vector3 Target = landingPoint - transform.position; Quaternion ToRotation = Quaternion.FromToRotation(Vector3.forward, Target); transform.rotation = Quaternion.Lerp(transform.rotation, ToRotation, Time.deltaTime * 1f); transform.Translate(Vector3.forward * Time.deltaTime * Speed); } else{ //stick to the ground where you wanted to land GetComponent ().Play("Armature|land"); transform.eulerAngles = LandingRot; transform.position = landingPoint; if (RNG > 95 || Vector3.Distance(transform.position, player.position) < 10){ //wait to takeoff, can be intrupted by a player "shooing" you away GetTakeOffDirection(); landing = false; } } } else{ //take off Speed = 10; if (Vector3.Distance(transform.position, landingPoint) < 20){ transform.rotation = Quaternion.LookRotation(TakeoffDirection); transform.Translate(Vector3.forward * Time.deltaTime * Speed); } else{ flying = true; landing = false; } } } void FindLandingPoint(){ //search for a landing point Vector3 desiredLandingPoint; int Distance= 50; RaycastHit Hit3; desiredLandingPoint = new Vector3(Random.Range(transform.position.x - Distance, transform.position.x + Distance), transform.position.y, Random.Range(transform.position.z - Distance, transform.position.z + Distance)); Debug.DrawRay (desiredLandingPoint, Vector3.down * 100, Color.blue); if (Physics.Raycast(desiredLandingPoint, Vector3.down, out Hit3, 100)){ if (Hit3.transform.tag != "UnderWater" && Hit3.transform.tag != "Water" && Hit3.transform.tag != "Boat" && Hit3.transform.tag != "PickUp" && Hit3.transform.tag != "Untagged"){ landingPoint = Hit3.point; LandingRot = Hit3.normal; flying = false; landing = true; return; } } return; } void GetTakeOffDirection(){ //find a direction that is free to take off RaycastHit hit; TakeoffDirection = transform.TransformDirection(Vector3.forward); TakeoffDirection.y += 0.5f; Vector3 Above = transform.position; Above.y += 1; int timesTried = 0; do { Debug.DrawRay (Above, TakeoffDirection * 50, Color.red); if (Physics.Raycast(Above, TakeoffDirection, out hit, 50)){ TakeoffDirection = Quaternion.Euler(0, -10, 0) * TakeoffDirection; } else{ GetComponent ().Play("Armature|Wing Flap"); flying = false; landing = false; return; } timesTried++; } while (timesTried < 100); print(name + " is stuck!"); Destroy(gameObject); return; } }
No comments:
Post a Comment