次に、OnCollisionEnter2D内でボールの速度を見てみたところ、すでに跳ね返り後の速度になっていました。この挙動はUnity - Manual: Execution Order of Event Functionsの解説とも合致していて、OnCollision系メソッドが呼ばれるのは物理状態更新後のタイミングだそうです。
ですので、仮に先に申し上げたようにsharedMaterialのbouncinessを変更し、コライダーのenabledをfalseにし、再度trueに戻したとしても、新しい反発係数が適用されるのは次回の衝突時になるようですね。
bouncinessを変更したその時の跳ね返りも新しい反発係数を適用するには、結局AddForceで過剰分・不足分の力積を加えて補正してやることになりそうです。
C#
1using UnityEngine;23[RequireComponent(typeof(Collider2D),typeof(Rigidbody2D))]4public class BallController : MonoBehaviour {56 private Collider2D collider;7 private Rigidbody2D rigidbody;89 public voidStart()10{11// あらかじめCollider2DとRigidbody2Dを取得しておく12 this.collider = this.GetComponent<Collider2D>();13 this.rigidbody = this.GetComponent<Rigidbody2D>();1415// マテリアルを複製し、sharedMaterialの変更が他へ及ばないようにする16 var material = this.collider.sharedMaterial;17 var newMaterial = new PhysicsMaterial2D(material.name +" (Instance)");1819 newMaterial.bounciness = material.bounciness;20 newMaterial.friction = material.friction;21 this.collider.sharedMaterial = newMaterial;22}2324 private voidOnCollisionEnter2D(Collision2D coll)25{26 var material = this.collider.sharedMaterial;27 var currentBounciness = material.bounciness;// 現在の反発係数28 var nextBounciness =0.5f;// 新しい反発係数2930// 今回の衝突で加わった法線方向の力積の総和を求める31 var impulse = Vector2.zero;3233foreach(var contact in coll.contacts)34{35 impulse += contact.normalImpulse * contact.normal;36}3738// sharedMaterialのbouncinessを変更し、colliderのenabledを切り替えて変更を適用させる39 material.bounciness = nextBounciness;40 this.collider.enabled = false;41 this.collider.enabled = true;4243// 上記のみでは現在の跳ね返りには新しい反発係数が適用されないので、差分を補償する追加の力積をrigidbodyに加える44 var extraImpulse =((nextBounciness - currentBounciness)/(1.0f+ currentBounciness))* impulse;4546 this.rigidbody.AddForce(extraImpulse, ForceMode2D.Impulse);47}48}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/11 23:26