- Home /
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?
Answer by Seth-Bergman · Oct 01, 2012 at 02:47 AM
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 ;)
Seth, your advice has worked perfectly! Everything is working exactly how I wanted it to. Thank you so much for your help, this problem's been driving me crazy. I really appreciate it.
Answer by Sundar · Oct 01, 2012 at 03:00 AM
Try this
void OnTriggerEnter(Collider other) {
if( other.gameObject.GetComponent<officerAI>() )
other.gameObject.GetComponent<officerAI>().jump();
else print( "No officerAI component found" );
}
}
Your answer
Follow this Question
Related Questions
OnTriggerStay and OnTriggerEnter won't react when the player enters them. 1 Answer
getComponent not working with Triggers? 1 Answer
Distribute terrain in zones 3 Answers
OnTriggerEnter questions 2 Answers
Error in..."calling"(?) script 0 Answers