実現したいこと
ここに実現したいことを箇条書きで書いてください。
- UnityにおいてRigidbodyを持つ親オブジェクトとRigidbodyを持たない子オブジェクトで衝突判定を別々にしたい。
前提
Unityで3Dアクションゲームを制作していて、相手に攻撃を行う際、衝突する部分(拳や足先など)の動くスピードによって相手に与えるダメージを変化させたい。
現状プレイヤーの体のパーツ(腕や足など)をまとめる親オブジェクト(Player)にRigidbodyを付けて、パーツにコライダーやスクリプトを付けている。また、敵オブジェクトにも同じスクリプトが付いている。
親オブジェクト(Player) Rigidbody
子オブジェクト(腕や足など) Box Collider + スクリプト(該当のソースコードに記載)
どちらもタグは「Player」
発生している問題・エラーメッセージ
衝突が検知されない。
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using System.Threading.Tasks; 5 6public class Status : MonoBehaviour 7{ 8 public int statuscode; 9 10 public float enemydamage; 11 12 public string partsname; 13 14 15 private Vector3 _prevPosition; 16 17 public float v; 18 19 public float damage; 20 21 public float defence; 22 23 public float targetv; 24 25 public Status targetstatus; 26 27 public WeaponStatus weaponstatus; 28 29 public Material damagematerial; 30 31 32 33 void Start() 34 { 35 _prevPosition = transform.position; 36 } 37 38 39 async void Update() 40 { 41 var position = transform.position; 42 43 // 現在速度計算 44 var velocity = (position - _prevPosition) / Time.deltaTime; 45 v= Mathf.Sqrt((velocity.x * velocity.x) + (velocity.y * velocity.y)+ (velocity.z* velocity.z)); 46 47 // 前フレーム位置を更新 48 _prevPosition = position; 49 50 51 52 53 54 55 } 56 57 58 59 private void OnCollisionEnter(Collision other) 60 { 61 62 63 64 if (statuscode == 1) 65 { 66 if (other.gameObject.tag == "Enemy") 67 { 68 69 70 targetstatus = other.gameObject.GetComponent<Status>(); 71 72 targetv = targetstatus.v; 73 74 enemydamage = targetstatus.damage * 0.01f / defence; 75 76 PlayerStatus.modelHP = PlayerStatus.modelHP - enemydamage; 77 78 } 79 } 80 else if (statuscode == 2) 81 { 82 83 if(other.gameObject.tag == "Weapon") 84 { 85 weaponstatus = other.gameObject.GetComponent<WeaponStatus>(); 86 87 enemydamage = weaponstatus.damage * weaponstatus.v; 88 89 90 91 EnemyStatus.enemyHP = EnemyStatus.enemyHP - enemydamage; 92 93 94 95 } 96 97 if (other.gameObject.tag == "Player") 98 { 99 100 101 102 103 targetstatus = other.gameObject.GetComponent<Status>(); 104 105 targetv = targetstatus.v; 106 107 108 109 110 111 Debug.Log("partsname" + targetstatus.partsname); 112 113 114 115 116 117 118 enemydamage = targetstatus.damage * targetv; 119 120 121 122 123 EnemyStatus.enemyHP = EnemyStatus.enemyHP - enemydamage; 124 125 126 } 127 128 129 130 } 131 } 132 133} 134
試したこと
同じような問題について対処法が書かれたサイトをいくつか見つけたので、試してみました。
①親オブジェクトにも衝突検知のスクリプトをつける。
親オブジェクト(Player) Rigidbody + 「スクリプト(該当のソースコードに記載)」
子オブジェクト(腕や足など) Box Collider + スクリプト(該当のソースコードに記載)
スクリプトにそれぞれpartsnameを設定して(親オブジェクトについているスクリプトのpartsnameには「Player」子オブジェクトについているスクリプトのpartsnameにはarmなどそれぞれのパーツの名前)衝突させましたが、腕や足などに当たった場合でも親と衝突したことになっていました。(親についているスクリプトだけが動いている?)
②子オブジェクトにもRigidbodyをつける。
親オブジェクト(Player) Rigidbody
子オブジェクト(腕や足など) Rigidbody + Box Collider
+ スクリプト(該当のソースコードに記載)
これだと子オブジェクトが衝突検知を行っているようですが、Rigidbodyを付けたパーツが地面に落ちたり、重力を外した場合でも相手に当たるとPlayerから離れてしまいます。
③親オブジェクトのタグやレイヤーを変更
親オブジェクトのみのタグやレイヤーを「Player」から「Parent」に変更しましたが、衝突を検知しなくなってしまいました。
④Playerの親オブジェクトのRigidbodyを外す
親オブジェクト(Player)
子オブジェクト(腕や足など) Box Collider + スクリプト(該当のソースコードに記載)
敵親オブジェクト(Enemy) Rigidbody
敵子オブジェクト(腕や足など) Box Collider + スクリプト(該当のソースコードに記載)
現在この状態で開発を進めていますが、敵側はPlayerのパーツごとの速度を取得できるものの、
Player側が敵側のパーツごとの速度を取得することができません。
Unity初心者であるため、衝突判定への知識が浅かったり、誤った認識をしている部分があるかもしれません。申し訳ありません。また、質問を答えていただくために必要な情報が抜けているかもしれません。コメントして教えていただければ、随時情報を加えたいと思います。少しでも何か教えていただければ嬉しいです。よろしくお願いします。
補足情報(FW/ツールのバージョンなど)
Unity 2021.2.7f1

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/03/15 11:25
2023/03/15 11:49