- Home /
How to best determine which direction an OnTriggerEnter object came from?
Good evening, folks! This is my first time using Unity Answers, but I couldn't seem to find an answer that fit my particular conditions, so I hope you all might be able to help me out! (though do correct me if I am asking a redundant question)
So, I'm making a fairly simple little The Witness-style maze-based puzzle game, and today I've been working through the basic mechanics using Line Renderer to draw my line based on the position of a GameObject that follows the position of the mouse. I've got it working to where as you move the line through intersections in the maze you cannot cross the line over itself and moving back over an intersection point you've just passed through will remove the line, however my method for doing this currently relies on OnTriggerEnter/Exit, which of course means that no matter what direction you move the line out of a point when backtracking, that point disappears, which can definitely cause problems. Here's a quickie video for reference:
https://drive.google.com/file/d/1YNXuC6EucP3TBpB8RoIfjykliDh75Lge/view?usp=sharing
(See the 0:29 second mark to see what I mean)
So it seems like, from my admittedly limited knowledge of C# programming, the best way to go about fixing this would be to somehow determine which direction the line entered the intersection point from, and then have different conditions for what happens when it leaves the intersection based on that. Buuuuuut I'm not sure how to go about doing that...
I'm not using rb.AddForce, so I can't get the velocity; the position of the end of the line is being lerp'd toward the mouse position (currently). Here's what I've got thus far:
Line movement:
void Update()
{
// Translates the mouse position into worldspace values.
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = 0;
// Lerp the Obj toward the mouse's position, applied to the Rigidbody
rb.MovePosition(Vector2.Lerp(transform.position, mousePos, moveSpd * Time.deltaTime));
}
And my OnTriggers/Collision for the intersections:
private void Start()
{
col = GetComponent<Collider2D>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag == "Player" && !activated)
{
lineScript.CreatePointMarker(transform.position);
currentPoint = lineScript.lRend.positionCount - 1;
activated = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (activated)
{
col.isTrigger = false;
}
else if (!activated)
{
Destroy(lineScript.allPoints[currentPoint]);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.transform.tag == "Player")
{
if (lineScript.lRend.positionCount > currentPoint + 2)
{
return;
}
else if (lineScript.lRend.positionCount <= currentPoint + 2)
{
col.isTrigger = true;
activated = false;
}
}
}
Sincerest thanks in advance for any assistance you may be able to provide! :)
Answer by I_Am_Err00r · Jul 09, 2019 at 02:34 PM
You can try to make some if statements that determine what to do depending on where the collision occurred, for example:
private void OnCollisionEnter2D(Collision2D collision)
{
if(collision.transform.tag == "Player")
{
if (lineScript.lRend.positionCount > currentPoint + 2)
{
return;
}
else if (lineScript.lRend.positionCount <= currentPoint + 2)
{
col.isTrigger = true;
activated = false;
FindSide(collision);
}
}
}
private void FindSide(Collision2D collision)
{
if (activated = true)
{
return;
}
if(collision.transform.position.x < col.transform.position.x)
{
//This means the player is moving in the left direction, heading into the colliders right side;
}
if(collision.transform.position.x > col.transform.position.x)
{
//This means the player is moving in the right direction, heading into the colliders left side;
}
if(collision.transform.position.y < col.transform.position.y)
{
//This means the player is moving in the down direction, heading into the colliders top side;
}
if(collision.transform.position.y > col.transform.position.y)
{
//This means the player is moving in the up direction, heading into the colliders bottom side;
}
}
I might have some of those backwards, but that is a simple solution to the problem I think you are having. There might be a cleaner way to do all that as well, but that should get you in the right direction.
I think this gets me on the right track, thanks! I'm going to test a few things and I'll report back if I find a working solution. Thanks for the recommendation! :)
Answer by dbchest · Jul 10, 2019 at 09:22 AM
@Eirreann alternatively, you can implement a list to store the transform(s) of each point in your scene as they are activated by the player; this is a great avenue to consider because having this information at the ready would allow you to reference any point, at any time, for any reason; I am sure you are able to infer how powerful this would be; in regards to your current consideration, if you dynamically populated a list with the points that the player activates, you would only need to compare the player's current transform against the most recently activated point to know which direction the player came from. if you are unsure of how to declare a list and populate it, you can follow this link for more information! https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=netcore-2.2
As it happens, I was already doing this, sort of, but just didn't think to use this for the purposes of deter$$anonymous$$ing direction! Each point in the line is a instantiated GameObject that's position is added to an array of positions that's referenced by the LineRenderer component to populate its own array of points. I'll try that out and see how it works for me. :)
Is there a notable difference between arrays and lists?
arrays win when it comes to performance and convenience arguably, but lists win when it comes to versatility and depth. if you look over that link I posted you will see that lists have a great deal more functionality over unity arrays, but the real benefit of a list is that you don't need to know upfront how many elements are to be included. the rule of thumb is that arrays should be chosen over lists if all you need is a lightweight solution for storing a known number of elements. on the other hand, if you do not know how many elements are to be included in the collection or you simply want the option to add elements later on, then a list is the right choice.
Your answer
Follow this Question
Related Questions
OnCollisionExit() firing when object has not exited 0 Answers
Destroy a game object but I would like to have it return? 3 Answers
Triggers et al. don't work with mesh colliders. But where is it written in the documentation? 0 Answers
Turn off collision of two triggers 1 Answer
2D - Two objects, each having two trigger colliders - interacting 0 Answers