スプライトが動的に変わるGameObjectがあり、polygonCollider2DをAddComponentしています。
スプライトが変わるごとにPolygonCollider2DをGetComponentしDestroyし、またAddComponentするという付け直しをしています。
これを付け直しすることなくコライダー領域を再生成することはできないでしょうか?
https://docs.unity3d.com/ja/2017.4/ScriptReference/PolygonCollider2D.html
これを見る限り、それっぽいメソッドは見当たりませんでした。
◆環境
Unity2017 3.1f1
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答1件
0
ベストアンサー
おっしゃる通りそれらしいメソッドはなさそうですね。
コライダーの再アタッチを使わない方法として、Refreshing the Polygon Collider (2D) upon sprite change? - Unity AnswersのLCStarkさんの案を参考に、スプライトが変化するGameObjectにこのようなスクリプトをアタッチし...
C#
1using System.Collections.Generic; 2using UnityEngine; 3 4[RequireComponent(typeof(PolygonCollider2D))] 5public class PolygonCollider2DUpdater : MonoBehaviour 6{ 7 private static readonly Dictionary<Sprite, Vector2[][]> PathsForSprite = new Dictionary<Sprite, Vector2[][]>(); 8 private PolygonCollider2D polygonCollider; 9 10 // このゲームオブジェクトのスプライトを変更した場合、併せてこのメソッドを実行するようにする 11 public void UpdateColliderShape(Sprite sprite) 12 { 13 if (sprite == null) 14 { 15 return; 16 } 17 18 if (!PathsForSprite.ContainsKey(sprite)) 19 { 20 // spriteに対応するパスが未キャッシュなら、スプライトから物理形状を取得し 21 // PathsForSpriteに保存しておく 22 var shapeCount = sprite.GetPhysicsShapeCount(); 23 var newPaths = new Vector2[shapeCount][]; 24 var shape = new List<Vector2>(); 25 for (var i = 0; i < shapeCount; i++) 26 { 27 sprite.GetPhysicsShape(i, shape); 28 var path = shape.ToArray(); 29 newPaths[i] = path; 30 } 31 32 PathsForSprite.Add(sprite, newPaths); 33 } 34 35 // spriteと対応するパスをPathsForSpriteから取り出し、コライダーにセットする 36 var paths = PathsForSprite[sprite]; 37 var pathCount = paths.Length; 38 for (var i = 0; i < pathCount; i++) 39 { 40 this.polygonCollider.SetPath(i, paths[i]); 41 } 42 } 43 44 // 比較用のコライダー破壊・再アタッチ方式での実装 45 /* 46 public void UpdateColliderShape(Sprite sprite) 47 { 48 Destroy(this.polygonCollider); 49 this.polygonCollider = this.gameObject.AddComponent<PolygonCollider2D>(); 50 }*/ 51 52 private void Awake() 53 { 54 this.polygonCollider = this.GetComponent<PolygonCollider2D>(); 55 } 56}
スプライトを変更した際には、下記のようにUpdateColliderShape
を実行してみました。
C#
1 this.spriteRenderer.sprite = sprite; 2 this.polygonCollider2DUpdater.UpdateColliderShape(sprite);
ですが、ちょっと動かしてみた限りでは性能面に大きな違いはなさそうでした。
コライダー破壊・再アタッチ方式で毎フレームスプライト差し替え
差し替え時の「GC Allocated」はSetPath
方式の方が若干小さく、結果として「Total GC Allocated」のノコギリ形グラフはSetPath
方式の方が周期が長くなりましたが、コライダー破壊方式がSetPath
方式に対して極端に劣るようなことはなさそうです。
コライダー破壊方式はコライダーのインスタンスが差し替わってしまうため、色々なスクリプトからコライダーを参照している場合はそれらをすべて新しいインスタンスに参照を更新してやる必要があるでしょうから、そのような場合はインスタンスが置き換わらないSetPath
方式を使う利点がありそうです。
ですが、コライダー破壊方式の方がコードがシンプルですので、上記のような条件でなければコライダー破壊方式でも問題ないかと思います。
その他、試していないのですが、Santosh_Nairさんの紹介されているUnity 4.3 2D Tutorial: Physics and Screen Sizes | raywenderlich.com記事内の「スプライトと対応するPolygon Collider 2Dをいくつもアタッチし、現在レンダラーにセットされているスプライトに応じてコライダーのenabled
を切り替える」という方式もありそうです。
スプライトの種類が少ない場合はいいかもしれませんが、切り替え候補のスプライトが多数ある場合はオブジェクトに大量のコライダーがアタッチされることになるでしょうから、インスペクタは見づらくなりそうです。パフォーマンスについては実験してみないと予想しにくいですね。大量のコライダーがあるとはいえ、アクティブなのは常に一つだけですので、案外パフォーマンス上の不利は小さいかもしれません。
投稿2018/10/27 08:43
総合スコア10816
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/27 21:45