前提・実現したいこと
Unity 2D AnimationとSpringJointを使ったソフトボディのオブジェクトを作ったのですが、ボーンに対応してspriteSkinで変形させたspriteの当たり判定の取り方がわかりません…。
別のオブジェクトを使って転がすようなゲームを作りたいので、porigonCollider2Dで自動生成される程度の正確な当たり判定が取りたいです。
ソフトボディの実装はこちらの動画を参考にして作りました。
リンク
□porigonCollider2Dを更新し続ける。
リンク
→自動生成のporigonCollider2DはspriteSkinで変形する前の形になるのでダメだった。
□meshを使う。
リンク
→meshとsprite、spriteSkinを同じオブジェクトに両立して実装させることが難しく、他の方法を模索。
□spriteSkinで変更されたspriteの値を取ってporigonCollider2Dに直接入れる。
リンク
リンク
→spriteSkinがメソッドで返してくれる値とporigonCollider2Dに入れる為の値が違うので変換する必要があるが、何がどういった値を示しているか理解できていない。
Unity 2D Animationを使わなくても、当たり判定が取れるもちもちしたものが実装できればよいのですが他に方法が思いつきません。
知識不足で頓挫してしまってるのは承知ですが、なにか解決のヒントを頂けたら非常にありがたいです。
◆環境
Unity 2020.3.15f2
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
□spriteSkinで変更されたspriteの値を取ってporigonCollider2Dに直接入れる。
というのはいい案かと思います。その方針で検討してみました。
オブジェクトに下記のようなスクリプトをアタッチしたところ...
lang
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEngine; 5using UnityEngine.U2D.Animation; 6 7[RequireComponent(typeof(PolygonCollider2D), typeof(SpriteSkin))] 8public class SpriteSkinColliderAdjuster : MonoBehaviour 9{ 10 private new PolygonCollider2D collider; 11 private SpriteSkin skin; 12 13 private readonly List<Vector3> deformedVertices = new List<Vector3>(); 14 private List<List<ushort>> outlines; 15 private List<Vector2[]> outlineVertices; 16 17 private void Awake() 18 { 19 // 必要なコンポーネントを取得しておく 20 this.collider = this.GetComponent<PolygonCollider2D>(); 21 this.skin = this.GetComponent<SpriteSkin>(); 22 23 // スプライトのメッシュの外周を成す頂点のインデックスを調べる 24 var spriteRenderer = this.GetComponent<SpriteRenderer>(); 25 var sprite = spriteRenderer.sprite; 26 var indices = sprite.triangles; 27 IEnumerable<Edge> CreateEdges(int triangleIndex) 28 { 29 var i0 = triangleIndex * 3; 30 var i1 = i0 + 1; 31 var i2 = i1 + 1; 32 yield return new Edge(indices[i0], indices[i1]); 33 yield return new Edge(indices[i1], indices[i2]); 34 yield return new Edge(indices[i2], indices[i0]); 35 } 36 var edges = Enumerable.Range(0, indices.Length / 3).SelectMany(CreateEdges).ToArray(); 37 var redundantEdges = edges.Where(e => edges.Contains(new Edge(e.To, e.From))).ToArray(); 38 var outlineEdges = new HashSet<Edge>(edges.Except(redundantEdges)); 39 this.outlines = new List<List<ushort>>(); 40 while (outlineEdges.Any()) 41 { 42 var outline = new List<ushort>(); 43 var firstEdge = outlineEdges.First(); 44 outlineEdges.Remove(firstEdge); 45 var origin = firstEdge.From; 46 outline.Add(origin); 47 var nextIndex = firstEdge.To; 48 while (nextIndex != origin) 49 { 50 outline.Add(nextIndex); 51 var nextEdge = outlineEdges.First(e => e.From == nextIndex); 52 outlineEdges.Remove(nextEdge); 53 nextIndex = nextEdge.To; 54 } 55 56 this.outlines.Add(outline); 57 } 58 this.outlineVertices = new List<Vector2[]>(Enumerable.Range(0, this.outlines.Count).Select(i => new Vector2[this.outlines[i].Count])); 59 } 60 61 private void Update() 62 { 63 // メッシュが変形されていれば... 64 if (this.skin.HasCurrentDeformedVertices()) 65 { 66 // まず変形されたメッシュの頂点座標を取得する 67 this.deformedVertices.Clear(); 68 this.deformedVertices.AddRange(this.skin.GetDeformedVertexPositionData()); 69 70 // 外周のインデックスを参照し、該当する頂点の座標を取得・整理する 71 for (var i = 0; i < this.outlines.Count; i++) 72 { 73 var outline = this.outlines[i]; 74 var positions = this.outlineVertices[i]; 75 for (var j = 0; j < outline.Count; j++) 76 { 77 positions[j] = this.deformedVertices[outline[j]]; 78 } 79 } 80 81 // コライダーにパスをセットする 82 this.collider.pathCount = this.outlines.Count; 83 for (var i = 0; i < this.outlines.Count; i++) 84 { 85 this.collider.SetPath(i, this.outlineVertices[i]); 86 } 87 } 88 } 89 90 private readonly struct Edge : IEquatable<Edge> 91 { 92 public Edge(ushort from, ushort to) 93 { 94 this.From = from; 95 this.To = to; 96 } 97 98 public readonly ushort From; 99 public readonly ushort To; 100 101 public bool Equals(Edge other) 102 { 103 return (this.From == other.From) && (this.To == other.To); 104 } 105 106 public override bool Equals(object obj) 107 { 108 return obj is Edge other && this.Equals(other); 109 } 110 111 public override int GetHashCode() 112 { 113 unchecked 114 { 115 return (this.From.GetHashCode() * 397) ^ this.To.GetHashCode(); 116 } 117 } 118 } 119}
下図のように変形しました。
投稿2021/09/06 22:12
総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/07 15:33