卵の「体力」
次、卵が強く衝突したら体力が減り、ゼロになったら卵が消える処理を追加しましょう。
スクリプト
まず、単純な考え方で、「ぶつけたら、体力が減る」処理をにしましょう。
// 卵の体力
public class EggHP : MonoBehaviour
{
// ぶつかるときに受けるダメージ
[SerializeField]
private float hitDamage = 30;
// 体力
private float hp = 100;
// 衝突の時
private void OnCollisionEnter(Collision other)
{
// ぶつけたら、体力が減る
hp -= hitDamage;
// UIまだないため、Debug.Logで確認
Debug.Log(hp);
// 体力ゼロ以下の場合、ゲームオブジェクトを廃止
if (hp <= 0)
Destroy(gameObject);
}
}
スクリプトを卵にアタッチし、転がしてみましょう。
問題1:すぐ消えてしまう!
ぶつかる時に体力が減るようにしたが、床面ともぶつかるので、転がるだけで死んでしまう!床面に新しい「Floor」タグを付けて、スクリプトで床を無視しましょう。

// 衝突の時
private void OnCollisionEnter(Collision other)
{
// 床面を無視する
if (other.gameObject.CompareTag("Floor"))
return;
// ぶつけたら、体力が減る
hp -= hitDamage;
// UIまだないため、Debug.Logで確認
Debug.Log(hp);
// 体力ゼロ以下の場合、ゲームオブジェクトを廃止
if (hp <= 0)
Destroy(gameObject);
}
これでまた確認してみてください。
問題2:優しくにしても、すぐ体力が減る
たしか、これで床で転がしても体力が減らないが、優しく壁を触れても、体力が30を減る!衝突の強さに合わせて体力が減る処理を追加しましょう。このため Collision の impulse を使用できる。impulse を確認するため、一旦 OnCollisionEnter を以下のように変えてください:
// 衝突の時
private void OnCollisionEnter(Collision other)
{
// 床面を無視する
if (other.gameObject.CompareTag("Floor"))
return;
// ぶつけたら、体力が減る
hp -= hitDamage;
// 一時的に impulse を表示
// impulseはベクトル(強さと向き)なので、ベクトルの長さを求める
float hitForce = other.impulse.magnitude;
Debug.Log($"衝突の強さ:{hitForce}");
// UIまだないため、Debug.Logで確認
//Debug.Log(hp);
// 体力ゼロ以下の場合、ゲームオブジェクトを廃止
//if (hp <= 0)
// Destroy(gameObject);
}
で実行するとこのように表示される(転がり方による)

これを使って、スクリプトを直しましょう。最小値と最大値の強さを Unityで設定し、
- 最小値以下なら:ゼロダメージ
- 最大値以上んら:最大ダメージ
- その間は:線形的に補間
ならば、以下のようにスクリプトを直す:
// 卵の体力
public class EggHP : MonoBehaviour
{
// ぶつかるときに受けるダメージ
[SerializeField]
private float hitDamage = 30;
// 最低の衝突の強さ
[SerializeField]
private float minImpulse = 4;
// 最大の衝突の強さ
[SerializeField]
private float maxImpulse = 20;
// 体力
private float hp = 100;
// 衝突の時
private void OnCollisionEnter(Collision other)
{
// 床面を無視する
if (other.gameObject.CompareTag("Floor"))
return;
// impulseはベクトル(強さと向き)なので、ベクトルの長さを求める
float hitForce = other.impulse.magnitude;
// 最低と最大の間に正規化する
float hitNorm = (hitForce - minImpulse) / (maxImpulse - minImpulse);
hitNorm = Mathf.Clamp01(hitNorm); // 絶対に0と1の間にする
// ぶつけたら、体力が減る
hp -= hitDamage * hitNorm;
// UIまだないため、Debug.Logで確認
Debug.Log($"衝突の強さ:{hitForce}, 残りの体力:{hp}");
// 体力ゼロ以下の場合、ゲームオブジェクトを廃止
if (hp <= 0)
Destroy(gameObject);
}
}
これで試して、体力の減り方を見てください。