AI through meshes + SphereCollider problem

Mesh issue:
AI has a RigidBody and a CharacterController.

Mesh only has a mesh collider.Mesh has a small bump/hill like adjustment in the middle, the AI slopes upwards fine, but at the top point they walk through it towards the player. AI also walks through walls with box colliders.

To stop AI going through walls/hills/meshes, is there an easy way without raycasting? If I must use raycasting, is there an easy tutorial because I get confused reading other people’s raycasting scripts.

If I can get the tagging script system working correctly for the sphere collider section below this section, then I only need to raycast/stop AI from walking through hills/etc on the Y axis I believe.

SphereCollider issue:
AI is using a sphere collider, if player moves into it then it’ll target the player and move towards. If player is out of range, AI moves back to spawn Position unless Player walks back within range.

Issue: If one enemy2 is following the player, and the player is inside this enemy2’s sphere collider, after the other enemy1 has walked back to spawn position, if enemy2’s sphere collider touches enemy1’s sphere collider, then enemy1 will activate towards the player.

Sphere collider script:

private var AIScript:AIMelee;
private var BackOff:AIReturnToSpawnPos;

function Awake() {
    var sc : SphereCollider;
    sc = this.gameObject.AddComponent ("SphereCollider");
    sc.radius = 10;
    sc.isTrigger = true;

    AIScript = GetComponent(AIMelee);
    AIScript.enabled = false;
	
	BackOff = GetComponent(AIReturnToSpawnPos);
	BackOff.enabled = false;
	
	rigidbody.Sleep();
}

function OnTriggerEnter(other:Collider){
    if(other.tag == "Player");
	AIScript.enabled = true;
	BackOff.enabled = false;
}

function OnTriggerExit(other:Collider){
    if(other.tag == "Player");
	AIScript.enabled = false;
	BackOff.enabled = true;
	}

AI Enemy2’s script:

var TargetPlayer : Transform; //Target Player
var Self : Transform; //Target AI's Self
var speed = 2.0; //Variable for speed
var lockPos = 0; //Variable for locking rotation position
var maxDistance = 1.5; //Maximum distance to move to at Player
var gravityForce = 20;

public var controller : CharacterController;

function Update() {
    transform.LookAt(TargetPlayer.position); //Tells object to look at and move to the target's XYZ Position
    if(Vector3.Distance(TargetPlayer.position, Self.position) > maxDistance) /*Keeps AI distance from Player*/ {
	transform.position += speed * Time.deltaTime * transform.forward; //Mathematics for speed  tells object to only move forward at target
	controller.Move( Vector3(0, controller.velocity.y - gravityForce * Time.deltaTime, 0) * Time.deltaTime); //Applies Gravity to physic component char controller
	transform.rotation = Quaternion.Euler(lockPos, lockPos, lockPos); //Stops object from rotating in all positions
	transform.position.y=56.28055; //Stops object from moving upwards (jumping) in y position any further from set value	
	}
}

Enemy2’s BackOff (return to spawn position) code:

private var spawnPos : Vector3;
private var spawnRot : Quaternion;
var speed = 3.0; //Variable for speed
var lockPos = 0; //Variable for locking rotation position

private function Awake()
{
    spawnPos = transform.position;
    spawnRot = transform.rotation;
}

function Update ()
{
		transform.LookAt(spawnPos);
		transform.position += speed * Time.deltaTime * transform.forward;
		transform.rotation = Quaternion.Euler(lockPos, lockPos, lockPos); //Stops object from rotating upwards in y position
}

Issue aside, I’m also thinking, if you can have one enemy off the sidelines to fight at a time, that it won’t provide the desired effect I want.

I’m not sure how to do this myself, and need a little help.

Lets say I put a cube with (isTrigger, mesh off) around where the enemies are, if the player walks within this cube, it activates all enemies to target player, if Player runs away, then all enemies return to position.

Please see the second edit of my second post on this thread in bold for an update on this section.

Thanks!

Bump? I still can’t get the cube to be a trigger for all enemies to attack the player rather than each enemy having their own individual spherecollider.

I was thinking of using the tag “Enemies” or a group/prefab “enemyMob”, anyway I’m stuck on how to format this with gameObject.GetComponent and how to link it to those enemies.

I’m also trying to call the scripts AIScript:AIRanged and BackOff:AIReturnToSpawnPos from the enemies, as the scripts are attached individually to each enemy.

var AIScript:AIRanged;
var BackOff:AIReturnToSpawnPos;
//var enemyMob : Transform;

function Awake() {
	enemyMob = gameObject.GetComponent(Transform);
	enemyMob = gameObject.transform;
	
    AIScript =  gameObject.GetComponent(enemyMob.AIRanged);
    AIScript.enabled = false;
	
	BackOff =  gameObject.GetComponent(AIReturnToSpawnPos);
	BackOff.enabled = false;
	
	rigidbody.Sleep();
}

function OnTriggerEnter(other:Collider){
    if(other.tag == "Player");
	AIScript.enabled = true;
	BackOff.enabled = false;
}

/*function OnTriggerExit(other:Collider){
    if(other.tag == "Player");
	AIScript.enabled = false;
	BackOff.enabled = true;
	}*/

Edit: Think I got the box collider working, had a syntax issue.

AIScript = gameObject.GetComponent(enemyMob(AIRanged));

works while

AIScript = gameObject.GetComponent(enemyMob.AIRanged);

this doesn’t.

Will experiment some more. Would like a tag system to be implemented however, so that I don’t have to select every enemy individually within the script.

Edit:

I want to have all enemies target the player by their tag, however the enemies need to be linked in the inspector in order to link their attack scripts. Is it possible to get these scripts based on tag alone and not individually on every enemy?

var AIRangedScript:AIRanged;
var AIMeleeScript:AIMelee;
var BackOff:AIReturnToSpawnPos;

function Awake() {
/*	enemyMob = gameObject.GetComponent.FindWithTag("Enemy");
	enemyMob = gameObject.transform; */
	
	var enemyMob = GameObject.FindWithTag("Enemy");
	
	enemyMob.GetComponent(AIMelee);
	AIMeleeScript.enabled = false;
	
	enemyMob.GetComponent(AIRanged);
	AIRangedScript.enabled = false;
	
	enemyMob.GetComponent(AIReturnToSpawnPos);
	BackOff.enabled = false;
	
	rigidbody.Sleep();
}

function OnTriggerEnter(other:Collider){
    if(other.tag == "Player");
	AIMeleeScript.enabled = true;
	AIRangedScript.enabled = true;
	BackOff.enabled = false;
}

function OnTriggerExit(other:Collider){
    if(other.tag == "Player");
	AIMeleeScript.enabled = false;
	AIRangedScript.enabled = false;
	BackOff.enabled = true;
	}

With my AI that I made for one of my games, I basically made it so the AI got the object with tag ‘player’, then checked the distance between the player and the AI. If the player was within the AI’s aggro range, the AI would approach the player to ‘attack’. No need to use colliders.

Although that doesn’t have the desired effect I’m aiming for, say you have a platform, instead of making invisible barriers to stop AI from falling off, they stay within the trigger collider. That scenario aside, I don’t want the player being able to pick off a couple or one by one at a time based on AI range from the player.

So, my question/problem remains. I need to be able to call script names by Enemy tag rather than by transform and dragging each enemy individually in the inspector to this trigger so it knows where to find the scripts.