Wednesday, December 13, 2017

Seagull Ai 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;
}
}