U3d_ artificial Intelligence [II] bird swarm behavior _ Artificial Intelligence

Source: Internet
Author: User
Tags time interval
1. Bird swarm behavior, three forces as the focus
    The birds move in one direction and give them a target in the game, and when they fly toward the target, if the code simply lets the birds move toward the target and then moves forward, it can cause the birds to crowd, especially after reaching the target point where the birds flock together.
    The effect we want to achieve is:
    1. Birds do not gather together (separation force)
    2. Birds are not the same in the direction of each individual, but the overall direction is to move to the target point (Team Lieli)
    3. Individual birds are not too far from the big team (gathering force)
    and some other behavior .
    Since it is force to influence speed, it is necessary to use Newton's second law: F=ma here m is our own definition of size and does not change, so F is proportional to a. Three forces are divided, and the ultimate influence on the birds is the resultant force of the three forces.
2. Separation Force
    Public Vector3 velocity=vector3.forward;//Current speed public
    Vector3 sumforce=vector3.zero;//resultant force public
    float m = 1;/ /Quality public

    list<gameobject> separationneighbors = new list<gameobject> ()//To store a game object in scope that requires a function of separation force Public
    float separationdistion=3;//Separation Force inspection range Public
    Vector3 separationforce=vector3.zero;//separation Force
    public float Separationweight = weight of 1;//separation force
    The separation force is determined by the distance between itself and the surrounding bird, and the direction is in the opposite direction to the other birds.
    First, check out a certain range of birds which
collider[] colliders = Physics.overlapsphere (transform.position, separationdistion);//The first argument is the center of the ball, and the second parameter is the radius of the shot. Return all collider to the collision
        ///will get all collider game objects into the list
        foreach (collider C in colliders)
        {
            if (c!= null & & C.gameobject!= This.gameobject)
            {
                separationneighbors.add (c.gameobject);
            }
        }
    After acquiring the bird around itself, the smaller the distance between each bird and itself, the greater the separation force, the direction of which is the detected bird pointing to the bird.
        All objects in the list give Thisgameobject a force
        foreach (gameobject neighbor in separationneighbors)
        {
            Vector3 dir = transform.position-neighbor.transform.position;//here is a vector, from the target bird point to the bird, length of two birds distance
            Separationforce + = Dir.normalized/dir.magnitude;//dir.normalized is to normalized the direction (that is, the direction is constant, the length becomes 1), the dir.magnitude is to get the length of the vector
        }
        // The separation force changes the joint
        if (Separationneighbors.count > 0)
        {
            separationforce *= separationweight;
            Sumforce + + Separationforce;
        }
3. Queue Force
    Public list<gameobject> alignmentneighbors = new list<gameobject> ()//The game object used to store the queue force used in the range is public
    Float alignmentdistance = Check range of 6;//queue Force public
    Vector3 aligmentforce=vector3.zero;//Queue Force public
    float Alignmentweight = weight of 1;//queue force
    Again, first check the birds around the bird, but the scope of this check needs to be larger.
        colliders = Physics.overlapsphere (transform.position, alignmentdistance);
        foreach (collider C in colliders)
        {
            if (c.gameobject!= null && c.gameobject!=)
            {this.gameobject />alignmentneighbors.add (C.gameobject);
            }
        
    and calculate the overall direction of the nearby birds.
        Vector3 avgdir=vector3.zero;//stores the average direction of all neighbors
        foreach (Gameobject neighber in alignmentneighbors)
        {
            Avgdir + = neighber.transform.forward;//Add all the neighbors ' directions.
        
    And this bird needs to adjust to the general direction, it is the vector of knowledge-vector a minus vector b to get a vector from B to point A. (the average of the vector in the direction of the nearby bird) minus the direction of the bird, the longer the vector gets, the greater the separation force.
        if (Alignmentneighbors.count > 0)
        {
            Avgdir/= alignmentneighbors.count;//average direction
            Aligmentforce = avgdir-transform.forward;//calculates the queue force (vector knowledge)
            aligmentforce *= alignmentweight;
            Sumforce + + Aligmentforce;
        }
4. Aggregation Force
    Public Vector3 cohesionforce=vector3.zero;//Aggregation Force public
    float cohesionweight = 1;//weight
    The aggregation force can be directly used to check the range of the queue force, the same use of vector knowledge to obtain the center of the nearby birds-the direction vector of nearby birds divided by the number of nearby birds, is the center point, we let the bird force to the center point near
        Aggregation force if
        (alignmentneighbors.count <= 0) return;//If there are no neighbors nearby
        Vector3 center = vector3.zero;//All Neighbors ' central point
        foreach (gameobject n in alignmentneighbors)
        {
            Center = n.transform.position;
        }
        Center/= Alignmentneighbors.count;
        Vector3 dirtocenter = center-transform.position;//A vector from this point to the center point, the vector length can be used as the size of the strength
        cohesionforce + = Dirtocenter;
        Sumforce + = Cohesionforce;
5. Final effect
    The effect of each force is very bad, but after use, the effect can be qualitative change. Do some other processing, such as setting an endpoint called Target, so that all the birds animation start playing a different point of time, it will not appear monotonous. Next post the full code:
Using Unityengine;
Using System.Collections;

Using System.Collections.Generic;

    public class Crowai:monobehaviour {public gameobject target;//Bird Group target public float targetweight = 1;//Target Force weight

    Public Vector3 velocity=vector3.forward;//Current speed public Vector3 sumforce=vector3.zero;//resultant force public float m = 1;//quality Public list<gameobject> separationneighbors = new list<gameobject> ()//is used to store objects in the scope that need to be decoupled. Public Flo  At separationdistion=3;//separation Force Inspection range Public Vector3 separationforce=vector3.zero;//separation Force public float separationweight =
    1;//the weight of the separation force public list<gameobject> alignmentneighbors = new list<gameobject> ()//to store the range of game objects that require the queue force public float alignmentdistance = Check range of 6;//queue Force public Vector3 aligmentforce=vector3.zero;//Queue Force public float ALIGNM

    Entweight = 1;//The weight of the queue force public Vector3 cohesionforce=vector3.zero;//Aggregation Force public float cohesionweight = 1;//weight Public float checkinterval=0.2f;//Check time interval private Animation animation;//Flying Animation//Use this for initialization void Start () {invokerepeating ("Calcforce", 0, Checkinterva L)//from 0 seconds after every checkinterval seconds to execute the Calcforce method animation = getcomponentinchildren<animation> ();//Get animation in 
    Voke ("Playeranim", Random.range (0, 2f));//Play animation at different times///<summary>///play animation///</summary> void Playeranim () {animation.
    Play ();
        } void Calcforce () {sumforce = Vector3.zero; 
        Separationforce = vector3.zero;//separation force Aligmentforce = vector3.zero;//queue force Cohesionforce = vector3.zero;//Aggregation Force
        Separationneighbors.clear ();
        Alignmentneighbors.clear (); collider[] colliders = Physics.overlapsphere (transform.position, separationdistion);//The first argument is the center of the ball, and the second parameter is the radius of the shot.  Return all collider to the collision///will get all collider game objects into the list foreach (Collider C in colliders) {if (c
 != null && c.gameobject!= this.gameobject) {               Separationneighbors.add (C.gameobject);
            }//List all objects to thisgameobject a force foreach (Gameobject neighbor in separationneighbors) {
            Vector3 dir = transform.position-neighbor.transform.position;
        Separationforce + = Dir.normalized/dir.magnitude; }//Separation force change Joint if (Separationneighbors.count > 0) {separationforce *= Separationweigh
            T
        Sumforce + = Separationforce;
        } colliders = Physics.overlapsphere (transform.position, alignmentdistance); foreach (collider C in colliders) {if (C.gameobject!= null && c.gameobject!= THIS.GAMEOBJEC
            T) {Alignmentneighbors.add (c.gameobject); 
        } Vector3 avgdir=vector3.zero;//Store the average direction of all neighbors foreach (Gameobject neighber in alignmentneighbors) {Avgdir + = neighber.transform.forward;//Adds all the neighbors ' directions.
        } if (Alignmentneighbors.count > 0) {avgdir/= alignmentneighbors.count;//average direction
            Aligmentforce = avgdir-transform.forward;//Calculates the queue force (vector knowledge) Aligmentforce *= alignmentweight;
        Sumforce + = Aligmentforce; }//Aggregation force if (alignmentneighbors.count <= 0) return;//return Vector3 Center = vector3.z If there are no neighbors nearby
        ero;//all Neighbors ' central point foreach (gameobject n in alignmentneighbors) {center = n.transform.position;
        Center/= Alignmentneighbors.count;
        Vector3 dirtocenter = center-transform.position;//A vector from this point to the center point, the vector length can be used as the size of the strength cohesionforce + = Dirtocenter;

        Sumforce + = Cohesionforce;
        target = Gameobject.find ("target"). Gameobject; Vector3 TargetDir = target.transform.position-transform.position;//Get this point to the vector Sumforce = = (Targetdir.normali Zed-transform.forward) * Targetweight//The location of the target affects the resultant force}//UpdatE is called once per frame void Update () {Vector3 a = sumforce/m;//acceleration velocity = A * time.deltat
        Ime Let the crow's direction with the speed of the same direction, so that different speed direction will appear all kinds of changes, parameter one: this orientation; parameter two: This needs to be changed into direction, slowly changing towards transform.rotation = Quaternion.slerp (trans
        Form.rotation, quaternion.lookrotation (velocity), time.deltatime); Transform.
    Translate (Velocity * time.deltatime, space.world); }
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.