ETeeskiTutorials AI Path Finding Tutorial Scripts FPS1.41

Click here to see the first person shooter tutorial, FPS1.41
Here are all the scripts used in FPS1.41 to affect the behavior of the enemies. Also, there is a zip file of the project.

FPS1.41 zip file:
924256–34634–$FPS1.41.zip (19.4 MB)

AIpathCellScript:

var doors = new Array();

function OnTriggerEnter (other : Collider)
{
	if (other.tag == "AIpathDoor")
		doors.Add(other.gameObject);
}

AIpathDoorScirpt;

var cells = new Array();
var doorsToCells = new Array();
var imediateCells = new Array();
var testForCells : boolean = true;
var waitToTestCells : float = 2;
var stage : int = 1;

var animatedDoor : GameObject;
@HideInInspector
var doorOpen : boolean = true;

function Awake () 
{
	doorOpen = true;
	cells = GameObject.FindGameObjectsWithTag("AIpathCell");
	doorsToCells.length = cells.length;
	testForCells = true;
	waitToTestCells = 2;
	stage = 1;
}

function Update () 
{
	if (animatedDoor)
		doorOpen = animatedDoor.GetComponent(DoorScript).open;

	if (testForCells  waitToTestCells <= 0)
	{
		for (var imediateCell : GameObject in imediateCells)
		{
			for (var i : int = 0; i <= cells.length - 1; i++)
			{
				if (cells[i] == imediateCell)
					doorsToCells[i] = 1;
			}
		}
		
		for (stage = 2; stage <= cells.length; stage++)
		{
			for (i = 0; i <= cells.length - 1; i++)
			{
				if (doorsToCells[i] == stage - 1)
					for (var checkDoor : GameObject in cells[i].GetComponent(AIpathCellScript).doors)
					{
						if (checkDoor != gameObject)
						{
							for (var checkCell : GameObject in checkDoor.GetComponent(AIpathDoorScript).imediateCells)
							{
								for (var j : int = 0; j <= cells.length - 1; j++)
								{
									if (cells[j] == checkCell  doorsToCells[j] == null)
										doorsToCells[j] = stage;
								}
							}
						}
					}
			}
		}
		
		testForCells = false;
		Debug.Log(doorsToCells);
	}
	waitToTestCells -= 1;
}

function OnTriggerEnter (other : Collider)
{
	if (other.tag == "AIpathCell")
		imediateCells.Add(other.gameObject);
}

BulletScript:

var maxDist : float = 1000000000;
var decalHitWall : GameObject;
var floatInFrontOfWall : float = 0.00001;
var damage : float = 1;
var bulletForce : float = 1000;

function Update () 
{
	var hit : RaycastHit;
	if (Physics.Raycast(transform.position, transform.forward, hit))
	{
		if (decalHitWall  hit.transform.tag == "Level Parts")
			Instantiate(decalHitWall, hit.point + (hit.normal * floatInFrontOfWall), Quaternion.LookRotation(hit.normal));
		if (hit.transform.tag == "EnemyBodyPart")
		{
			if (hit.transform.GetComponent(EnemyBodyPartScript).enemyBody.GetComponent(EnemyBodyScript).enemyHealth > damage * hit.transform.GetComponent(EnemyBodyPartScript).damageMultiplyer)
				hit.transform.GetComponent(EnemyBodyPartScript).enemyBody.GetComponent(EnemyBodyScript).enemyHealth -= damage * hit.transform.GetComponent(EnemyBodyPartScript).damageMultiplyer;
			else
			{
				hit.transform.GetComponent(EnemyBodyPartScript).enemyBody.GetComponent(EnemyBodyScript).enemyHealth -= damage * hit.transform.GetComponent(EnemyBodyPartScript).damageMultiplyer;
				hit.transform.GetComponent(EnemyBodyPartScript).addForceVector = transform.forward * bulletForce;
			}
		}
	}
	Destroy(gameObject);
}

EnemyBodyPartScript;

var enemyBody : GameObject;
var addForceVector : Vector3;
var damageMultiplyer : float = 1;

function Update () 
{
	if (addForceVector != Vector3.zero  !enemyBody.GetComponent(EnemyBodyScript).enabled)
	{
		if (rigidbody)
			rigidbody.AddForce(addForceVector);
		else
			transform.parent.rigidbody.AddForce(addForceVector);
		addForceVector = Vector3.zero;
	}
}

EnemyBodyScript:

var moveDamp : float = 0.1;
var parentToFollow : Transform;
var parentLastPos : Vector3;
var targetRotation : Quaternion;
var turnSpeed : float = 10;

var velocityX : float;
var velocityZ : float;

var parentScript : EnemyMovementScript;
var walkAnimationString : String;
var runAnimationString : String;

var enemyHealth : float = 1;
var rigidbodies : Rigidbody[];

function Awake ()
{
	parentScript = transform.parent.GetComponent(EnemyMovementScript);
	animation.wrapMode = WrapMode.Loop;
	parentToFollow = transform.parent;
	transform.parent = null;
}

function Update () 
{
	transform.position.x = Mathf.SmoothDamp(transform.position.x, parentToFollow.position.x, velocityX, moveDamp);
	transform.position.z = Mathf.SmoothDamp(transform.position.z, parentToFollow.position.z, velocityZ, moveDamp);
	
	var tempParentCurrentPos : Vector3 = parentToFollow.position;
	var tempParentLastPos : Vector3 = parentLastPos;
	tempParentCurrentPos.y = 0;
	tempParentLastPos.y = 0;
	
	targetRotation = Quaternion.LookRotation(tempParentCurrentPos - tempParentLastPos);
	parentLastPos = parentToFollow.position;
	
	transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
	
	var hits : RaycastHit[];
	hits = Physics.RaycastAll(Ray(transform.position + Vector3(0,100,0), Vector3.up * -1));
	for (var i : int = 0; i < hits.length; i++)
	{
		var hit : RaycastHit = hits[i];
		if (hit.transform.gameObject == parentToFollow.gameObject.GetComponent(EnemyMovementScript).currentCell)
			transform.position.y = hit.point.y;
	}
	
	if (!animation.IsPlaying(walkAnimationString)  !parentScript.aware)
		animation.Play(walkAnimationString);
	if (!animation.IsPlaying(runAnimationString)  parentScript.aware)
		animation.Play(runAnimationString);
		
	if (enemyHealth <= 0)
	{
		for (var rigidbodyFor in rigidbodies)
			rigidbodyFor.isKinematic = false;
		animation.enabled = false;
		parentScript.enabled = false;
		enabled = false;
	}
}

EnemyMovementScript:

var currentCell : GameObject;
var playerMovementScript : PlayerMovementScript;
var playerTransform : Transform;
var playerCell : GameObject;
var goalDoor : GameObject;
var shortestPathSoFar : float;
@HideInInspector
var waitToStart : int = 5;
var maxMoveSpeed : float = 5;
var minMoveSpeed : float = 1;
var speedDamage : float = 0.5;
var speedRecover : float = 1;
var currentMoveSpeed : float = 5;

var randomizedCourse : boolean = false;
var randomizeCourseVector : Vector3;
var calculatedNewRandomizeCourseVector : boolean;

var lastPos : Vector3;

var viewAngle : float = 60;
var aware : boolean = false;
var unawareSpeed : float = 1;



function Awake ()
{
	shortestPathSoFar = Mathf.Infinity;
	playerMovementScript = GameObject.FindWithTag("Player").GetComponent(PlayerMovementScript);
	playerTransform = GameObject.FindWithTag("Player").transform;
	waitToStart = 5;
	randomizeCourseVector = transform.position;
	lastPos = transform.position;
	aware = false;
}

function Update () 
{
	if (waitToStart <= 0)
	{
		playerCell = playerMovementScript.currentCell;
		for (var doorCheckingNow : GameObject in currentCell.GetComponent(AIpathCellScript).doors)
		{
			for (var i : int = 0; i <= doorCheckingNow.GetComponent(AIpathDoorScript).cells.length - 1; i++)
			{
				if (doorCheckingNow.GetComponent(AIpathDoorScript).cells[i] == playerCell)
				if (doorCheckingNow.GetComponent(AIpathDoorScript).doorsToCells[i] < shortestPathSoFar)
				{
					goalDoor = doorCheckingNow;
					shortestPathSoFar = doorCheckingNow.GetComponent(AIpathDoorScript).doorsToCells[i];
				}
			}
		}
		shortestPathSoFar = Mathf.Infinity;
	}
	waitToStart -= 1;
	
	var hits : RaycastHit[];
	var anyHit : boolean = false;
	if (Vector3.Angle(transform.forward, playerTransform.position - transform.position) < viewAngle / 2  !aware)
	{
		hits = Physics.SphereCastAll(transform.position, transform.localScale.x / 3, playerTransform.position - transform.position, Vector3.Distance(transform.position, playerTransform.position));
		for (var hit : RaycastHit in hits)
		{
			if (hit.transform.tag == "Level Parts")
				anyHit = true;
		}
		if (!anyHit)
			aware = true;
	}
	
	if (!aware)
		goalDoor = null;
	
	if (!calculatedNewRandomizeCourseVector)
	{
		randomizeCourseVector = FindRandomSpotInCurrentCell();
		calculatedNewRandomizeCourseVector = true;
	}
	
	if (goalDoor)
	if (!goalDoor.GetComponent(AIpathDoorScript).doorOpen)
		goalDoor = null;
	
	if (currentCell != playerCell || playerCell == null || !aware)
	{
		if (randomizedCourse  goalDoor)
			transform.position += (goalDoor.transform.position - transform.position).normalized * currentMoveSpeed * Time.deltaTime;
		if (!randomizedCourse)
		{
			transform.position += (randomizeCourseVector - transform.position).normalized * currentMoveSpeed * Time.deltaTime;
			if (Vector3.Distance(transform.position, randomizeCourseVector) < transform.localScale.x)
			{
				if (goalDoor)
					randomizedCourse = true;
				if (goalDoor == null)
					calculatedNewRandomizeCourseVector = false;
			}
		}
	}
		
	if (playerCell == currentCell  aware)
		transform.position += (playerTransform.position - transform.position).normalized * currentMoveSpeed * Time.deltaTime;
	
	if (currentMoveSpeed < maxMoveSpeed  aware)
		currentMoveSpeed += speedRecover * Time.deltaTime;
	if (currentMoveSpeed > maxMoveSpeed  aware)
		currentMoveSpeed = maxMoveSpeed;

	if (currentMoveSpeed < unawareSpeed  !aware)
		currentMoveSpeed += speedRecover * Time.deltaTime;
	if (currentMoveSpeed > unawareSpeed  !aware)
		currentMoveSpeed = unawareSpeed;
		
	transform.rotation = Quaternion.LookRotation(transform.position - lastPos);
	lastPos = transform.position;
}

function OnTriggerEnter (hitTrigger : Collider)
{
	if (hitTrigger.tag == "AIpathCell")
	{
		currentCell = hitTrigger.gameObject;
		randomizedCourse = false;
		calculatedNewRandomizeCourseVector = false;
	}
}

function OnTriggerStay (hitTrigger : Collider)
{
	if (hitTrigger.tag == "Enemy"  hitTrigger.gameObject != gameObject)
	{
		if (currentMoveSpeed > minMoveSpeed)
			currentMoveSpeed -= speedDamage;
		transform.position += (transform.position - hitTrigger.transform.position).normalized * 0.1;
	}
}

function FindRandomSpotInCurrentCell ()
{
	return currentCell.transform.position + (currentCell.transform.rotation * Vector3(Random.Range(currentCell.transform.localScale.x * -0.5,currentCell.transform.localScale.x * 0.5),0,Random.Range(currentCell.transform.localScale.z * -0.5,currentCell.transform.localScale.z * 0.5)));
}

PlayerMovementScript:

var currentGun : GameObject;
var distToPickUpGun : float = 6;
var throwGunUpForce : float = 100;
var throwGunForwardForce : float = 300;
var waitFrameForSwitchGuns : int = -1;

var walkAcceleration : float = 5;
var walkAccelAirRacio : float = 0.1;
var walkDeacceleration : float = 5;
@HideInInspector
var walkDeaccelerationVolx : float;
@HideInInspector
var walkDeaccelerationVolz : float;

var cameraObject : GameObject;
var maxWalkSpeed : float = 20;
@HideInInspector
var horizontalMovement : Vector2;

var jumpVelocity : float = 20;
@HideInInspector
var grounded : boolean = false;
var maxSlope : float = 60;

var crouchRacio : float = 0.3;
var transitionToCrouchSec : float = 0.2;
var crouchingVelocity : float;
var currentCrouchRacio : float = 1;
var originalLocalScaleY : float;
var crouchLocalScaleY : float;
var collisionDetectionSphere : GameObject;

@HideInInspector
var waitToPickupAmmo : float = 0;

var currentCell : GameObject;

function Awake ()
{
	currentCrouchRacio = 1;
	originalLocalScaleY = transform.localScale.y;
	crouchLocalScaleY = transform.localScale.y * crouchRacio;
}

function LateUpdate () 
{
	waitFrameForSwitchGuns -= 1;
	waitToPickupAmmo -= Time.deltaTime;
	
	transform.localScale.y = Mathf.Lerp(crouchLocalScaleY, originalLocalScaleY, currentCrouchRacio);
	if (Input.GetButton("Crouch"))
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 0, crouchingVelocity, transitionToCrouchSec);
	if (Input.GetButton("Crouch") == false  collisionDetectionSphere.GetComponent(CollsionDetectionSphereScript).collisionDetected == false)
		currentCrouchRacio = Mathf.SmoothDamp(currentCrouchRacio, 1, crouchingVelocity, transitionToCrouchSec);
	
	horizontalMovement = Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
	if (horizontalMovement.magnitude > maxWalkSpeed)
	{
		horizontalMovement = horizontalMovement.normalized;
		horizontalMovement *= maxWalkSpeed;		
	}
	
	rigidbody.velocity.x = horizontalMovement.x;
	rigidbody.velocity.z = horizontalMovement.y;
	
	if (grounded){
		rigidbody.velocity.x = Mathf.SmoothDamp(rigidbody.velocity.x, 0, walkDeaccelerationVolx, walkDeacceleration);
		rigidbody.velocity.z = Mathf.SmoothDamp(rigidbody.velocity.z, 0, walkDeaccelerationVolz, walkDeacceleration);}
	
	transform.rotation = Quaternion.Euler(0, cameraObject.GetComponent(MouseLookScript).currentYRotation, 0);
	
	/*if (grounded)
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * Time.deltaTime);
	else
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio * Time.deltaTime, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio * Time.deltaTime);
			*/
	if (Input.GetButtonDown("Jump")  grounded)
		rigidbody.AddForce(0,jumpVelocity,0);
}

function FixedUpdate ()
{
	if (grounded)
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration, 0, Input.GetAxis("Vertical") * walkAcceleration);
	else
		rigidbody.AddRelativeForce(Input.GetAxis("Horizontal") * walkAcceleration * walkAccelAirRacio, 0, Input.GetAxis("Vertical") * walkAcceleration * walkAccelAirRacio);
}

function OnCollisionStay (collision : Collision)
{
	for (var contact : ContactPoint in collision.contacts)
	{
		if (Vector3.Angle(contact.normal, Vector3.up) < maxSlope)
			grounded = true;
	}
}

function OnCollisionExit ()
{
	grounded = false;
}

function OnTriggerExit ()
{
	currentCell = null;
}

function OnTriggerStay (hitTrigger : Collider)
{
	if (hitTrigger.tag == "AIpathCell")
		currentCell = hitTrigger.gameObject;

	if (hitTrigger.transform.tag == "StairGoingUp")
		if (!Input.GetButton("Jump")  Vector3.Angle(rigidbody.velocity, hitTrigger.transform.forward) < 90)
			if (rigidbody.velocity.y > 0)
				rigidbody.velocity.y = 0;
	if (hitTrigger.transform.tag == "StairGoingDown")
		if (!Input.GetButton("Jump")  Vector3.Angle(rigidbody.velocity, hitTrigger.transform.forward) < 90)
			rigidbody.AddForce(0,-100,0);


	var current : GunScript = null;
	if (currentGun)
		current = currentGun.GetComponent(GunScript);
	var ammo : AmmoPickupScript = null;
	var gun : GunScript = null;
	if (hitTrigger.tag == "AmmoPickup"  waitToPickupAmmo <= 0)
	{
		ammo = hitTrigger.gameObject.GetComponent(AmmoPickupScript);
		if (current.currentExtraAmmo < current.maxExtraAmmo)
		{
			if (ammo.fromGun)
			{
				gun = ammo.gun.GetComponent(GunScript);
				if (gun.currentExtraAmmo > 0  gun.ammoType == current.ammoType  ammo.gun != currentGun)
				{
					if (gun.currentExtraAmmo >= current.maxExtraAmmo - current.currentExtraAmmo)
					{
						gun.currentExtraAmmo -= current.maxExtraAmmo - current.currentExtraAmmo;
						current.currentExtraAmmo = current.maxExtraAmmo;
					}
					if (gun.currentExtraAmmo < current.maxExtraAmmo - current.currentExtraAmmo)
					{
						current.currentExtraAmmo += gun.currentExtraAmmo;
						gun.currentExtraAmmo = 0;
					}
					if (ammo.pickupSound)
						ammo.gameObject.GetComponent(AudioSource).Play();
				}
			}
			if (!ammo.fromGun)
			{
				if (current.ammoType == ammo.ammoType || ammo.ammoType == -1)
				{
					if (ammo.ammoAmount > 0  !ammo.unlimitedAmmo)
					{
						if (ammo.ammoAmount >= current.maxExtraAmmo - current.currentExtraAmmo)
						{
							ammo.ammoAmount -= current.maxExtraAmmo - current.currentExtraAmmo;
							current.currentExtraAmmo = current.maxExtraAmmo;
						}
						if (ammo.ammoAmount < current.maxExtraAmmo - current.currentExtraAmmo)
						{
							current.currentExtraAmmo += gun.currentExtraAmmo;
							ammo.ammoAmount = 0;
						}
						if (ammo.pickupSound)
							ammo.gameObject.GetComponent(AudioSource).Play();
					}
					if (ammo.unlimitedAmmo)
					{
						current.currentExtraAmmo = current.maxExtraAmmo;
						if (ammo.pickupSound)
							ammo.gameObject.GetComponent(AudioSource).Play();
					}
				}
			}
		}
	}
}

hey ETeeskiTutorials got a problem with that .addForceVector
my gameobject is just a cube with no body parts so its not in a array…

unity say its:
MissingFieldException: Field ‘target.addForceVector’ not found.
Boo.Lang.Runtime.DynamicDispatching.PropertyDispatcherFactory.FindExtension (IEnumerable`1 candidates)
Boo.Lang.Runtime.DynamicDispatching.PropertyDispatcherFactory.Create (SetOrGet gos)
Boo.Lang.Runtime.DynamicDispatching.PropertyDispatcherFactory.CreateSetter ()
Boo.Lang.Runtime.RuntimeServices.DoCreatePropSetDispatcher (System.Object target, System.Type type, System.String name, System.Object value)
Boo.Lang.Runtime.RuntimeServices.CreatePropSetDispatcher (System.Object target, System.String name, System.Object value)
Boo.Lang.Runtime.RuntimeServices+c__AnonStorey16.<>m__C ()

the code i used is this:
var maxDist : float = 1000000000;
var decalHitWall : GameObject;
var floatInFrontOfWall : float = 0.00001;
var damage : float = 20;
var bulletForce : float = 600;

function Update ()
{
var hit : RaycastHit;
if (Physics.Raycast(transform.position, transform.forward, hit, maxDist))
{
if (decalHitWall hit.transform.tag == “Level Parts”)
Instantiate(decalHitWall, hit.point + (hit.normal * floatInFrontOfWall), Quaternion.LookRotation(hit.normal));
if(hit.transform.tag == “targets”){
if(hit.transform.GetComponent(target).targetHealth > damage)
hit.transform.GetComponent(target).targetHealth -= damage;
else
{
hit.transform.GetComponent(target).targetHealth -= damage;
hit.transform.GetComponent(target).addForceVector = transform.forward * bulletForce;
}
}
}
Destroy(gameObject);
}

theres not much of a difference but what am i missing here… =<