C# - Problem with trigger that won't activate

Hello, I am working on a sidescrolling platformer where the player is chased by an AI police officer. What I’m trying to do is to make the police officer jump when he hits an invisible trigger. I only want the officer to set off the trigger, so not the player or anything else. My problem is that the trigger doesn’t seem to make him jump at all.

Here’s the code I have on my police officer:

using UnityEngine;
using System.Collections;
public class officerAI : MonoBehaviour {
	public float speed = 6.0F;
	public float jumpHeight = 8.0F;
	public float gravity = 20.0F;
	private Vector3 moveDirection = Vector3.zero;
	public void jump() {
			moveDirection.y = jumpHeight;
			}
	void Update() {
		CharacterController controller = GetComponent<CharacterController>();
		if (controller.isGrounded) {
			  moveDirection = Vector3.forward;
			  moveDirection = transform.TransformDirection(moveDirection);
			  moveDirection *= speed;			
		}
		
		moveDirection.y -= gravity * Time.deltaTime;
		controller.Move(moveDirection * Time.deltaTime);
	}
}

And here is the code I have on the trigger:

using UnityEngine;
using System.Collections;
public class jumptrigger : MonoBehaviour {
	void OnTriggerEnter(Collider other) {
		GameObject policeman = GameObject.Find("Police Officer");
		policeman.GetComponent<officerAI>().jump();
	}
}

It flat out doesnt do anything. At first, I thought something may have been wrong with accessing the jump command from the Officer AI script, so I tested it with this code to make him jump when the program starts:

using UnityEngine;
    using System.Collections;
    public class jumptrigger : MonoBehaviour {
    	void Start() {
    		GameObject policeman = GameObject.Find("Police Officer");
    		policeman.GetComponent<officerAI>().jump();
    	}
    }

This worked how it should have and made him jump as soon as the program started, so I knew it wasn’t a problem with accessing the jump code. I then decided to test the trigger itself by using the sample code the Unity Script Reference gives for OnTriggerEnter command which is this:

using UnityEngine;
using System.Collections;
public class jumptrigger : MonoBehaviour {
	void OnTriggerEnter(Collider other) {
		Destroy(other.gameObject);
	}
}

This code also worked as it would be expected to be, as the police officer disappeared as soon as he hit the trigger works. So, each individual thing works, but when I combine the trigger code with the jump code, nothing happens. I’m a beginner at unity scripting, so I’m sure this is some simple thing that I don’t get. What can I do to successfully get the officer to jump when he (and only he) touches the trigger?

the problem here is not that the trigger is not working, but rather faulty jump logic…

namely:

   if (controller.isGrounded) {
       moveDirection = Vector3.forward;
       moveDirection = transform.TransformDirection(moveDirection);
       moveDirection *= speed;         
   }

seems to me this may very well cancel out any changes made by calling your jump function, as it sets moveDirection to Vector3.forward EVERY FRAME, including the frame you called jump().

Maybe try adding a separate check to account for this such as an additional boolean, or as in the script reference:

http://docs.unity3d.com/Documentation/ScriptReference/CharacterController.Move.html

note that they adjust the y value after the other code… But, since triggers are executed prior to the update (as described here):

http://docs.unity3d.com/Documentation/Manual/ExecutionOrder.html

yours is simply being overridden…

adding a boolean to skip this one frame would probably be one simple fix:

private boolean jumping; // add this

public void jump() {
     jumping = true; // this...
   
     }

…(and in Update)

if (controller.isGrounded) {
       moveDirection = Vector3.forward;    
       moveDirection = transform.TransformDirection(moveDirection);
       moveDirection *= speed;   
       if(jumping){  // and this...
       moveDirection.y = jumpHeight;
       jumping = false;
       }
   }

…etc

that would probably fix your immediate issue…

also, let me point out one other thing:

void OnTriggerEnter(Collider other) {
   GameObject policeman = GameObject.Find("Police Officer");
   policeman.GetComponent<officerAI>().jump();
}

the part “(Collider other)” refers to the Collider component of the object colliding with the trigger, which is automatically passed in to the trigger function, so there is no need for using GameObject.Find here, it is more efficient to simply check the name or tag of the colliding object:

 void OnTriggerEnter(Collider other) {
   if(other.name == "Police Officer")
   other.gameObject.GetComponent<officerAI>().jump();
}

this will also ensure that other objects cannot set off your trigger :wink:

Try this

void OnTriggerEnter(Collider other) {

   if( other.gameObject.GetComponent<officerAI>() )

               other.gameObject.GetComponent<officerAI>().jump();

   else print( "No officerAI component found" );

}

}