AI characters don't work in Web Export

When I Play my game in the editor or export it to Windows Standalone the AI characters I have will work as they should and follow my player around etc.

When I export to the Web Player however, the AI characters walk on the spot and seem to be ‘stuck’ in place. They do not shoot or any of that either, just walking on the spot.

Any ideas as to why this would work in Editor/Windows Standalone, yet not in the Web Player?

Thanks.

Do you have external data files that might not be getting loaded?

hmm I’m really not sure. Everthing is the same as I usually have them…

Could you perhaps give an example of an external data file that I could be using and not loading? I’m not 100% sure I know what you are referring to :stuck_out_tongue:

Thanks!

Anything using File.Load or StreamReaders etc. Searching for System.IO will show you classes which may be using local File IO.

Thanks for the suggestion :wink: I checked it though out and that sort of thing doesn’t seem to be the culprit here…

What I have noticed is that it seems as though my AI characters are not recognising my ‘Player’ object as thier ‘target’. I’m a bit confused as to how this would be different in the Web Player compared with the Windows Stand Alone export…

This is the script I am using for my AI. The ‘target’ variable is what I’m looking at. I notice that if I physically drag the ‘Player’ prefab onto the target variable slot in my gui I get the same result as what I see in the Web Player export. Basically that variable get set in the code so it seems to only work if I don’t physically drag the prefab onto it, only if it’s empty in the Inspector??

Yet if I ensure the AI character’s Target IS empty in inspector, it won’t work in Web Export but will in windows export and in the editor?

Perhaps someone can take a look at this code and tell me if i’m missing something here? Or is there something differnt in the web exporter that I’m unaware of?

var speed = 3.0;
var rotationSpeed = 5.0;
var swingRange = 5.0;
var attackRange = 30.0;
//var swingAngle = 30.0;
var dontComeCloserRange = 4.0;
var delaySwingTime = 0.5;
//var pickNextWaypointDistance = 2.0;
var target : Transform;

var damage = 1;
var wackingSound : AudioClip;
var wackingSoundVolume : float = 2.0;

private var lastSwing = -10.0;

// Make sure there is always a character controller
@script RequireComponent (CharacterController)

function Start () 
{
	// Auto setup player as target through tags
	if (target == null  GameObject.FindWithTag("Player"))
		target = GameObject.FindWithTag("Player").transform;

	Patrol();
	
}




function Patrol () 
{
	while (true) 
	{
		if (CanSeeTarget ())
		{
			yield StartCoroutine("AttackPlayer");
		}
		
		yield;
	}
}


function CanSeeTarget () : boolean 
{
	if (Vector3.Distance(transform.position, target.position) > attackRange)
		return false;
		
	var hit : RaycastHit;
	if (Physics.Linecast (transform.position, target.position, hit))
		return hit.transform == target;

	return false;
}

function Melee () 
{
	// Start swinging ("attack") animation
	//animation.CrossFade("attack, 0.3");
	Debug.Log("running melee");
	animation.Play("attack");
	//send a damage message to the hit object
	Debug.Log("damage was:  " + damage);

	// Wait until half the animation has played
	yield WaitForSeconds(delaySwingTime);		//make this the time it takes to backswing.
	
	// Wait for the rest of the animation to finish
	yield WaitForSeconds(animation["attack"].length - delaySwingTime);
	target.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver); 
	
	if (wackingSound)
		AudioSource.PlayClipAtPoint(wackingSound, transform.position, wackingSoundVolume);
}


function AttackPlayer () 
{
	var lastVisiblePlayerPosition = target.position;
	
	while (true) 
	{
		if (CanSeeTarget ()) 
		{
			// Target is dead - stop hunting
			if (target == null)
				return;

			// Target is too far away - give up	
			var distance = Vector3.Distance(transform.position, target.position);
			
			if (distance > attackRange * 3)
				return;
			
			lastVisiblePlayerPosition = target.position;
			
			if (distance > dontComeCloserRange)
			{
				MoveTowards (lastVisiblePlayerPosition);
			}
			else
			{
				RotateTowards(lastVisiblePlayerPosition);
			}
			
			var forward = transform.TransformDirection(Vector3.forward);
			var targetDirection = lastVisiblePlayerPosition - transform.position;
			targetDirection.y = 0;

			var angle = Vector3.Angle(targetDirection, forward);

			// Starting if close and player is in sight
			//if (distance <= swingRange  angle <= swingAngle)
			if (distance <= swingRange)
				yield StartCoroutine("Melee");
				
		yield;		
		} 
		else 
		{
			yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
			// Player not visible anymore - stop attacking
			if (!CanSeeTarget ())
				return;
		}
	}
}

function SearchPlayer (position : Vector3) 
{
	// Run towards the player but after 3 seconds timeout and go back to Patroling
	var timeout = 3.0;
	while (timeout > 0.0) 
	{
		MoveTowards(position);

		// We found the player
		if (CanSeeTarget ())
			return;

		timeout -= Time.deltaTime;
		yield;
	}
}

function RotateTowards (position : Vector3) 
{
//	SendMessage("SetSpeed", 0.0);							//don't know what this does???
	
	var direction = position - transform.position;
	direction.y = 0;
	if (direction.magnitude < 0.1)
		return;
	
	// Rotate towards the target
	transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
	transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}

function MoveTowards (position : Vector3) 
{
	var direction = position - transform.position;
	direction.y = 0;
	if (direction.magnitude < 0.5) 
	{
//		SendMessage("SetSpeed", 0.0);
		return;
	}
	
	// Rotate towards the target
	transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
	transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

	// Modify speed so we slow down when we are not facing the target
	var forward = transform.TransformDirection(Vector3.forward);
	var speedModifier = Vector3.Dot(forward, direction.normalized);
	speedModifier = Mathf.Clamp01(speedModifier);

	// Move the character
	direction = forward * speed * speedModifier;
	GetComponent (CharacterController).SimpleMove(direction);
	
	//SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}

Fixed it.
Problem was quite hard to find. I had added my original character with the tag ‘Player’ to another prefab which I gave the tag ‘Player’ also with out thinking about it.

When I took the ‘Player’ tag off of the first prefab set and left it on the top level prefab it works.

I’ve no idea why it would work in the Editor and Windows Standalone but not in Web Player the way that it was, but there you go. I’m just glad it’s resolved.