|
#pragma strict |
|
|
|
// Customizable |
|
var detectionRange : float = 25.0; // Set from spawn script |
|
var updateSkip : float = 5.0; |
|
var aSpeed : float = 70; |
|
var hostile : boolean = false; |
|
var player : boolean = false; |
|
|
|
private var curVec : Vector2 = Vector2.zero; |
|
private var instructionUpdate : int = 0; |
|
private var lastAngle : float = 0; |
|
private var lastSpeed : float = 0; |
|
|
|
function Start () { |
|
// Set player color |
|
if (player) { |
|
renderer.material.color = Color.green; |
|
|
|
// Set hostile color |
|
} else if (hostile) { |
|
renderer.material.color = Color.red; |
|
} |
|
} |
|
|
|
function Update () { |
|
var posV3 : Vector3 = transform.position; |
|
var posV2 : Vector2 = Vector2( posV3.x, posV3.z ); |
|
var speed : float = aSpeed; |
|
var angle : float; |
|
|
|
// Influence / Acceleration |
|
var inf : float = 0.02; |
|
if (hostile) inf = 0.05; |
|
|
|
// Get data for surrounding agents |
|
// ------------------------------------------- |
|
if (instructionUpdate <= 0 || player) { |
|
instructionUpdate = updateSkip*Random.value; |
|
|
|
// Friendly |
|
var fNum : int = 0; |
|
var fAverage : Vector2 = Vector2.zero; |
|
var fDistance : float = 1000; |
|
var fAgent : Rigidbody; |
|
|
|
// Enemy |
|
var eDistance : float = 1000; |
|
var eAgent : Rigidbody; |
|
|
|
// Get all objects touching or in range |
|
var colliders : Collider[] = Physics.OverlapSphere( posV3, detectionRange ); |
|
|
|
// Check agents in proximity |
|
for (var crossAgent : Collider in colliders) { |
|
// avoid wrong references |
|
if (!crossAgent) continue; |
|
if (!crossAgent.rigidbody) continue; |
|
if (rigidbody == crossAgent.rigidbody) continue; |
|
|
|
// Get cross brain |
|
var crossBrain : AgentBrain4 = crossAgent.GetComponent( AgentBrain4 ) as AgentBrain4; |
|
if (!crossBrain) continue; |
|
|
|
// Check distance |
|
var crossDistance : float = (posV3 - crossAgent.rigidbody.position).magnitude; |
|
|
|
// Is Hostile |
|
if (crossBrain.hostile || crossBrain.player) { |
|
// Closest hostile |
|
if (crossDistance < eDistance) { |
|
eDistance = crossDistance; |
|
eAgent = crossAgent.rigidbody; |
|
|
|
// Hostile too close: Suicide |
|
if (!hostile && crossBrain.hostile && eDistance < 2) { |
|
Destroy( gameObject ); |
|
return; |
|
} |
|
} |
|
// Is Friendly |
|
} else { |
|
fAverage += Vector2( crossAgent.rigidbody.position.x, crossAgent.rigidbody.position.z ); |
|
fNum++; |
|
// Closest friendly |
|
if (crossDistance < fDistance) { |
|
fDistance = crossDistance; |
|
fAgent = crossAgent.rigidbody; |
|
} |
|
} |
|
} |
|
|
|
// Behavior |
|
// ------------------------------------------- |
|
var crossPosV2 : Vector2; |
|
fAverage.x = fAverage.x / fNum; |
|
fAverage.y = fAverage.y / fNum; |
|
|
|
// Player |
|
// ------------------ |
|
if (player) { |
|
// Stay apart |
|
if (eDistance < 1.5) { |
|
crossPosV2 = Vector2( eAgent.position.x, eAgent.position.z ); |
|
angle = getAngle( crossPosV2, posV2 ) +45; |
|
speed *= 1.3; |
|
|
|
// Go to mouse position |
|
} else { |
|
var ray : Ray = Camera.main.ScreenPointToRay( Input.mousePosition ); |
|
var hit : RaycastHit; |
|
// Ray cast hit |
|
if (Physics.Raycast( ray, hit )) { |
|
var hitV2 : Vector2 = Vector2( hit.point.x, hit.point.z ); |
|
angle = getAngle( hitV2, posV2 ) -90; |
|
speed *= 1.3; |
|
inf = 0.20; |
|
} |
|
} |
|
|
|
// Predator |
|
// ------------------ |
|
} else if (hostile) { |
|
var curSpeed : float = Mathf.Abs(rigidbody.velocity.x + rigidbody.velocity.z); |
|
|
|
if ( fAgent ) { |
|
// Predator: Single target |
|
if ( fNum < 5 || fDistance < 4 ) { |
|
// Change color |
|
if (renderer.material.color != Color.blue) renderer.material.color = Color.blue; |
|
// Set angle |
|
crossPosV2 = Vector2( fAgent.position.x, fAgent.position.z ); |
|
angle = getAngle( crossPosV2, posV2 ) -90; |
|
speed *= 1.4; |
|
inf = 0.20; |
|
|
|
// Predator: Multi target |
|
} else { |
|
// Change color |
|
if (renderer.material.color != Color.red) renderer.material.color = Color.red; |
|
// Set angle |
|
angle = getAngle( fAverage, posV2 ) -90; |
|
speed *= 1.3; |
|
inf = 0.10; |
|
} |
|
|
|
// Predator: Circulate |
|
} else { |
|
// Set angle |
|
angle = getAngle( Vector2.zero, posV2 ) -140; // -30; |
|
speed *= 1.1; |
|
// Change color |
|
if (renderer.material.color != Color.yellow) renderer.material.color = Color.yellow; |
|
} |
|
|
|
// Prey |
|
// ------------------ |
|
} else { |
|
// Prey: Enemy nearby |
|
if ( eDistance < 20 ) { |
|
// Escape enemy |
|
crossPosV2 = Vector2( eAgent.position.x, eAgent.position.z ); |
|
angle = getAngle( crossPosV2, posV2 ) +100; |
|
speed *= 1.2; |
|
inf = 0.10; |
|
|
|
// Prey: Friendly nearby |
|
} else if ( fAgent ) { |
|
// Distance to average position |
|
var fAvgDist : float = (posV3 - Vector3(fAverage.x, 0, fAverage.y)).magnitude; |
|
|
|
// When close, align vectors |
|
if (fAvgDist < 12) { |
|
angle = getAngle( Vector2.zero, posV2 ) -45; |
|
speed *= 0.8; |
|
|
|
// When far apart, go closer |
|
} else { |
|
angle = getAngle( fAverage, posV2 ) -90; |
|
speed *= 1.2; |
|
} |
|
|
|
// Prey: Circulate |
|
} else { |
|
// Go to zero |
|
angle = getAngle( Vector2.zero, posV2 ) -90; |
|
} |
|
} |
|
|
|
// Store instructions |
|
lastAngle = angle; |
|
lastSpeed = speed; |
|
} else { |
|
// Get last instructions |
|
instructionUpdate--; |
|
angle = lastAngle; |
|
speed = lastSpeed; |
|
} |
|
|
|
// Movement |
|
// ------------------------------------------- |
|
var goalVec : Vector2 = Vector2.zero; |
|
|
|
// Goal Vector |
|
lastAngle = lastAngle + transform.eulerAngles.y; |
|
goalVec.x = Mathf.Sin( Mathf.Deg2Rad * lastAngle ) *lastSpeed; |
|
goalVec.y = Mathf.Cos( Mathf.Deg2Rad * lastAngle ) *-lastSpeed; |
|
|
|
// New Vector |
|
curVec.x = influence(goalVec.x, curVec.x, inf); |
|
curVec.y = influence(goalVec.y, curVec.y, inf); |
|
|
|
var grav = 0; |
|
if (posV3.y > 0.5) grav = -5; |
|
else transform.position.y = 0.5; |
|
|
|
// Apply Movment |
|
rigidbody.velocity = transform.TransformDirection(Vector3( curVec.x, grav, curVec.y )); |
|
|
|
// Fallen off the world, reset |
|
if (posV3.y < -50) { |
|
print('Resetting position'); |
|
transform.position = Vector3(0,5,0); |
|
} |
|
} |
|
|
|
|
|
// ------------------------------------------- |
|
function influence( value1 : float, value2 : float, inf : float ) { |
|
var aInf : float = 1-inf; |
|
return (value1*inf) + (value2*aInf); |
|
} |
|
|
|
|
|
// ------------------------------------------- |
|
function getAngle( obj1 : Vector2, obj2 : Vector2 ) { |
|
var deltaX : float = obj2.x - obj1.x; |
|
var deltaY : float = obj2.y - obj1.y; |
|
var value : float = Mathf.Atan2( deltaY, deltaX ); |
|
value = ( value * Mathf.Rad2Deg ); |
|
return value; |
|
} |
|
|
|
|