- Home /
Keep SphereCollider radius the same, even though scale is changed
For a nice effect on a object I constantly change the scale of the transform, but this obviously changes the radius of the SphereCollider too. I need to find a way to keep the SphereCollider's radius the game, even though the scale of the transform changes.
Any idea on how to do this?
Help will be appreciated
Never $$anonymous$$d, solved it! :) This is how I did:
Start(): sphereCollider = GetComponent(); float sphereColliderRadius = sphereCollider.radius;
Update(): sphereCollider.radius = sphereColliderRadius / transform.localScale.x;
you could put your object as a child of an empty game. The empty game object gets the collider, the child scale is modified. Then no need for calculation.
Answer by cbeattie · Oct 19, 2018 at 10:41 AM
It is better to not use lossyScale
as it is inaccurate.
Instead use localToWorldMatrix
directly:
var sphereCollider = gameObject.GetComponent<SphereCollider>();
var matrix = sphereCollider.transform.localToWorldMatrix;
var xAxisMag = matrix.GetColumn(0).magnitude;
var yAxisMag = matrix.GetColumn(1).magnitude;
var zAxisMag = matrix.GetColumn(2).magnitude;
// Adjust radius to be in meters.
sphereCollider.radius = _collisionRadius / Mathf.Max(xAxisMag, yAxisMag, zAxisMag);
Answer by attlue_1 · Mar 22, 2017 at 07:05 AM
Actually what you have to do is divide target spherecollider.radius by the largest component value of transform.losslyScale.
ie:-
SphereCollider __spherecollider = this .GetComponent< SphereCollider >();
float scale__float = this.transform.lossyScale.x;
if( this.transform.lossyScale.y > scale_float ) { scale_float = this.transform.lossyScale.y; }
if( this.transform.lossyScale.z > scale_float ) { scale_float = this.transform.lossyScale.z; }
__spherecollider.radius = target_radius_float / scale_float;