Vector 2 direction problem (knockback)
Can someone help with this problem? please look at this image for help (http://noobtuts.com/content/unity/2d-pong-game/vector2_directions.png)
When player collides with object, player should get knock back
Depending on where the player hits I want the script to calculate the player's direction when it bounces off the object
The script does that, but the Y-axis is not working properly
When the player hits the center of the objects box collider the player is sent of diagonally not straight forward
I want (when my player hit the center on the box collider) my player to go straight forward. This is my code:
public float xForceToAdd; public float yForceToAdd; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.tag == "Player") { //Store the vector 2 of the location where the initial hit happened; Vector2 initialHitPoint = new Vector2 (other.gameObject.transform.position.x, other.gameObject.transform.position.y); float xForce = 0; float yForce = 0; //Grab our collided with objects rigibody Rigidbody2D rigidForForce = other.gameObject.GetComponent<Rigidbody2D>(); //Determine left right center of X hit if (initialHitPoint.x > (this.transform.position.x + (this.transform.localScale.x /3))) { xForce = 1; } else if (initialHitPoint.x < (this.transform.position.x - (this.transform.localScale.x /3))) { xForce = -1; } else { xForce = 0; } if (initialHitPoint.y > (this.transform.position.y + (this.transform.localScale.y /3))) { yForce = 1; } else if (initialHitPoint.y < (this.transform.position.y - (this.transform.localScale.y /3))) { yForce = -1; } else { yForce = 0; } Debug.Log("xForce: " + xForce + " xForceToAdd: " + xForceToAdd + " yForce: " + yForce + " yForceToAdd: " + yForceToAdd); rigidForForce.velocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd); } }
I attached a debug.log to see the co-ordinate I was receiving when I hit the center top of the object and got this: xForce: 1 xForceToAdd: 100 yForce: 1 yForceToAdd: 100
Answer by wibble82 · Dec 22, 2015 at 04:20 PM
Cleaning up your code a bit so we can see a bit more clearly what is happening and print out a bit more useful information:
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
//Store the vector 2 of the location where the initial hit happened
//(note: Vector3 automatically converts to Vector2 by removing z);
Vector2 initialHitPoint = other.gameObject.transform.position;
//calculate the minimum and maximum 'extents' that we will use for picking direction
Vector2 extentSize = transform.localScale / 3.0f;
Vector2 centre = transform.position;
Vector2 minExtent = centre-extentSize;
Vector2 maxExtent = centre+extentSize;
//Determine x direction to push
float xForce = 0;
if (initialHitPoint.x > maxExtent.x)
xForce = 1;
else if (initialHitPoint.x < minExtent.x)
xForce = -1;
else
xForce = 0;
//Determine y direction to push
float yForce = 0;
if (initialHitPoint.y > maxExtent.y)
yForce = 1;
else if (initialHitPoint.y < minExtent.y)
yForce = -1;
else
yForce = 0;
//calculate the velocity to apply
Vector2 newVelocity = new Vector2(xForce * xForceToAdd, yForce * yForceToAdd);
//print out lots of stuff
Debug.Log("Hit point: " + initialHitPoint.ToString());
Debug.Log("Min extent: " + minExtent.ToString());
Debug.Log("Max extent: " + maxExtent.ToString());
Debug.Log("New velocity: " + newVelocity.ToString());
//Grab our collided with objects rigibody and apply velocity
Rigidbody2D rigidForForce = other.gameObject.GetComponent<Rigidbody2D>();
rigidForForce.velocity = newVelocity;
}
}
It generally looks Ok from a logic point of view. All I can suggest is that you are either mistaken about where the 'centre' of your object or the player is, or the localScale is not representative of its actual size in the world.
Those debug prints should tell you exactly what is happening though, as I am now calculating the maximum extent and minimum extent and printing them, so you can read them for yourself and determine whether they are what you think they should be.
(note: just realised that code relies on 'localScale' not being negative!
Hope that helps - I appreciate it isn't a solution, but it hopefully puts you well on the way to finding one.
-Chris
Thank you for replying I really appreciate it. I'm getting this error in my console: (42,48): error CS1525: Unexpected symbol `='
oops - typo. I don't have unity here to try compiling with. There were 2 '=' signs on the line where I calculate the velocity apply - correcting answer now.
WAIT!! never $$anonymous$$d I fixed it (sorry i'm a noob)
I got these debug.log comments when I hit the top center of my object:
Hit point: (2.5, 1.5) $$anonymous$$in extent: (2.9, -1.3) $$anonymous$$ax extent: (2.2, -0.9) New velocity: (100.0, 100.0)
What would you infer from that information? Does anything look wrong? Do you think its your logic that's wrong, or the numbers its using that is wrong? Analyse :)
I have to go soon, so I'll write my thinking so far...
$$anonymous$$y thought process would be to work out where the problem lies. It could be a problem with the numbers going into my logic, or a bug or typo in my logic, or perhaps they're both fine and I've just not written the right code to achieve the result I want!
So first, given those numbers, is my logic doing what I would expect? Looking at the x coordinate first, I can see my initialHitPoint.x is greater than my maxExtent.x (2.5 > 2.2), so would expect a positive x force (which I have). Similarly, my initialHitPoint.y is greater than my maxExtent.y (1.5 > -0.9), so would expect a positive y force (which I have).
So, my 'if statements' are doing what they are told, but my calculated velocity is clearly not what I want. This is also not the result I would expect from those 'if statements' if the other object was genuinely above this one.
Next question is whether the numbers going into my logic are correct. The first thing that stands out to me is that we would certainly expect our $$anonymous$$AX extent to be greater than our $$anonymous$$IN extent in both x and y, however our $$anonymous$$Extent.x is 2.9, and the maxExtent.x is 2.2.
That's definitely an issue. The extents are calculated (as in your original code) using the localScale of this object. This suggests to me that the x component of the local scale is negative, which is throwing off all our calculations.
If you don't expect a -ve scale, then you'll need to look where that's co$$anonymous$$g from.
If you do expect a -ve scale, then we'll need to update the extentSize calculations to remove the -ve bit using $$anonymous$$athf.Abs:
Vector2 extentSize = transform.localScale / 3.0f;
extentSize.x = $$anonymous$$athf.Abs(extentSize.x);
extentSize.y = $$anonymous$$athf.Abs(extentSize.y);
Good luck!
Your answer