- Home /
PhysicMaterial Property Change Not Effective If Change During Collision
The problem is that when the collision occurs, the angle of collision is calculated and then the bounciness changes. I see in the inspector that it does actually change like it's supposed to, but alas, no bouncy.
Well, here's the code. I've tried a few workarounds that you can see with the enabled = true/false, and also with PrevCollisionObject. With PrevCollisionObject, that was created because I thought maybe Unity was accidentally causing multiple collision calls. The code's a mess, I know, but try to look past that. First run trying to figure things out is usually duct taped together anyway.
The collider.enabled part was something I found while tirelessly looking through Unity Answers which had no effect.
Alright, so to clearly state things and put everything in a nutshell - I need the bounciness property to change on collision (which it does) and then actually bounce using the new bounciness value.
Thanks in advance and I'm REALLY sorry this is so messy :)
#pragma strict
var Ball : Transform; //The ball.
var ObjectDirection : GameObject; //Object used that always points in direction of ball movement.
var RecPreCollisionPosition : int; //Record PreCollisionPosition every nth frames.
var MaxAllowedAngle : int; //Angle of impact that allows bounciness.
var Bounciness : float; //Bounciness applied when all requirements are met.
static var PrevCollisionObject : GameObject; //Previous object hit. Shared across all scripts.
internal var PreCollisionPosition : Vector3; //Position before collision detection.
internal var PostCollisionPosition : Vector3; //Position after collision detection.
internal var RecPreCollisionPositionIt : int; //RecPreCollisionPosition iterator.
internal var AngleOfIntersection : float; //Angle of intersection between ball and forward hit point.
function Start () {
PreCollisionPosition = Ball.position; //Records position on hit just in case the ball is near the wall and position recording does not record an effective position.
}
function FixedUpdate () {
if (RecPreCollisionPositionIt == RecPreCollisionPosition) {
PreCollisionPosition = Ball.position; //Records position of ball during this frame.
RecPreCollisionPositionIt = 0; //Resets frame recording iterator.
} else if (RecPreCollisionPositionIt < RecPreCollisionPosition) {
RecPreCollisionPositionIt++; //Increments frame recording iterator.
}
}
function OnCollisionEnter (collision : Collision){
PostCollisionPosition = Ball.position; //Saves ball position on collision.
AngleOfIntersection = Mathf.Abs(Vector3.Angle(collision.contacts[0].normal, (PostCollisionPosition - PreCollisionPosition))); //Angle of intersection.
if (AngleOfIntersection < MaxAllowedAngle) {
PrevCollisionObject = gameObject; //This will store the game object that satisfied the requirements. This will then be compared to the else statement to prevent wrong bounciness changes.
gameObject.collider.sharedMaterial.bounciness = Bounciness; //Sets bounciness if angle of intersection is less than specified angle.
gameObject.collider.enabled = false;
gameObject.collider.enabled = true;
} else if ((PrevCollisionObject != gameObject) && (AngleOfIntersection >= MaxAllowedAngle)){
gameObject.collider.sharedMaterial.bounciness = 0;
gameObject.collider.enabled = false;
gameObject.collider.enabled = true;
}
/*//Ball.rigidbody.Sleep();
//Raycast from ball position to direction.
var Hit : RaycastHit;
if (Physics.Raycast (ObjectDirection.transform.position, ObjectDirection.transform.TransformDirection (-Vector3.forward), Hit)) {
}*/
}
So I ended up trying to change the entire material too, and I can see in the inspector that the material changed. I still have the same problem though. I even rearranged the code like this:
gameObject.collider.enabled = false;
gameObject.collider.material = Default$$anonymous$$aterial;
gameObject.collider.enabled = true;
It feels like it should be such a simple thing to fix.
Alright, well I was thinking about this logically and I thought this from the beginning, but I was somewhat attempting to delude myself into thinking I was wrong.
This probably will never work because the ball already collided with the object, so being that the collision is done, it can't exact institute the new values until it's hit the next time.
The reason I got confused is because it seems like others got it to work the way I wanted it to.
I could always just use raycasting, but the ray would miss the tail ends of a collision. I was maybe even thinking of maybe the curves smoother with more colliders where then I could just adjust the bounciness level to work perfect. Problem with that is that Unity sees a collision in between two points as a line, which it should, but it will never stick to a curve when the colliders have bounciness greater than zero.
Eh, if anyone has a solution to this, let me know.