Cannot detect trigger
Hello, i am fairly new to unity so any help is appreciated. I programmed an object to follow a predetermined path and i would like to make it change paths when collided with a trigger (using OnTriggerEnter()). I can't figure out what i am doing wrong. Also, sorry for the huge amount of code and annoying comments (they're not mine).
This is the script for the object to follow the path:
public class FollowPath : MonoBehaviour
{
#region Enums
public enum MovementType //Type of Movement
{
MoveTowards,
LerpTowards
}
#endregion //Enums
#region Public Variables
public MovementType Type = MovementType.MoveTowards; // Movement type used
public MovementPath MyPath; // Reference to Movement Path Used
public MovementPath NewPath;
public float Speed = 1; // Speed object is moving
public float MaxDistanceToGoal = .1f; // How close does it have to be to the point to be considered at point
#endregion //Public Variables
#region Private Variables
private IEnumerator<Transform> pointInPath; //Used to reference points returned from MyPath.GetNextPathPoint
#endregion //Private Variables
// (Unity Named Methods)
#region Main Methods
public void Start()
{
//Make sure there is a path assigned
if (MyPath == null)
{
Debug.LogError("Movement Path cannot be null, I must have a path to follow.", gameObject);
return;
}
//Sets up a reference to an instance of the coroutine GetNextPathPoint
pointInPath = MyPath.GetNextPathPoint();
Debug.Log(pointInPath.Current);
//Get the next point in the path to move to (Gets the Default 1st value)
pointInPath.MoveNext();
Debug.Log(pointInPath.Current);
//Make sure there is a point to move to
if (pointInPath.Current == null)
{
Debug.LogError("A path must have points in it to follow", gameObject);
return; //Exit Start() if there is no point to move to
}
//Set the position of this object to the position of our starting point
transform.position = pointInPath.Current.position;
}
//Update is called by Unity every frame
public void Update()
{
//Validate there is a path with a point in it
if (pointInPath == null || pointInPath.Current == null)
{
return; //Exit if no path is found
}
transform.LookAt(pointInPath.Current);//EU FIZ SAPORRA!
//Quaternion desiredRotation = Quaternion.LookRotation(pointInPath.Current.position);//Não consegui fazer
//transform.rotation = Quaternion.Lerp(transform.rotation, desiredRotation, 0.1f);//funcionar (ainda)
if (Type == MovementType.MoveTowards) //If you are using MoveTowards movement type
{
//Move to the next point in path using MoveTowards
transform.position =
Vector3.MoveTowards(transform.position,
pointInPath.Current.position,
Time.deltaTime * Speed);
}
else if (Type == MovementType.LerpTowards) //If you are using LerpTowards movement type
{
//Move towards the next point in path using Lerp
transform.position = Vector3.Lerp(transform.position,
pointInPath.Current.position,
Time.deltaTime * Speed);
}
//Check to see if you are close enough to the next point to start moving to the following one
//Using Pythagorean Theorem
//per unity suaring a number is faster than the square root of a number
//Using .sqrMagnitude
var distanceSquared = (transform.position - pointInPath.Current.position).sqrMagnitude;
if (distanceSquared < MaxDistanceToGoal * MaxDistanceToGoal) //If you are close enough
{
pointInPath.MoveNext(); //Get next point in MovementPath
}
//The version below uses Vector3.Distance same as Vector3.Magnitude which includes (square root)
/*
var distanceSquared = Vector3.Distance(transform.position, pointInPath.Current.position);
if (distanceSquared < MaxDistanceToGoal) //If you are close enough
{
pointInPath.MoveNext(); //Get next point in MovementPath
}
*/
}
public void OnTriggerEnter(Collider other)
{
MyPath = NewPath;
}
#endregion //Main Methods
//(Custom Named Methods)
#region Utility Methods
#endregion //Utility Methods
//Coroutines run parallel to other fucntions
#region Coroutines
#endregion //Coroutines
}
This is used to create the path:
public class MovementPath : MonoBehaviour
{
#region Enums
public enum PathTypes //Types of movement paths
{
linear,
loop
}
#endregion //Enums
#region Public Variables
public PathTypes PathType; //Indicates type of path (Linear or Looping)
public int movementDirection = 1; //1 clockwise/forward || -1 counter clockwise/backwards
public int movingTo = 0; //used to identify point in PathSequence we are moving to
public Transform[] PathSequence; //Array of all points in the path
#endregion //Public Variables
#region Private Variables
#endregion //Private Variables
// (Unity Named Methods)
#region Main Methods
//Update is called by Unity every frame
void Update()
{
}
//OnDrawGizmos will draw lines between our points in the Unity Editor
//These lines will allow us to easily see the path that
//our moving object will follow in the game
public void OnDrawGizmos()
{
//Make sure that your sequence has points in it
//and that there are at least two points to constitute a path
if(PathSequence == null || PathSequence.Length < 2)
{
return; //Exits OnDrawGizmos if no line is needed
}
//Loop through all of the points in the sequence of points
for(var i=1; i < PathSequence.Length; i++)
{
//Draw a line between the points
Gizmos.DrawLine(PathSequence[i - 1].position, PathSequence[i].position);
}
//If your path loops back to the begining when it reaches the end
if(PathType == PathTypes.loop)
{
//Draw a line from the last point to the first point in the sequence
Gizmos.DrawLine(PathSequence[0].position, PathSequence[PathSequence.Length-1].position);
}
}
#endregion //Main Methods
//Coroutines run parallel to other fucntions
#region Coroutines
//GetNextPathPoint() returns the transform component of the next point in our path
//FollowPath.cs script will inturn move the object it is on to that point in the game
public IEnumerator<Transform> GetNextPathPoint()
{
//Make sure that your sequence has points in it
//and that there are at least two points to constitute a path
if (PathSequence == null || PathSequence.Length <1)
{
yield break; //Exits the Coroutine sequence length check fails
}
while(true) //Does not infinite loop due to yield return!!
{
//Return the current point in PathSequence
//and wait for next call of enumerator (Prevents infinite loop)
yield return PathSequence[movingTo];
//*********************************PAUSES HERE******************************************************//
//If there is only one point exit the coroutine
if(PathSequence.Length == 1)
{
continue;
}
//If Linear path move from start to end then end to start then repeat
if (PathType == PathTypes.linear)
{
//If you are at the begining of the path
if (movingTo <= 0)
{
movementDirection = 1; //Seting to 1 moves forward
}
//Else if you are at the end of your path
else if (movingTo >= PathSequence.Length - 1)
{
movementDirection = -1; //Seting to -1 moves backwards
//thisCurve.enabled = true;
//this.enabled = false;
}
}
movingTo = movingTo + movementDirection;
//movementDirection should always be either 1 or -1
//We add direction to the index to move us to the
//next point in the sequence of points in our path
//For Looping path you must move the index when you reach
//the begining or end of the PathSequence to loop the path
if(PathType == PathTypes.loop)
{
//If you just moved past the last point(moving forward)
if (movingTo >= PathSequence.Length)
{
//Set the next point to move to as the first point in sequence
movingTo = 0;
}
//If you just moved past the first point(moving backwards)
if (movingTo < 0)
{
//Set the next point to move to as the last point in sequence
movingTo = PathSequence.Length - 1;
}
}
}
}
#endregion //Coroutines
}
Answer by Matthewj866 · Apr 05, 2017 at 10:27 AM
There could me multiple causes for this.
Does the other object have a regular collider? Does the moving object have a RigidBody?
Vector3.MoveTowards()
uses Translate()
behind the scenes, which ignores colliders and physics.
You need Physics.AddForce()
or directly setting the Physics.velocity
value to ensure it uses physics so the collider doesn't get ignored. This will ensure OnTriggerEnter()
fires.
This may need additional things to ensure your object doesn't leave the path when too much force is applied.
On a side note, NewPath
appears to not be set by anything, is this something you're doing in the editor?
Answer by iLucas13 · Apr 07, 2017 at 02:01 PM
@Matthewj866 Yes to the collider and RigidBody, and yes, I am setting Newpath
in the editor. I was not aware that Vector3.MoveTowards()
ignored colliders, that must be it! Thanks for the input!
No problem, please mark it as the answer if it solved your problem