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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

1580閲覧

Unityでパーティクル座標がうまく取得・計算できない

KSKH

総合スコア1

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2022/02/22 01:43

概要

  • Unityでパーティクルを使ったスクリプトを作成していて行き詰ってしまいました。
  • 困っていることの概要は以下になります。原因や解決方法についてご意見いただけないでしょうか。
    よろしくお願いいたします。

作業環境

  • windows10 pro
  • unity 2021.2.7f1

やりたいこと

  • Unityで放出されているパーティクルの座標の最大最小値を取得したい
  • パーティクルはcone状に発生、発生元から上(y軸+方向)に上がっていく

問題

  • パーティクルによって、座標値がうまく取得できていないと思われる結果になる
    • 発生元と、パーティクル最大最小の座標がずれる
  • 発生する速度やサイズなど主なパラメータについては揃えてみたが改善しない
  • 取得方法の実装について間違いがある?

実装

  • 計算部分を抜粋した内容は以下になります

cs

1[SerializeField] 2 private ParticleSystem _particleSystem; 3 4void Update () 5{ 6 // パーティクルを取得 7 var particleCount = _particleSystem.particleCount; 8 ParticleSystem.Particle[] particles = new ParticleSystem.Particle[particleCount]; 9 _particleSystem.GetParticles(particles); 10 11 // パーティクルのワールド座標を取得 12 Vector3[] particles_worldpos = new Vector3[particleCount]; 13 for( int i=0 ; i<particleCount ; i++ ){ 14 particles_worldpos[i] = _particleSystem.transform.TransformPoint(particles[i].position); 15 } 16 17 // 最大最小を求める 18 var pos3_min = min_pos3( particles_worldpos, particleCount ); // get min in particles 19 var pos3_max = max_pos3( particles_worldpos, particleCount ); // get max in particles 20 21 // 出力 最小値、最大値、パーティクルシステム座標値 22 Vector3 tmp_s = _particleSystem.transform.position; 23 string s1 = $"particle min: {pos3_min}, max: {pos3_max}, system: {tmp_s}"; 24 Debug.Log($"{s1}"); 25 26} 27 28// 最大最小を計算する 29Vector3 min_pos3( Vector3[] pos, int count ) 30 { 31 Vector3 ret= new Vector3(); 32 float min_x = float.MaxValue; 33 float min_y = float.MaxValue; 34 float min_z = float.MaxValue; 35 36 for( int idx=0 ; idx<count ; idx++ ){ 37 if( min_x > pos[idx].x ) min_x = pos[idx].x; 38 if( min_y > pos[idx].y ) min_y = pos[idx].y; 39 if( min_z > pos[idx].z ) min_z = pos[idx].z; 40 } 41 42 ret.x = min_x; 43 ret.y = min_y; 44 ret.z = min_z; 45 46 return( ret ); 47 } 48 49 Vector3 max_pos3( Vector3[] pos, int count ) 50 { 51 Vector3 ret= new Vector3(); 52 float max_x = float.MinValue; 53 float max_y = float.MinValue; 54 float max_z = float.MinValue; 55 56 for( int idx=0 ; idx<count ; idx++ ){ 57 if( max_x < pos[idx].x ) max_x = pos[idx].x; 58 if( max_y < pos[idx].y ) max_y = pos[idx].y; 59 if( max_z < pos[idx].z ) max_z = pos[idx].z; 60 } 61 62 ret.x = max_x; 63 ret.y = max_y; 64 ret.z = max_z; 65 66 return( ret ); 67 } 68

出力結果

  • パーティクルA、Bを同じ位置に設置。見た目での大きさもほぼ同じぐらいに設定
  • パーティクルAでのログ(frame=10)
    particle min: (18.62, -31.04, 67.70), max: (20.08, -28.89, 68.80), system: (18.72, -31.04, 68.18)
  • パーティクルBでのログ(frame=10)
    particle min: (22.41, -37.23, 81.55), max: (22.68, -36.32, 81.84), system: (18.72, -31.04, 68.18)
  • パーティクルBでは、設置した位置から座標値が大きくずれてしまう

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問にあるコードで取得しているのはパーティクルの座標ではなく、Particle System コンポーネントがアタッチされているオブジェクトの座標なので、実際のパーティクルの座標を取るコードを書いてみました。

csharp

1using UnityEngine; 2 3public class ParticleData : MonoBehaviour 4{ 5 [SerializeField] ParticleSystem _target = default; 6 7 void Start() 8 { 9 if (_target.main.simulationSpace != ParticleSystemSimulationSpace.World) 10 { 11 Debug.LogWarning("Particle のワールド空間上の座標を取得するために Simulation Space を World に設定してください。"); 12 } 13 } 14 15 void Update() 16 { 17 ParticleSystem.Particle[] particles = new ParticleSystem.Particle[_target.main.maxParticles]; 18 int count = _target.GetParticles(particles); 19 float highest = float.MinValue; 20 21 for (int i = 0; i < count; i++) 22 { 23 highest = Mathf.Max(highest, particles[i].position.y); 24 } 25 26 Debug.Log($"Particle は現在 {count} 個あり、一番高い所にある Particle の y 座標は {highest} です。"); 27 } 28}

投稿2022/02/22 06:03

bboydaisuke

総合スコア5339

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

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

KSKH

2022/02/22 07:24

ご回答ありがとうございます。 教えていただいたサンプルコードで確認してみましたところ、無事に座標が取得できるようになりました! 私の設定を見たところpositionの取得と同時に、もう一つ間違えていました。 一つのパーティクルはSimulation SpaceをWorldに、もう一つはLocalに設定していました。 サンプルコードでSimulation Spaceのチェックもいれていただいたおかげで気づきました。 大変勉強になりました、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問