How do you determine the x,y co-ordinates of a sprite's boundaries?
Short version: want to find corresponding missing points from slanted rectangle sprite, see diagram:
Problem statement: want to determine if point in space exists within sprites bounds.
For normal rectangles, I can use the SpriteRenderer.bounds min and max to figure out the bottom left point and top right point, and can infer from there the other remaining points. Logic is: if point is less than the sprite's max .x and .y, but greater than the sprite's min .x and .y, then it must exist in the sprite.
For a slanted rectangle, however, I only ever get half of each point's information. See above diagram. I know once I have the points I can use determinant's to find if the point is below or above the line between the two points, so I then can follow the same logic above. But now I need to determine what these points are. I can just put them in manually but that gets laborious if I use more of these slanted rectangles.
If this is impossible to answer then that's okay too. I've considered trying out RigidBody 2D approach, to try and detect a collision somehow, and then do something with it.
Answer by sirpinkleton · May 30, 2016 at 05:54 PM
EDIT2: ended up improving the script, edited comments/code below
I believe I've resolved this problem. My solution is approximate, but that's good enough for my purposes, and I'm only using walls that are longer on the y axis than they are on the x axis (a tall rectangle rotated about the center such that the x axis is width, is another way to put it). So, future people reading this, keep this in mind, this code is sort of particular if you're not using sprite like I am.
Code below is a script I attached onto each slanted wall, explanation follows.
public class SlantedWalls : MonoBehaviour {
public float minX;
public float maxX;
public float minY;
public float maxY;
public float yForMinX;
public float yForMaxX;
public float xForMinY;
public float xForMaxY;
void Start () {
minX = GetComponent<SpriteRenderer>().bounds.min.x;
maxX = GetComponent<SpriteRenderer>().bounds.max.x;
minY = GetComponent<SpriteRenderer>().bounds.min.y;
maxY = GetComponent<SpriteRenderer>().bounds.max.y;
float decisionAngle = transform.rotation.eulerAngles.z % 180;
//Debug.Log(string.Format("I am {0}, my angle is {1}", this, decisionAngle));
if (decisionAngle < 90)
{
float xOffset = transform.localScale.x * (1 - ((transform.rotation.eulerAngles.z % 90) / 90));
float yOffset = transform.localScale.x * ((transform.rotation.eulerAngles.z % 90) / 90);
yForMinX = maxY - yOffset;
yForMaxX = minY + yOffset;
xForMinY = maxX - xOffset;
xForMaxY = minX + xOffset;
//Debug.Log(string.Format("maxY: {0}, rotation%90: {1}, rotation%90/90: {2}, thus yOffset: {3}, and so yForMinX: {4}", maxY, transform.rotation.eulerAngles.z % 90, ((transform.rotation.eulerAngles.z % 90) / 90), yOffset, yForMinX));
}
else
{
float xOffset = transform.localScale.x * ((transform.rotation.eulerAngles.z % 90) / 90);
float yOffset = transform.localScale.x * (1 - ((transform.rotation.eulerAngles.z % 90) / 90));
yForMinX = minY + yOffset;
yForMaxX = maxY - yOffset;
xForMinY = minX + xOffset;
xForMaxY = maxX - xOffset;
//Debug.Log(string.Format("minY: {0}, rotation%90: {1}, 1 - rotation%90/90: {2}, thus yOffset: {3}, and so yForMinX: {4}", minY, transform.rotation.eulerAngles.z%90, 1 - ((transform.rotation.eulerAngles.z % 90) / 90), yOffset, yForMinX));
}
//Debug.Log(string.Format("LMP: {0}, {1}", minX, yForMinX));
//Debug.Log(string.Format("TMP: {0}, {1}", xForMaxY, maxY));
//Debug.Log(string.Format("BMP: {0}, {1}", xForMinY, minY));
//Debug.Log(string.Format("RMP: {0}, {1}", maxX, yForMaxX));
}
}
Basically, I noticed that depending on the kind of angle used, the missing pieces were relatively close to other existing pieces, so I could use some inferring to figure the missing pieces out.
For example, if the slanted wall is mostly straight up and down, then the missing y values are close enough to the known y values, so the difference between the y values is small, about (transform.rotation.eulerAngles.z % 90) (example: 10 degrees / 90 = .11. With a width of 1, the missing y value from the left most point is .11 below max y, which is close to max y itself) Alternatively, the missing x values are close to one width away from known x values, so a difference is used that is close to the width, or 1 - ((transform.rotation.eulerAngles.z % 90) / 90) (example: 10 degrees / 90 = .11, 1 - .11 = .89. with a width of 1, the missing x value from the top most point is .89 to the right of min x, which is close to one widths away from min x). Whether the offset was added or removed depends which value is being inferred from which point. No magic here, I just looked at rotated rectangles and saw what needed to happen based on if the angle was > or < 90.
You could figure out which axis is longer instead of assuming y like I do, and make this script even more generic. Also you could fine tune the number for further accuracy, at the moment the resulting values look like they're anywhere between 0 or .2 off.
Finally, I found that I only needed to solve for 180 degrees. Because I'm using the bounds, rotating past 180 degrees of rotation makes, say, min.x, equivalent to what it was at a small angle. This is why I created decisionAngle, and why it's a mod 180 from the euler angles.
Your answer
Follow this Question
Related Questions
Bounds.Intersects returns false while collision still works? 1 Answer
Sprite 2d passes through the ground 0 Answers
Get tile from trigger 0 Answers
Sprite Resizing in certain Positions 0 Answers
How to define when object is inside another object (2D)? 0 Answers