GeorgeGularte
[email protected]
  • Home
  • Blog
  • Projects
  • Resume

Sample Code

flock.cs
File Size: 5 kb
File Type: cs
Download File

Flocking

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class flock : MonoBehaviour 
{
	private float c_attration = 5f;
    private float c_repulsion = 10f;
    
    //ignoring the 'ground' layer to avoid collisions with ground
    public int collisionMask = 8;

    //private
    float m_fMoveSpeed;  
    float m_fRepelRange;  
    float m_fDetectRange;
    
	Color m_repelColor  = Color.cyan;
    Color m_detectColor = Color.cyan;

    public List m_detectionList = new List();
    
    // in case of game objects with multiple components, counts number of objets at start
    int numObjects = 1;
    
    // Use this for initialization
    void Start()
    {
         m_fMoveSpeed   = 5.0f;
		 m_fRepelRange  = 5f;  
		 m_fDetectRange = 10f; //10
		 numObjects += transform.childCount;
    }
    
    void FixedUpdate()
    {
        Overlap();

        Move( transform.InverseTransformDirection( sumOfForces() ) + MoveToEnemy() );
		
        RotateToEnemy();
    }
	
	Vector3 MoveToEnemy()
	{
		Vector3 direction =  Player.GetThisPlayer().gameObject.transform.position - transform.position;
		
		return direction.normalized * 1000 ;
	}


    /*
     * Does range detection and creates a list of transforms that are within specified ranges
     * collision mask is included to ignore the ground, for loops added to ignore self-collisions
     */
    void Overlap()
    {
        Collider[] detects = Physics.OverlapSphere(transform.position, m_fDetectRange, ~(1 << collisionMask));
		
		m_detectionList.Clear();
        
        //in detection range, ignore number of overlaps equal to number of gameobjects
		//print (detects.Length);
        //if (detects.Length > numObjects)
        {
            //adding to detection list
            for (int i = 0; i < detects.Length; ++i)
			{
                if (!detects[i].transform.IsChildOf(gameObject.transform))// && detects[i].tag != "neutral" ) 
                {
                    m_detectionList.Add(detects[i].transform);

                    Vector3 direction = detects[i].transform.position - transform.position;
                    float distance    = direction.magnitude;
                   
					if (distance <= m_fRepelRange)
                        m_repelColor = Color.red;
                    else
                    	m_repelColor = Color.cyan;
				}
            }
        }
		if (m_detectionList.Count > 0)
        {
            m_detectColor = Color.red;
        }
        else
        {
            m_detectColor = Color.cyan;
        }
		
	}

     Vector3 sumOfForces()
    {
        Vector3 sumForce   = Vector3.zero;
        Vector3 sumAttract = Vector3.zero;
        Vector3 sumRepolst = Vector3.zero;
        int attractionCounter = 1;

        for (int i = 0; i < m_detectionList.Count; ++i)
        {
            Vector3 direction = m_detectionList[i].position - transform.position;
            
            float distance = direction.magnitude;
            
            direction.Normalize();

            if (distance <= m_fRepelRange)
            {
                direction *= -1;
                sumRepolst += (direction * c_repulsion) / (distance * distance); //REPEL FORCE
            }
            else if (gameObject.CompareTag(m_detectionList[i].tag))
            {
                float neutralZone = .3f * (m_fDetectRange - m_fRepelRange) + m_fRepelRange;
                if (distance > neutralZone)
                {   // if your outside of the nretural range
                    sumAttract += (direction * c_attration) / (distance * distance); //Atraction FORCE
                    attractionCounter++;
                }
            }
            else
            {
				direction *= -1;
                sumRepolst += (direction * c_repulsion) / (distance * distance); //runaway
			}
        }
        sumForce = (sumAttract / attractionCounter) + sumRepolst;
        sumForce.y = 0;
        return sumForce;
    }
    
    public void Move(Vector3 dir)
    {
        float s = dir.magnitude < m_fMoveSpeed ? dir.magnitude : m_fMoveSpeed;
        dir.Normalize();
        transform.Translate(dir * s * Time.deltaTime);
    }
    
    void OnDrawGizmos()
    {
        //visualize detection and repel range
        Gizmos.color = m_repelColor;
        Gizmos.DrawWireSphere(transform.position, m_fRepelRange);

        Gizmos.color = m_detectColor;
        Gizmos.DrawWireSphere(transform.position, m_fDetectRange);
    }

    void RotateToEnemy()
    {
        if(m_detectionList.Count<=0)
			return;

        float bestDist = 1e30f;
        Vector3 bestPos = Vector3.zero;

        for (int i = 0; i < m_detectionList.Count; ++i)
        {
            if ( m_detectionList[i].gameObject.tag == "Player") 
            {
                Vector3 currentEnemy = m_detectionList[i].position - transform.position;
                float dist = currentEnemy.magnitude;
                if (dist <= bestDist)
                {
                    bestPos = m_detectionList[i].position;
                    bestDist = dist;
                }
            }
        }

        bestPos.y = 0;
        transform.LookAt(bestPos);
    }
}
Powered by Create your own unique website with customizable templates.