How to find point just outside of box collider?
I think this one is pretty easy but I couldn't find the answer on my own. I have a character, above which I want to display a game object. In this case it's a health bar. Because of some other decisions about the design of the game I cannot parent the object with the character so I can't pre-position the object above the character. I have a box collider around the character that I can use to determine the size of the character. How can I get a Vector3 point indicating a position directly above the character, just outside of the box collider?
Here is the code that I've tried to use. It's very inconsistent though and unusable. For some characters the status display is positioned well, for others it is way off. I'm obviously doing something wrong.
BoxCollider collider = characterScript.gameObject.GetComponent<BoxCollider>();
if (collider != null)
{
GameObject miniStatusDisplay = (GameObject)Instantiate(StatusDisplayPrefab, transform);
miniStatusDisplay.transform.position = Camera.main.WorldToScreenPoint(new Vector3(collider.transform.position.x, collider.transform.position.y + collider.size.y, collider.transform.position.z));
}
Attached is a visual representation of what I'm trying to accomplish.
Appreciate any help.
You know the height of the collider and its center in 3D space. Add half the height to the position to find the top of the box. You can add more or less distance (in the up direction) to create a desirable offset.
Of course certain conditions may make this slightly more complicated, depending on exactly how you're using your gameobjects and colliders, but this is the basic idea regardless, and belongs to a family of math tricks you'll use again and again.
Thanks @AlwaysSunny, this is in fact what I'm trying to do by taking the collider.size.y but it's not working. I will spend some more time on this again. Something about how inconsistent my results are makes me think I'm missing something, like maybe the units in which the box collider is measured isn't the same as the units of the world or something like that.
This may indeed be part of the problem. You may be doing your math in the wrong "space" - depending upon factors we aren't seeing here. If you want to get a more detailed assessment, can you elaborate on your situation a bit? What happens if, for instance, you simply ignore the collider and add to the object's position to find your point?
Vector3 myPoint = character.transform.position + ( Vector3.up * 5 );
myPoint = Camera.main.WorldToScreenPoint( myPoint );
Oh, and be doubly sure that the prefab you're instantiating has its elements centered on its origin. That's an easy mistake to make while building prefabs - having their contents at a weird local position.
Answer by omatase · Dec 27, 2016 at 11:48 PM
Thanks so much for your help. I figured out the problem! When I scale the characters, the box collider size stayed the same, so I had to scale down the box collider height by the character scale. Now it's working correctly!
Here's the code
var statusRectTransform = current.Value.MiniStatusDisplayScript.GetComponent<RectTransform>();
BoxCollider collider = current.Value.CharacterScript.gameObject.GetComponent<BoxCollider>();
if (collider != null)
{
var newPosition = Camera.main.WorldToScreenPoint(new Vector3(current.Value.CharacterScript.gameObject.transform.position.x, current.Value.CharacterScript.gameObject.transform.position.y + (collider.size.y * current.Value.CharacterScript.gameObject.transform.localScale.y), current.Value.CharacterScript.gameObject.transform.position.z));
current.Value.MiniStatusDisplayScript.transform.position = new Vector3(newPosition.x - ((statusRectTransform.rect.width * statusRectTransform.localScale.x) / 4), newPosition.y + ((statusRectTransform.rect.height * statusRectTransform.localScale.y) / 2), newPosition.z);
}