質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Kinect

Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。

Q&A

解決済

1回答

6484閲覧

UnityとKinectを用いた当たり判定

black_sleepman

総合スコア220

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Kinect

Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。

0グッド

0クリップ

投稿2016/08/16 02:46

編集2016/08/16 02:52

Unity初心者でUnityとKinectを用いて開発しています。
現在行いたいこととして、Kinectからの深度情報をもとに画像(Raw Image)を生成しQuadメッシュに画像を表示させています。
その、表示させている画像とGame Objectで当たり判定を行いたいと思っているのですが、うまくできません。

こちらがKinectから得たデータをもとにQuadメッシュに画像を表示させているソース全文になります。

C#

1using UnityEngine; 2using Windows.Kinect; 3using System; 4 5public class SimpleDepthView : MonoBehaviour 6{ 7 public GameObject depthSourceManager; 8 private DepthSourceManager depthSourceManagerScript; 9 10 Texture2D texture; 11 byte[] depthBitmapBuffer; 12 FrameDescription depthFrameDesc; 13 14 public float scale = 1.0f; 15 16 void Start() 17 { 18 // Get the description of the depth frames. 19 depthFrameDesc = KinectSensor.GetDefault().DepthFrameSource.FrameDescription; 20 21 // get reference to DepthSourceManager (which is included in the distributed 'Kinect for Windows v2 Unity Plugin zip') 22 depthSourceManagerScript = depthSourceManager.GetComponent<DepthSourceManager>(); 23 24 // allocate. 25 depthBitmapBuffer = new byte[depthFrameDesc.LengthInPixels * 4]; 26 texture = new Texture2D(depthFrameDesc.Width, depthFrameDesc.Height, TextureFormat.BGRA32, false); 27 28 // arrange size of gameObject to be drawn 29 gameObject.transform.localScale = new Vector3(scale * depthFrameDesc.Width / depthFrameDesc.Height, scale, 1.0f); 30 } 31 32 void Update() 33 { 34 updateTexture(); 35 this.GetComponent<Renderer>().material.mainTexture = texture; 36 } 37 38 // Depth判定範囲 39 int min = 500; 40 int max = 1500; 41 void updateTexture() 42 { 43 // get new depth data from DepthSourceManager. 44 ushort[] rawdata = depthSourceManagerScript.GetData(); 45 46 // convert to byte data ( 47 for (int i = 0; i < rawdata.Length; i++) 48 { 49 // BGRAの順番 50 int colorindex = i * 4; 51 52 depthBitmapBuffer[i * 4 + 0] = (byte)0; // B // 53 depthBitmapBuffer[i * 4 + 1] = (byte)((min < rawdata[i]) && (rawdata[i] < max) ? 255 : 0); // G // COMMON 54 depthBitmapBuffer[i * 4 + 2] = (byte)0; // R // 55 depthBitmapBuffer[i * 4 + 3] = (byte)((min < rawdata[i]) && (rawdata[i] < max) ? 255 : 0); // A // COMMON 56 } 57 58 // make texture from byte array 59 texture.LoadRawTextureData(depthBitmapBuffer); 60 texture.Apply(); 61 } 62}

Mesh Colliderなども使ってみましたが、うまくできませんでした。

開発環境としては
・Windows 10 ( BootCamp )
・Visual Studio 2015
・Unity Personal v5.3.5
・Kinect v2

です。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

KinectとColliderに関連性は無さそうなので、
通常のQuadオブジェクトとGameObjectによる衝突判定の問題かと思われます。

Quadオブジェクトは厚さが0なので、衝突せずすり抜けている可能性が高いです。
詳しくは「衝突判定の再考、壁抜けを止める」をご覧ください。

投稿2016/08/20 07:06

sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

black_sleepman

2016/09/07 09:40

コメントありがとうございます。 Quadオブジェクトに厚さを持たせる方法はあるのでしょうか? また、Kinectから得た深度情報とGameObjectの当たり判定をする方法はあるのでしょうか。
sakura_hana

2016/09/07 12:46

Quad自体は厚さを変えられませんが、Quadオブジェクトに付いているColliderを厚くすれば当たり判定されやすくなります。 Kinectの深度情報がどういうデータで出て来るのか分かりませんが、もしただの数値やVector3のような座標データであるなら、GameObjectの位置(座標)による比較か、RayCastを用いた方が確実かもしれません。
black_sleepman

2016/09/08 11:54 編集

```C# using UnityEngine; using System.Collections; using Windows.Kinect; public enum DepthViewMode { SeparateSourceReaders, MultiSourceReader, } public class DepthSourceView : MonoBehaviour { public DepthViewMode ViewMode = DepthViewMode.SeparateSourceReaders; public GameObject ColorSourceManager; public GameObject DepthSourceManager; public GameObject MultiSourceManager; private KinectSensor _Sensor; private CoordinateMapper _Mapper; private Mesh _Mesh; private Vector3[] _Vertices; private Vector2[] _UV; private int[] _Triangles; // Only works at 4 right now private const int _DownsampleSize = 4; private const double _DepthScale = 0.5f; private const int _Speed = 50; private MultiSourceManager _MultiManager; private ColorSourceManager _ColorManager; private DepthSourceManager _DepthManager; void Start() { _Sensor = KinectSensor.GetDefault(); if (_Sensor != null) { _Mapper = _Sensor.CoordinateMapper; var frameDesc = _Sensor.DepthFrameSource.FrameDescription; // Downsample to lower resolution CreateMesh(frameDesc.Width / _DownsampleSize, frameDesc.Height / _DownsampleSize); if (!_Sensor.IsOpen) { _Sensor.Open(); } } } void CreateMesh(int width, int height) { _Mesh = new Mesh(); GetComponent<MeshFilter>().mesh = _Mesh; _Vertices = new Vector3[width * height]; _UV = new Vector2[width * height]; _Triangles = new int[6 * ((width - 1) * (height - 1))]; int triangleIndex = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int index = (y * width) + x; _Vertices[index] = new Vector3(x, -y, 0); _UV[index] = new Vector2(((float)x / (float)width), ((float)y / (float)height)); // Skip the last row/col if (x != (width - 1) && y != (height - 1)) { int topLeft = index; int topRight = topLeft + 1; int bottomLeft = topLeft + width; int bottomRight = bottomLeft + 1; _Triangles[triangleIndex++] = topLeft; _Triangles[triangleIndex++] = topRight; _Triangles[triangleIndex++] = bottomLeft; _Triangles[triangleIndex++] = bottomLeft; _Triangles[triangleIndex++] = topRight; _Triangles[triangleIndex++] = bottomRight; } } } _Mesh.vertices = _Vertices; _Mesh.uv = _UV; _Mesh.triangles = _Triangles; _Mesh.RecalculateNormals(); } void OnGUI() { GUI.BeginGroup(new Rect(0, 0, Screen.width, Screen.height)); GUI.TextField(new Rect(Screen.width - 250 , 10, 250, 20), "DepthMode: " + ViewMode.ToString()); GUI.EndGroup(); } void Update() { if (_Sensor == null) { return; } if (Input.GetButtonDown("Fire1")) { if(ViewMode == DepthViewMode.MultiSourceReader) { ViewMode = DepthViewMode.SeparateSourceReaders; } else { ViewMode = DepthViewMode.MultiSourceReader; } } float yVal = Input.GetAxis("Horizontal"); float xVal = -Input.GetAxis("Vertical"); transform.Rotate( (xVal * Time.deltaTime * _Speed), (yVal * Time.deltaTime * _Speed), 0, Space.Self); if (ViewMode == DepthViewMode.SeparateSourceReaders) { if (ColorSourceManager == null) { return; } _ColorManager = ColorSourceManager.GetComponent<ColorSourceManager>(); if (_ColorManager == null) { return; } if (DepthSourceManager == null) { return; } _DepthManager = DepthSourceManager.GetComponent<DepthSourceManager>(); if (_DepthManager == null) { return; } gameObject.GetComponent<Renderer>().material.mainTexture = _ColorManager.GetColorTexture(); RefreshData(_DepthManager.GetData(), _ColorManager.ColorWidth, _ColorManager.ColorHeight); } else { if (MultiSourceManager == null) { return; } _MultiManager = MultiSourceManager.GetComponent<MultiSourceManager>(); if (_MultiManager == null) { return; } gameObject.GetComponent<Renderer>().material.mainTexture = _MultiManager.GetColorTexture(); RefreshData(_MultiManager.GetDepthData(), _MultiManager.ColorWidth, _MultiManager.ColorHeight); } } private void RefreshData(ushort[] depthData, int colorWidth, int colorHeight) { var frameDesc = _Sensor.DepthFrameSource.FrameDescription; ColorSpacePoint[] colorSpace = new ColorSpacePoint[depthData.Length]; _Mapper.MapDepthFrameToColorSpace(depthData, colorSpace); for (int y = 0; y < frameDesc.Height; y += _DownsampleSize) { for (int x = 0; x < frameDesc.Width; x += _DownsampleSize) { int indexX = x / _DownsampleSize; int indexY = y / _DownsampleSize; int smallIndex = (indexY * (frameDesc.Width / _DownsampleSize)) + indexX; double avg = GetAvg(depthData, x, y, frameDesc.Width, frameDesc.Height); // print("avg:: " + avg + "\n"); avg = avg * _DepthScale; // print("_DepthScale * avg:: " + avg + "\n"); _Vertices[smallIndex].z = (float)avg; // Update UV mapping with CDRP var colorSpacePoint = colorSpace[(y * frameDesc.Width) + x]; _UV[smallIndex] = new Vector2(colorSpacePoint.X / colorWidth, colorSpacePoint.Y / colorHeight); } } _Mesh.vertices = _Vertices; _Mesh.uv = _UV; _Mesh.triangles = _Triangles; _Mesh.RecalculateNormals(); } private double GetAvg(ushort[] depthData, int x, int y, int width, int height) { double sum = 0.0; for (int y1 = y; y1 < y + 4; y1++) { for (int x1 = x; x1 < x + 4; x1++) { int fullIndex = (y1 * width) + x1; if (depthData[fullIndex] == 0) sum += 4500; else sum += depthData[fullIndex]; } } return sum / 16; } void OnApplicationQuit() { if (_Mapper != null) { _Mapper = null; } if (_Sensor != null) { if (_Sensor.IsOpen) { _Sensor.Close(); } _Sensor = null; } } } ``` これが実際にKinectから得た深度情報をQuad(Plane)オブジェクトに投影しているプログラムになります。Vector3ということはX,Y,Z成分をもつデータを生成して、それをQuadに投影しているという認識で合ってますでしょうか。なので、Z方向の値を大きくすればObjectと衝突し当たり判定が動くようになるのでしょうか。 あまりにも無知ですいません。回答よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問