日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

关于Unity粒子系统碰撞的几个坑

發(fā)布時間:2024/3/24 windows 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Unity粒子系统碰撞的几个坑 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關(guān)于Unity粒子系統(tǒng)碰撞的幾個坑

最近公司的項目正好要用到粒子系統(tǒng)的碰撞,所以特意研究了一下。在實踐中遇到了很多問題,所以借此文記錄一下學習的過程。而且學習過程中發(fā)現(xiàn)網(wǎng)上這方面文章極少,所以也算借這篇文章填補一下行業(yè)漏洞,順道給自己和后來者一個參考。本人接觸Unity時間也不算太長,如果下面哪里說的不對,歡迎各位大神糾正。
大量圖片預(yù)警

粒子與碰撞器的碰撞

這一部分官方用戶手冊有很明確的說明,首先找到手冊下圖這一層級目錄 Collision Module,點進去就能看到關(guān)于面板所有參數(shù)的介紹了:

這里我用的是Unity5.6.4的用戶手冊,是本地文件,所以就不貼鏈接了,而且我相信愿意看這篇文章的人,應(yīng)該不至于找不到用戶手冊吧……
這篇手冊已經(jīng)講得詳細了,所以我們只討論一些文章里沒有提到的東西和提到了但是說得比較模糊的東西。點進去之后拉到文章最后你會看到這樣一段關(guān)于粒子碰撞的介紹:

簡單的說就是告訴你怎么用碰撞檢測腳本,但是請注意它說的是 the object with the particle system, or the one with the Collider, or both 也就是說只有帶有粒子系統(tǒng)或者帶有碰撞器的物體之間可以碰撞,而且經(jīng)過我的實踐發(fā)現(xiàn):只有一個帶有碰撞器組件的物體和一個帶有粒子系統(tǒng)并開啟了粒子碰撞的物體之間碰撞才會觸發(fā)碰撞事件,其他任何情況都無法觸發(fā)粒子碰撞事件,如果您不信可以繼續(xù)看下去。
我們先來看一下簡單的一種情況,也就是官方提供的這種情況,同時也是網(wǎng)上在我寫這篇文章之前能搜到的最多的一種情況。所以我盡量用最短的篇幅介紹,如果您除了這種情況不會用到其他情況,那看完這一小節(jié)后下面的就不用看了。
我們打開Unity直接實踐:
新建一個場景,創(chuàng)建一個平面當?shù)孛?#xff0c;刪掉原有攝像機(我們會用FPS控制器,自帶相機),拖上來一個粒子(這里你隨意拖一個粒子就好,我用的是一個火焰粒子),開啟粒子碰撞,我的設(shè)置如下,其中 Radius ScaleColliders With 要根據(jù)你的實際粒子來設(shè)置,前者為碰撞器大小,后者為需要碰撞的層。

然后我為了節(jié)省時間是把標準資源中的FPS控制器拖進來了,如果你有時間可以自己寫一個FPS控制器……然后將控制器的標簽和層都改成 “Player” ,如果沒有可以自己添加,只要記得添加好后把 Colliders With 也相應(yīng)改好就行。現(xiàn)在你選中粒子應(yīng)該可以在Scene視圖下看到粒子碰撞器了:

然后開始寫腳本吧,我就用最簡單的代碼測試一下,代碼如下,腳本拖到粒子身上:

using System.Collections; using System.Collections.Generic; using UnityEngine;public class FireTest : MonoBehaviour {private void OnParticleCollision(GameObject other){if (other.tag == "Player"){Debug.Log("一個玩家已死亡");}} }

接下來運行游戲即可,走到火焰上就會看到打印,說明碰撞檢測生效。你應(yīng)該會注意到不但打印了而且打印了很多次,這說明每一個粒子的碰撞都會單獨觸發(fā)。

截至到此,如果您不需要用到其他的碰撞(只是粒子和帶碰撞器組件的物體之間的碰撞),您可以不用往下看了。

粒子與射線的碰撞

接下來我們看一下射線與粒子的碰撞。這是我在做項目的時候,項目需要做一個準星檢測前方區(qū)域是否有粒子然后變色的功能,自然得就想到要用射線檢測。還用剛才的場景,為了加強說服力,我把 Colliders With 改成“Everything”,也就是可以和一切有碰撞的物體碰撞,然后寫發(fā)射射線腳本,代碼如下,掛在FPS控制器身上。

using System.Collections; using System.Collections.Generic; using UnityEngine;public class ShootTest : MonoBehaviour {void Update (){RaycastHit hit;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out hit)){Debug.Log(hit.collider);if (hit.collider.gameObject.tag == "Fire"){Debug.Log("前方有火");}}} }

同時為了加強說服力我們把火焰粒子物體的標簽改為“Fire”,并把層設(shè)置為“Player”,然后修改其身上的腳本如下,運行游戲

sing System.Collections; using System.Collections.Generic; using UnityEngine;public class FireTest : MonoBehaviour {private void OnParticleCollision(GameObject other){Debug.Log("粒子發(fā)生碰撞");if (other.tag == "Player"){Debug.Log("一個玩家已死亡");}} }

運行后我們,當我們把鏡頭轉(zhuǎn)向火時只打印了地面,無論怎么改變鏡頭朝向都沒有其他打印

經(jīng)過這個例子,我想大家已經(jīng)明白吧,首先射線不含有碰撞器組件,所以無法被粒子檢測到,其次,粒子碰撞只是粒子組件的一個屬性,所以也不能算成是碰撞器組件,而射線其實能夠檢測的也只有帶有碰撞器組件的物體。
為了驗證我的射線代碼沒有問題,我在場景中放了一個Cube,將其標簽設(shè)置為“Fire”,如下:

這時運行游戲可以看到如下打印,說明我的射線代碼也沒有問題:

綜上所述,得出結(jié)論 射線與粒子的碰撞器是無法發(fā)生碰撞 的。這是Unity這個引擎的問題,不是我們用代碼可以解決的。

粒子與粒子的碰撞

最后讓我們看一下粒子和粒子之間的碰撞,這個也是我在項目中實踐發(fā)現(xiàn)的問題,因為我們的項目需要做一個水粒子撲滅火粒子的功能,所以也是自然就像到粒子之間是否會發(fā)生碰撞。
廢話不多說,還是用實踐來檢驗:
還用剛才的場景,不過這次不必用FPS控制器,所以刪掉它,加一個攝像機,調(diào)好角度能看到火焰粒子就好。然后加入一個水的粒子(這個粒子您也可以隨便加,只要保證粒子有初始速度,并且往火粒子那邊發(fā)射就好),水粒子也同樣要開啟碰撞,設(shè)置同上,把 Colliders With 設(shè)置為“Everything”來增強說服力,調(diào)節(jié)好碰撞器大小,不要勾選 Play On Awake 因為我們要用代碼控制粒子播放 ,接下來寫腳本,代碼如下,腳本拖到水粒子身上。

using System.Collections; using System.Collections.Generic; using UnityEngine;public class WaterTest : MonoBehaviour {private ParticleSystem par;void Start(){par = GetComponent<ParticleSystem>();}void Update(){if (Input.GetKeyDown(KeyCode.Q)){par.Play();}}private void OnParticleCollision(GameObject other){if (other.tag == "Fire"){Debug.Log("水粒子碰到了火粒子");}} }

運行游戲,運行后按下Q鍵,可以看到水粒子落下,但是沒有任何打印:

綜上所述,得出結(jié)論 粒子與粒子之間無法發(fā)生碰撞

對于以上問題的我的解決方案

根據(jù)以上我們得出的結(jié)論,我們知道了 粒子的碰撞器只能和帶有碰撞器組件的物體發(fā)生碰撞并觸發(fā)事件 ,由于射線和粒子本身都不帶有碰撞器組件,所以是無法發(fā)生碰撞的,那么這兩種情況我們要怎么實現(xiàn)呢,以下僅是我個人能夠想到的解決方案,但不一定是最好的,如果有大神有更好的解決方案 歡迎提出:

對于射線無法檢測的解決方案

我能想到三種解決方法:
1、直接給需要檢測的粒子物體加觸發(fā)器,觸發(fā)器區(qū)域要比粒子碰撞器能到達的最遠區(qū)域大,從而在玩家即將進入粒子區(qū)域時通過 On Trigger Enter 通知玩家,該方法無法在玩家離粒子較遠時使用,并且也不會隨著玩家視野旋轉(zhuǎn)而產(chǎn)生不同的通知(例如煙區(qū)域和火區(qū)域的區(qū)分);
2、給粒子物體加一個空子物體,在子物體上加碰撞器,給子物體設(shè)置一個單獨的層,使該層的碰撞器不會碰到玩家,從而不會影響玩家移動,在下圖窗口中有碰撞矩陣的設(shè)置,可以修改各層之間的碰撞。然后還是玩家發(fā)射射線,來檢測子物體的碰撞器,該方法可能會影響到粒子的碰撞,不是很推薦,但是效果最好。

3、讓粒子系統(tǒng)所在物體向自身所在環(huán)形區(qū)域發(fā)射射線,檢測玩家后修改玩家身上記錄區(qū)域的變量,此方法彌補了前兩種方法的不足,但是最費性能,不推薦在手機游戲種使用。

對于粒子之間無法檢測的解決方案

由于粒子的特殊性,暫時只能想到一種解決方法:
給其中一個粒子加一個碰撞器或者給其子物體加碰撞器。
但是請不要給粒子系統(tǒng)所在物體加剛體,我試過,會發(fā)生奇怪的現(xiàn)象,暫時還沒有搞清楚這個現(xiàn)象的原因:粒子會掉在地上,彈跳幾下,然后迅速飛走…………
可以給加了碰撞器的子物體加剛體,然后在粒子播放時觸發(fā)剛體,從而到達和水粒子一起碰到火粒子的效果

以上內(nèi)容,都為我個人看法和實踐得出結(jié)論,如果說的不妥當處還望前輩高人指點,完結(jié)撒花……

總結(jié)

以上是生活随笔為你收集整理的关于Unity粒子系统碰撞的几个坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。