- Home /
Determine Distance to Top of Collider?
I have some code where my character can "climb up" onto an object in front of them. Right now, I'm using a RaycastHit to determine if a climbable object exists in front of them and that part works great. Now I want to be able to detect the height of the collider plane in front of the player. I'm attempting this with the "mpCenter" vector and using a Bounds.Contains with marginal success.
What I'd really like is to know exactly what the world coordinate is of the tallest point of the colliders surface for my initial RaycastHit. That way, if it is a box collider for a wall for example, then i want the height of the plane (normal?) in front of the player - which will allow me to adjust my animation accordingly (i.e. if its about eye level then just play the climb up on ledge animation, if its a few feet above them, then play a jump animation first to get the player to the right height, then play climb up on ledge).
RaycastHit hit; if( Physics.Raycast( transform.position, transform.forward, out hit, 0.35f ) ) { // check if this is a climbable object or we are free to jump if( hit.transform.gameObject.tag == "Climbable" ) { Vector3 mpCenter = new Vector3( hit.point.x, rigidbody.position.y + jumpHeight, hit.point.z ); if( !hit.collider.bounds.Contains( mpCenter ) ) { animation.CrossFade( "ClimbUpOnLedge" ); } } }
Answer by Kourosh · Apr 29, 2011 at 03:45 AM
You can get the size of your wall (with a box collider) this way:
var length:float = hit.transform.localScale.x * hit.collider.size.x;
var width:float = hit.transform.localScale.z * hit.collider.size.z;
var height:float = hit.transform.localScale.y * hit.collider.size.y;
var dimensions:Vector3 = Vector3(length, height, width);
now to know the world position of top most level of the wall:
var topMost:float = hit.transform.position.y + dimensions.y/2;
In c#, you need to cast accordingly (put it here, that others can copy-paste without having to convert manually):
float length = hit.transform.localScale.x * ((BoxCollider)hit.collider).size.x;
float width = hit.transform.localScale.z * ((BoxCollider)hit.collider).size.z;
float height = hit.transform.localScale.y * ((BoxCollider)hit.collider).size.y;
Vector3 dimensions = new Vector3(length, height, width);
//now to know the world position of top most level of the wall:
float top$$anonymous$$ost = hit.transform.position.y + dimensions.y / 2;
I'll add a comment as other people will find this though google as I did and it's relevant.
Both codes are not taking into account the offset of the Box Collider, and will be inaccurate if you have it, the error is enormous if you are using big scales. To account for it just add the offset to the calculations.
float height = hit.transform.localScale.y * ((BoxCollider)hit.collider).size.y + (hit.transform.localScale.y * ((BoxCollider)hit.collider).offset.y)
Answer by iuripujol · Apr 23, 2016 at 10:50 AM
hit.collider.GetComponent ().bounds.center.y + 0.97f * hit.collider.GetComponent ().bounds.extents.y + 0.075f;//needs to match all!
Combine this with this and it will give you awesome results.
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation (hit.normal * -1), Time.deltaTime); if (m_Animator.GetCurrentAnimatorStateInfo (0).IsName ("Climb")) { m_Controller.enabled = false; }
m_Animator.MatchTarget (m_Target, new Quaternion (), AvatarTarget.LeftHand, new MatchTargetWeightMask (new Vector3(0,m_Target.y,0), 0), ClimbMatchTargetStart, ClimbMatchTargetStop);
if 0.97f or 0.0075f do not match, change'em and match'em with new values, hope it helps...