もくじ
Unity ARで物体を積み上げる!
前回は、UnityのARで
物体を投げました。
ARで物体を投げる。
今回は、前回の続きから
投げた物体を積み上げれ
るようにします。
※前回からの続きのため、
キューブを投げ方等は
省いています。そのため、
他の設定については、前回
のものを見ていただけると
助かります。
Unity ARで物体を積み上げる!
MeshColliderの設定
「Hierarchy」-「Plane Generator」の
Inspectorを見ます。
その中に、「DetectedPlaneVisualizer」
があります。これは、ARで平面を検出した
際に出てくるオブジェクトです。
ここにMesh Collider(衝突判定)を付けることで、
物体を積み上げることができます。
「DetectedPlaneVisualizer」 を選択して、
Inspectorを開きます。

「Add Component」から「Mesh Collider」を
追加します。
(追加の方法は、 「Mesh Collider」 を検索
もしくは「Phisics」の中にあります。)

上記の様に追加できましたら、「Convex」の
チェックは外してください。
チェックがついていると、ほかのMeshCollider
と衝突する可能性があるためです。
MeshColliderの詳細は以下のリンクからご覧
ください。
MeshColliderについて
Unity ARで物体を積み上げる!
スクリプトの設定
「DetectedPlaneVisualizer」 を選択して、
Inspectorを開きます。
InspectorのScriptである「DetectedPlaneVisualizer」
を開きます。

以下の2文を追加してください。
1 2 |
GetComponent<MeshCollider>().sharedMesh = null; GetComponent<MeshCollider>().sharedMesh = m_Mesh; |
DetectedPlaneVisualizer に追加したコードが以下です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
namespace GoogleARCore.Examples.Common { using System.Collections.Generic; using GoogleARCore; using UnityEngine; public class DetectedPlaneVisualizer : MonoBehaviour { private DetectedPlane m_DetectedPlane; private List<Vector3> m_PreviousFrameMeshVertices = new List<Vector3>(); private List<Vector3> m_MeshVertices = new List<Vector3>(); private Vector3 m_PlaneCenter = new Vector3(); private List<Color> m_MeshColors = new List<Color>(); private List<int> m_MeshIndices = new List<int>(); private Mesh m_Mesh; private MeshRenderer m_MeshRenderer; public void Awake() { m_Mesh = GetComponent<MeshFilter>().mesh; m_MeshRenderer = GetComponent<UnityEngine.MeshRenderer>(); } public void Update() { if (m_DetectedPlane == null) { return; } else if (m_DetectedPlane.SubsumedBy != null) { Destroy(gameObject); return; } else if (m_DetectedPlane.TrackingState != TrackingState.Tracking) { m_MeshRenderer.enabled = false; return; } m_MeshRenderer.enabled = true; _UpdateMeshIfNeeded(); } public void Initialize(DetectedPlane plane) { m_DetectedPlane = plane; m_MeshRenderer.material.SetColor("_GridColor", Color.white); m_MeshRenderer.material.SetFloat("_UvRotation", Random.Range(0.0f, 360.0f)); Update(); } private void _UpdateMeshIfNeeded() { m_DetectedPlane.GetBoundaryPolygon(m_MeshVertices); if (_AreVerticesListsEqual(m_PreviousFrameMeshVertices, m_MeshVertices)) { return; } m_PreviousFrameMeshVertices.Clear(); m_PreviousFrameMeshVertices.AddRange(m_MeshVertices); m_PlaneCenter = m_DetectedPlane.CenterPose.position; Vector3 planeNormal = m_DetectedPlane.CenterPose.rotation * Vector3.up; m_MeshRenderer.material.SetVector("_PlaneNormal", planeNormal); int planePolygonCount = m_MeshVertices.Count; for (int i = 0; i < planePolygonCount; ++i) { m_MeshColors.Add(Color.clear); } const float featherLength = 0.2f; const float featherScale = 0.2f; for (int i = 0; i < planePolygonCount; ++i) { Vector3 v = m_MeshVertices[i]; // Vector from plane center to current point Vector3 d = v - m_PlaneCenter; float scale = 1.0f - Mathf.Min(featherLength / d.magnitude, featherScale); m_MeshVertices.Add((scale * d) + m_PlaneCenter); m_MeshColors.Add(Color.white); } m_MeshIndices.Clear(); int firstOuterVertex = 0; int firstInnerVertex = planePolygonCount; for (int i = 0; i < planePolygonCount - 2; ++i) { m_MeshIndices.Add(firstInnerVertex); m_MeshIndices.Add(firstInnerVertex + i + 1); m_MeshIndices.Add(firstInnerVertex + i + 2); } for (int i = 0; i < planePolygonCount; ++i) { int outerVertex1 = firstOuterVertex + i; int outerVertex2 = firstOuterVertex + ((i + 1) % planePolygonCount); int innerVertex1 = firstInnerVertex + i; int innerVertex2 = firstInnerVertex + ((i + 1) % planePolygonCount); m_MeshIndices.Add(outerVertex1); m_MeshIndices.Add(outerVertex2); m_MeshIndices.Add(innerVertex1); m_MeshIndices.Add(innerVertex1); m_MeshIndices.Add(outerVertex2); m_MeshIndices.Add(innerVertex2); } m_Mesh.Clear(); m_Mesh.SetVertices(m_MeshVertices); m_Mesh.SetTriangles(m_MeshIndices, 0); m_Mesh.SetColors(m_MeshColors); //最初にNULLを設定しないと反映されませんので、注意してください。 GetComponent<MeshCollider>().sharedMesh = null; GetComponent<MeshCollider>().sharedMesh = m_Mesh; } private bool _AreVerticesListsEqual(List<Vector3> firstList, List<Vector3> secondList) { if (firstList.Count != secondList.Count) { return false; } for (int i = 0; i < firstList.Count; i++) { if (firstList[i] != secondList[i]) { return false; } } return true; } } } |
Unity ARで物体を積み上げる!
実行
編集でしたら、アンドロイドにビルドして、
実行します。
平面を認識して積み上げることができました。
読んでいただきありがとうございます。
不明点等ありましたら、コメントに
お願いいたします。