炎に放水し、水が炎に当たれば消したい | Unity Forum | Tech Stadium Forum

炎に放水し、水が炎に当たれば消したい
 
通知
すべてクリア

炎に放水し、水が炎に当たれば消したい  

  RSS

Student
(@student)
メンバー Moderator
結合: 4年前
投稿: 1325
18/03/2021 12:04 pm  
炎に放水し、水が炎に当たれば消すスクリプトを書いているのですが、
particle systemとparticle systemの重なり判定もしくは当たり判定ができないというのを調べました。
 
なので、炎のparticleにboxcolliderを設定し、boxcolliderと重なれば消すような方法を作りたいと考えています。
 
なかなか実装できないのですが、なぜ間違っているのか教えて頂けますでしょうか。
 
炎のparticlesystemのscript
Hose_Water_Particlesは放水のgameopbject
using UnityEngine;
using System.Collections;public class ParticleCollision : MonoBehaviour
{
private void Start()
{
GameObject Water = GameObject.Find("Hose_Water_Particles");
} private void OnCollisionEnter(Collider other)
{ if (other.gameObject.tag == "Water")
{
Destroy(other.gameObject);
} }
}


※ソース
ts_un_stu_202012/-/tree/user/taka/99_Portfolio/MyPortfolio

This topic was modified 3年前 3回 by Student

引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:05 pm  
このコードからだけだと、原因の特定が難しいですが、書いてあるコードに何か問題があるようには今のところ見えませんね。
以下の点に注意してもう一度確認してください。
 
①そもそもBoxColliderの当たり判定がParticleSystemの当たり判定と大きさ、形が合っているか
②どちらかのColliderの「isTrigger」がtrueになっており、CollisionEnterで判定が取れなくなってしまっているか
③そのParticleSystemのレイヤーと、当たって欲しいオブジェクトのレイヤーがヒットするようになっているか
④Destroyがうまくいっていないだけで、当たり判定自体は問題ないのか(breakポイント等を使って確認するといいですね)

返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:07 pm  
スクリプト確認致しました。
「ParticleCollision」スクリプト内の関数OnCollisionEnterを消して、以下の様に書き換えれば『炎に放水し、炎に当たれば炎が消える』という実装ができます。
private void OnParticleCollision(GameObject obj)
{
if (obj.tag == "Water")
{
Destroy(this.gameObject);
}
}
まずパーティクルの当たり判定を検出するには、OnCollisionEnter関数では無くOnParticleCollision関数を使用します。
OnParticleCollision関数は引数として必ずGamobject型の変数を使用します。
以下のサイトも参考にしてみて下さい。
https://qiita.com/Mikoshi/items/ed2e02acdce3ee5c3998
 
また、Destroyする指定はタグ判断で使用した水のオブジェクトでは無く、this.gameobjectで炎自身のオブジェクトを指定してください。
そうすれば、放水のパーティクルが触れた時点で炎のオブジェクトが消えます。

返信引用
Student
(@student)
メンバー Moderator
結合: 4年前
投稿: 1325
18/03/2021 12:14 pm  

ありがとうございます!
続けて質問ですが、5秒間当たればtransform.scaleを半分に、
10秒間当たれば消すというようなif文を作成したいと考えております。

何か良い記事かヒントをいただけませんでしょうか。


返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:15 pm  

OnParticleCollisionはパーティクルが触れている間ずっと呼ばれるので、
変数で触れている時間を計測して、if文等で経過時間ごとに効果を実装すれば良いと思います。

具体的な実装方法は手探りで是非試してみて下さい。


返信引用
Student
(@student)
メンバー Moderator
結合: 4年前
投稿: 1325
18/03/2021 12:15 pm  

using UnityEngine;
using System.Collections;
public class ParticleCollision : MonoBehaviour
{
    float seconds = 5f;
    private void Start()
    {
        GameObject Water = GameObject.Find("Hose_Water_Particles");    }
    private void OnParticleCollision(GameObject obj)
    {    seconds += Time.deltaTime;        if (obj.tag == "Water")
        {
            Destroy(this.gameObject);
        }
    }
}

時間は指定できたのですが、接触する時間の算出はどのようにやればいいのでしょうか。


返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:16 pm  
OnParticleCollisionはパーティクルが触れている間ずっと呼ばれるので、
記載して頂いたスクリプトの変数「seconds」で接触時間の計測は出来ていますよ。
それをif文等で
if( 指定時間 < seconds  ) //指定時間よりsecondsが大きくなったらif文の処理を開始
{
 処理
}
といった様にやれば問題ありません。

返信引用
Student
(@student)
メンバー Moderator
結合: 4年前
投稿: 1325
18/03/2021 12:19 pm  

using UnityEngine;
using System.Collections;
public class ParticleCollision : MonoBehaviour
{
    float seconds = 10f;
    private void Start()
    {
        GameObject Water = GameObject.Find("Hose_Water_Particles");
    }
    private void OnParticleCollision(GameObject obj)
    {    seconds += Time.deltaTime;        if (obj.tag == "Water")
        {
            if ( 9 < seconds)
            {
                Destroy(this.gameObject);
            }
            }
    }
}

何度もすみません。接触した瞬間消えるのですが、、、間違えてますか?


返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:20 pm  

OnParticleCollision関数は、自身の炎のパーティクルに接触した際にも関数内の処理が呼ばれます。

現在のスクリプトでは、水のパーティクルが触れていなくても、常に変数secondsでの時間計測が行われてしまいます。

なので、「seconds += Time.deltaTime;」を「if (obj.tag == "Water")」の中に入れて下さい。

そうすれば、水のパーティクルが触れた時のみ時間計測が行われるはずです。


返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:21 pm  

プロジェクトを確認したのですが、正常に水を当て続けて9秒経過した後に炎のオブジェクトが消えます。

状況確認がこちらでできない状態なので、ひとまず「ParticleCollision」スクリプトの
変数「seconds」に[SerializeField]を付けてインスペクタに表示するか、
Debug.Logを使うかで、数値がどのように変動しているかを確認してみて下さい。

そうすれば「Water」タグを持ったパーティクルが触れる前から数値が増えているのか、
「Water」タグを持ったパーティクルが触れたら急激な増え方をしているか等がわかるはずです。


返信引用
Teacher
(@admin)
メンバー Admin
結合: 4年前
投稿: 1296
18/03/2021 12:22 pm  

「9秒間BoxColiderにパーティクルの接触があったら、炎が消える」という感じですね。

OnParticleCollisionはBoxColiderにパーティクルが当たった場合に呼ばれるので、この解釈で問題ありません。


返信引用
共有:
タイトルとURLをコピーしました