前提・実現したいこと
ここに質問の内容を詳しく書いてください。
発射した弾丸が障害物に当たると砕け散るようにしたいと考えています。
■■な機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
弾はmayaでオブジェクトを粉砕。 unityにて発射元にprefabに指定。 ですが障害物に当たっても飛散せず固体のままです。
該当のソースコード
ソースコード
試したこと
試した事は、
発射口とprefabを複数にして、各発射口にthis.GetComponent<Rigidbody>().Sleep();を付与し初動でのリジットボディ無効を行いましたが弾同士の衝突は避けられるが飛んで行きません。
衝突時にprefabの親を消すスクリプトを付与すると全て消えてしまうようです。
せめて発射直後に弾同士のコライダー反応で飛散してくれるならIgnoreCollisionで行けそうなんですが・・・
mayaでの粉砕状態も色々試しましたが、
後処理はシェイプ、オリジナルサーフェスは削除で良いような気がします。
unity上で解決できる問題と思いますが他にやれる事はありますか?
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
Mayaを持っておらず(魅力的なソフトですが高価ですね)、Mayaから出力されたモデルをインポートした結果どのような状態にあるのか分かりませんが、もしかして個々の破片にはCollider(おそらくMesh Colliderでしょうか)があるのみでRigidbodyがアタッチされておらず、親オブジェクトに一つだけRigidbodyが付いている状態だったりしないでしょうか?
もしそうでしたら、それをそのままUnity上で動かしてもオブジェクト全体が一塊の剛体としてふるまい、破片が飛び散るような動きはさせられないんじゃないかと思います。
かといって個々の破片に単純にRigidbodyを付けた状態で発射すれば、いきなり弾丸が砕けてしまうでしょうから対策が必要なはずです。
一案としては、破片同士をFixedJointで連結してやる手がありそうです。breakForceを適切に設定すれば、接続部に一定以上の力がかかった際にジョイントが破断し破片が飛び散ってくれそうです。
ただし、発射時は負荷上限を大きくしておいて、発射後に上限を目標値に合わせるような工夫が必要かもしれません。発射方式にもよるでしょうが、負荷上限が小さいまま発射すると、発射時の加速に耐えられず砕けてしまうなんてこともありそうです。
別案として、発射から着弾までは単純なコライダーとRigidbodyを一つずつ持つ未粉砕弾丸を使い、着弾を検出した際に複数の破片からなる粉砕弾丸に差し替えてしまう手もあるでしょう。
第一の案の、複雑なコライダーを持ち複数のRigidbodyを継ぎ合わせたオブジェクトを常時使用するのは、単純なオブジェクトを使うよりも計算コストの面で不利なはずです。着弾後の演出としてだけ粉砕表現があれば十分なのでしたら、こちらの方が有効そうな気がします。
ご参考として、後者の案を試してみました。粉砕弾丸への差し替えにもいくつか方法が考えられますが、今回は下図のように、未粉砕弾丸の子オブジェクトとして粉砕弾丸を内蔵しておき、衝突時に粉砕弾丸を未粉砕弾丸の外に取り出して、未粉砕弾丸は削除するという方式にしました。
親オブジェクトである未粉砕弾丸はSphereColliderとRigidbodyを一つずつ持つシンプルなオブジェクトです。子オブジェクトである粉砕弾丸は破片の集合体で、個々の破片にそれぞれMeshColliderとRigidbodyが付けられています。
未粉砕弾丸の方に下記のスクリプトをアタッチし、衝突時のオブジェクト差し替えを行いました。
C#
1using System.Collections; 2using UnityEngine; 3 4public class SphereController : MonoBehaviour 5{ 6 public float Delay = 5.0f; 7 public float InitialSpeed = 20.0f; 8 public float ShatteringImpulse = 100.0f; 9 public Transform Target; 10 private Vector3 previousAngularVelocity; 11 private Vector3 previousCenterOfMass; 12 private Vector3 previousPosition; 13 private Vector3 previousVelocity; 14 private new Rigidbody rigidbody; 15 private Transform shatteredSphere; 16 17 private IEnumerator Start() 18 { 19 this.rigidbody = this.GetComponent<Rigidbody>(); 20 21 // 子オブジェクトとして内蔵している破砕済みオブジェクトを取得し、 22 // Start時点では非アクティブ状態にしておく 23 this.shatteredSphere = this.transform.Find("ShatteredSphere"); 24 this.shatteredSphere.gameObject.SetActive(false); 25 26 // 一定時間経過後、目標に向かって発射する 27 yield return new WaitForSeconds(this.Delay); 28 29 if (this.Target != null) 30 { 31 this.rigidbody.AddForce( 32 (this.Target.position - this.transform.position).normalized * this.InitialSpeed, 33 ForceMode.VelocityChange); 34 } 35 } 36 37 private void FixedUpdate() 38 { 39 // FixedUpdate時点の位置・速度・角速度を覚えておく 40 // 微妙な違いですが、OnCollisionEnter時点のこれらは衝突後のもののようですので 41 // それを使った場合だと破片の動きがちょっと気に入らなかったため、衝突直前の 42 // 位置・速度・角速度を使うことにしました 43 this.previousPosition = this.rigidbody.worldCenterOfMass; 44 this.previousVelocity = this.rigidbody.velocity; 45 this.previousAngularVelocity = this.rigidbody.angularVelocity; 46 this.previousCenterOfMass = this.rigidbody.worldCenterOfMass; 47 } 48 49 private void OnCollisionEnter(Collision collision) 50 { 51 // 衝突しても、衝撃が一定量を下回っていれば何もしない 52 if (collision.impulse.magnitude < this.ShatteringImpulse) 53 { 54 return; 55 } 56 57 // ひとまず自分自身は非アクティブにし... 58 this.gameObject.SetActive(false); 59 60 // 破砕済みオブジェクトをルート直下に取り出し... 61 this.shatteredSphere.SetParent(null); 62 63 // 破砕済みオブジェクトを衝突直前の位置に移動し... 64 this.shatteredSphere.position = this.previousPosition; 65 66 // 破砕済みオブジェクトをアクティブにし... 67 this.shatteredSphere.gameObject.SetActive(true); 68 69 // 衝突直前の速度を各破片に与え... 70 foreach (var r in this.shatteredSphere.GetComponentsInChildren<Rigidbody>()) 71 { 72 // 破壊前の重心から遠い位置にある破片は、回転によってハンマー投げのように飛びそうだと思い 73 // 回転の影響を追加してみましたが、省略して計算量を削減しても見栄えはさほど変わらないと思います 74 r.velocity = this.previousVelocity + Vector3.Cross(this.previousAngularVelocity, r.worldCenterOfMass - this.previousCenterOfMass); 75 } 76 77 // 自分自身はもう不要なので削除する 78 Destroy(this.gameObject); 79 } 80}
動かしてみますと下図のようになりました。一定以上の衝撃が加わるとオブジェクトが差し替わり、個々の破片が独立して運動します。
投稿2018/12/10 09:47
総合スコア10807
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/12/10 15:56
2018/12/10 21:54
2018/12/11 15:09
2018/12/11 20:31
2018/12/12 14:59
2018/12/12 19:11
2018/12/13 11:15
2018/12/13 11:34
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。