4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Cube や Sphere の内壁で衝突判定したい

4
Posted at

自分用メモ。

概要

メッシュの内壁と衝突判定させたい場合、Cube や Sphere といったプリミティブをそのまま使うことはできないようです。
理由は、衝突判定にはメッシュの法線ベクトルの向きが関係しており、Cube や Sphere では法線ベクトルが外向きになっているため。

衝突判定させる方法(球の場合)

プリミティブでは法線ベクトルが外向きのために内壁で衝突判定ができない……ということは、
法線ベクトルを逆向きにしてやればできる!

下記リンク先では Sphere の法線を逆向きにした Inverted Sphere を作ってインスペクタから使えるようにする方法が解説されています。
http://answers.unity3d.com/questions/514637/how-do-i-invert-normals-of-a-sphere.html

該当部分を和訳しておきます。

以下は Inverted Sphere を作るためのスクリプトです。
このスクリプトをあなたのプロジェクトの Assets/Editor フォルダに保存してください。
保存後に Hierarchy 上で右クリック > GameObject > Create Other > Inverted Sphere... を選択すると Inverted Sphere を配置できます。

InvertedSphere.cs
     using UnityEngine;
     using UnityEditor;
     
     public class InvertedSphere : EditorWindow {
         private string st = "1.0";
      
         [MenuItem("GameObject/Create Other/Inverted Sphere...")]
         public static void ShowWindow() {
             EditorWindow.GetWindow(typeof(InvertedSphere));
         }
      
         public void OnGUI() {
             GUILayout.Label("Enter sphere size:");
             st = GUILayout.TextField (st);
             
             float f;
             if (!float.TryParse (st, out f))
                 f = 1.0f;
             if (GUILayout.Button("Create Inverted Sphere")) {
                 CreateInvertedSphere(f);
             }
         }
         
         private void CreateInvertedSphere(float size) {
             GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
             MeshFilter mf = go.GetComponent<MeshFilter>();
             Mesh mesh = mf.sharedMesh;
             
             GameObject goNew = new GameObject();    
             goNew.name = "Inverted Sphere";
             MeshFilter mfNew = goNew.AddComponent<MeshFilter>();
             mfNew.sharedMesh = new Mesh();
     
             
             //Scale the vertices;
             Vector3[] vertices = mesh.vertices;
             for (int i = 0; i < vertices.Length; i++)
                 vertices[i] = vertices[i] * size;
             mfNew.sharedMesh.vertices = vertices;
             
             // Reverse the triangles
             int[] triangles = mesh.triangles;
             for (int i = 0; i < triangles.Length; i += 3) {
                 int t = triangles[i];
                 triangles[i] = triangles[i+2];
                 triangles[i+2] = t;
             }
             mfNew.sharedMesh.triangles = triangles;
             
             // Reverse the normals;
             Vector3[] normals = mesh.normals;
             for (int i = 0; i < normals.Length; i++)
                 normals[i] = -normals[i];
             mfNew.sharedMesh.normals = normals;
             
             
             mfNew.sharedMesh.uv = mesh.uv;
             mfNew.sharedMesh.uv2 = mesh.uv2;
             mfNew.sharedMesh.RecalculateBounds();
             
             // メモ: 下記3行は Unity 5.0.2 ではコンパイルエラーになりました。まるごと削除すれば普通に使えます。
             // Add the same material that the original sphere used
             MeshRenderer mr = goNew.AddComponent<MeshRenderer>();
             mr.sharedMaterial = go.renderer.sharedMaterial;
             
             DestroyImmediate(go);
         }
     }

Cube なども同じ方法で作成できそうです。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?