Распространение огня

Лучший способ помочь другим, поделиться своими находками.

Распространение огня

Сообщение alexz 18 ноя 2010, 02:16

В рамках изучения Unity сделал скрипты, которые позволяют поджигать объекты, чтобы пламя при этом могло перекидываться на соседние объекты.

Что нужно сделать, чтобы устроить пожар:

1. На те объекты, которым позволительно гореть, надо повесить скрипт FireController. У него есть несколько свойств:
а) Is Combustible (boolean) ― может ли объект загораться,
б) Is Burning (boolean) ― горит ли объект в данный момент,
в) Intensity (int) ― интенсивность горения (пока это просто количество частиц огня; чем больше объект, тем большее желательно значение).

2. Добавить любой коллайдер к объектам, которые должны уметь загораться от горящих соседей.

3. Поместить на сцену экземпляр префаба FireManager. У него есть два свойства:
а) Burning Dummy Prefab ― болванка с настроенной системой частиц для показа пламени.
б) Sparking Dummy Prefab ― болванка с настроенной системой частиц для разлетающихся угольков.

Как работает:

1. При старте FireManager находит все объекты с подключенным FireController и поджигает те, у которых IsBurning = true.
2. Когда объект зажигается, в его позиции в пространстве создаются невидимые экземпляры источников частиц пламени и угольков. В них используется MeshParticleEmitter, у которого свойство mesh подменяется сеткой реального поджигаемого объекта. В результате частицы появляются по всей поверхности объекта.
3. Если разлетающиеся в разные стороны угольки попадают на соседний объект, у которого есть какой-нибудь коллайдер, подключен скрипт FireController и в нем IsCombustible = true, то этот соседний объект точно так же загорается.
4. Чтобы поджечь объект вручную, у него нужно вызвать функцию Ignite(). Чтобы погасить горящий объект ― функцию Extinguish().

Код скриптов:

Синтаксис:
Используется csharp
using System.Collections.Generic;
using UnityEngine;

public class FireController : MonoBehaviour
{
        /// <summary>
        /// All currently burning objects dictionary.
        /// Key - burning object, Value - array of burning dummy and sparking dummy instances
        /// </summary>
        private static readonly Dictionary<GameObject, GameObject[]> burningObjectDictionary = new Dictionary<GameObject, GameObject[]>();

        /// <summary>
        /// Affects <span class="posthilit">particle</span> emission amount when burning
        /// </summary>
        public int intensity = 50;

        public bool isBurning = false;
        public bool isCombustible = true;

        // Start burning
        public void Ignite()
        {
                isBurning = true;

                var fireManager = (FireManager) FindObjectOfType(typeof (FireManager));
                if (fireManager == null)
                {
                        print("[Error] Igniting failed: can't find FireManager on scene.");
                        return;
                }
                if (fireManager.burningDummyPrefab == null)
                {
                        print("[Error] Igniting failed: burningDummyPrefab is not specified in FireManager.");
                        return;
                }
                if (fireManager.sparkingDummyPrefab == null)
                {
                        print("[Error] Igniting failed: sparkingDummyPrefab is not specified in FireManager.");
                        return;
                }

                var fireDummy = (GameObject) Instantiate(fireManager.burningDummyPrefab);
                fireDummy.transform.localPosition = transform.localPosition;
                fireDummy.transform.localRotation = transform.localRotation;
                fireDummy.transform.localScale = transform.localScale;
                fireDummy.transform.parent = transform;

                var sparkingDummy = (GameObject) Instantiate(fireManager.sparkingDummyPrefab);
                sparkingDummy.transform.localPosition = transform.localPosition;
                sparkingDummy.transform.localRotation = transform.localRotation;
                sparkingDummy.transform.localScale = transform.localScale;
                sparkingDummy.transform.parent = transform;

                var burningDummyMeshFilter = (MeshFilter) fireDummy.GetComponent("MeshFilter");
                if (burningDummyMeshFilter == null)
                {
                        print("[Error] Igniting failed: burningDummyPrefab in FireManager have no MeshFilter component");
                        return;
                }

                var sparkingDummyMeshFilter = (MeshFilter) sparkingDummy.GetComponent("MeshFilter");
                if (sparkingDummyMeshFilter == null)
                {
                        print("[Error] Igniting failed: sparkingDummyPrefab in FireManager have no MeshFilter component");
                        return;
                }

                var targetMeshFilter = (MeshFilter) GetComponent("MeshFilter");
                if (targetMeshFilter == null)
                {
                        print(string.Format("[Error] Igniting faild: burning object ({0}) have no MeshFilter component", name));
                        return;
                }

                burningDummyMeshFilter.<span class="posthilit">mesh</span> = sparkingDummyMeshFilter.<span class="posthilit">mesh</span> = targetMeshFilter.<span class="posthilit">mesh</span>;

                var targetFireController = (FireController) GetComponent("FireController");
                fireDummy.particleEmitter.minEmission = fireDummy.particleEmitter.maxEmission = targetFireController.intensity;

                burningObjectDictionary.Add(gameObject, new[] {fireDummy, sparkingDummy});
        }

        // Stop burning
        public void Extinguish()
        {
                isBurning = false;

                if (burningObjectDictionary.ContainsKey(gameObject) == false)
                {
                        print(string.Format("[Warning] Can't extinguish the object ({0}) that isn't burning.", name));
                }
                var dummies = burningObjectDictionary[gameObject];
                burningObjectDictionary.Remove(gameObject);
                Destroy(dummies[0]);
                Destroy(dummies[1]);
        }

        // Ignite the object if a spark <span class="posthilit">particle</span> hits it
        private void OnParticleCollision(GameObject target)
        {
                var controller = (FireController) target.GetComponent("FireController");
                if (controller == null)
                {
                        return;
                }

                if (controller.isCombustible && controller.isBurning == false)
                {
                        controller.Ignite();
                }
        }
}


Синтаксис:
Используется csharp
using UnityEngine;

public class FireManager : MonoBehaviour
{
        public GameObject burningDummyPrefab = null;
        public GameObject sparkingDummyPrefab = null;

        // Ignite all objects with isBurning == true
        private void Start()
        {
                var targets = FindObjectsOfType(typeof (FireController));

                foreach (FireController target in targets)
                {
                        if (target.isBurning)
                        {
                                target.Ignite();
                        }
                }
        }
}


Ссылка на package:
http://www.autosim-utilities.ru/unity/F ... itypackage

Тест:

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://www.autosim-utilities.ru/unity/Fire.unity3d&w=600&h=400&t=true&preview=1' height='"+(400+30)+"' width='600' frameborder='0' scrolling='no'></iframe>"); </script>
alexz
UNITрон
 
Сообщения: 270
Зарегистрирован: 16 ноя 2010, 23:37

Re: Распространение огня

Сообщение alexz 18 ноя 2010, 02:43

Из любопытства повесил FireController на FirstPersonController, подошёл к огню и загорелся сам :)
alexz
UNITрон
 
Сообщения: 270
Зарегистрирован: 16 ноя 2010, 23:37

Re: Распространение огня

Сообщение Zaicheg 18 ноя 2010, 10:01

Прилично. А для каких целей это делается?

var targetFireController = (FireController) GetComponent("FireController");

Вы var используете потому что не знаете, какой тип получаете или из личных предпочтений? Просто очень непривычно (до недавнего времени у нас была не очень новая версия Mono).
Кстати, в Unity через C# более употребительной сейчас является конструкция GetComponent<FireController>(). В 2.6 ввели и там была какой-то прогон на тему того, что теперь надо так. Хотя может и путаю.
Дьяченко Роман
e-mail: _zaicheg.reg@gmail.com
skype: zaicheg12
vkontakte: _vk.com/zaichegq
Работа: _wie3.com _www.sanviz.com
Аватара пользователя
Zaicheg
Адепт
 
Сообщения: 3024
Зарегистрирован: 19 июн 2009, 15:12
Откуда: Череповец

Re: Распространение огня

Сообщение alexz 18 ноя 2010, 14:40

Zaicheg писал(а):Прилично. А для каких целей это делается?

Просто так. Unity понравилась, очень уютная среда. Хочу научиться делать в ней что-нибудь полезное.

Когда в мануале читал про частицы, в частности про World Particle Collider, подумалось, что он как-будто специально существует, чтобы устраивать пожары.

Zaicheg писал(а):
var targetFireController = (FireController) GetComponent("FireController");

Вы var используете потому что не знаете, какой тип получаете или из личных предпочтений? Просто очень непривычно (до недавнего времени у нас была не очень новая версия Mono).

Считаю, что в четвёртый раз повторять одно и то же название ― немного перебор.
Даже, если бы писал
var targetFireController = someObject.GetSomethingStrange();
всё равно бы не стал явно указывать тип. Стараюсь именовать переменные так, чтобы из названия было и так ясно, что в них хранится, а использование var к этому сильно мотивирует.

Zaicheg писал(а):Кстати, в Unity через C# более употребительной сейчас является конструкция GetComponent<FireController>(). В 2.6 ввели и там была какой-то прогон на тему того, что теперь надо так. Хотя может и путаю.

Даже не видел пока такую конструкцию. В официальном мануале раздел Reference довольно практичный, но совершенно без кода, а раздел Scripting сухой, как таблицы Брадиса. Хотелось бы для ознакомления почитать что-нибудь одновременно и жизненное, и с примерами кода.
alexz
UNITрон
 
Сообщения: 270
Зарегистрирован: 16 ноя 2010, 23:37

Re: Распространение огня

Сообщение GameWorld 17 фев 2011, 00:22

А у меня незагораються рядом стоящие предметы :(
Не могу скинуть скрин, не знаю как.
«Улучшение работающего продукта - приводит к его ухудшению.»
Аватара пользователя
GameWorld
Старожил
 
Сообщения: 620
Зарегистрирован: 11 янв 2011, 03:02
Skype: Alien3DModeller

Re: Распространение огня

Сообщение Graveier 17 фев 2011, 07:18

Может быть вы неправильно прописали что-либо?
Аватара пользователя
Graveier
UNIт
 
Сообщения: 149
Зарегистрирован: 08 ноя 2009, 20:25

Re: Распространение огня

Сообщение Syberex 03 мар 2011, 16:15

Супер! :ymapplause:
Аватара пользователя
Syberex
Адепт
 
Сообщения: 2292
Зарегистрирован: 14 янв 2011, 20:35
Откуда: Кострома
  • Сайт

Re: Распространение огня

Сообщение SmG 30 окт 2011, 00:56

Скрытый текст:
Сервер не найден







Firefox не может найти сервер www.autosim-utilities.ru.





Проверьте, не допущена ли ошибка при наборе адреса, например, ww.example.com вместо www.example.com
Если ни одна страница не загружается – проверьте настройки соединения с Интернетом.
Если компьютер или сеть защищены межсетевым экраном или прокси-сервером – убедитесь, что Firefox разрешён выход в Интернет.
Пожалуйста перезалейте куда-нибудь
Аватара пользователя
SmG
UNец
 
Сообщения: 19
Зарегистрирован: 15 окт 2011, 16:14
Откуда: Город Магадан
  • Сайт

Re: Распространение огня

Сообщение echo 17 фев 2012, 04:23

Спасибо! (3A4OT)
Аватара пользователя
echo
UNIт
 
Сообщения: 140
Зарегистрирован: 30 окт 2011, 17:27
Откуда: От верблюда
  • Сайт

Re: Распространение огня

Сообщение VBProgr 19 фев 2012, 17:35

Почему бы не делать так?
Синтаксис:
Используется csharp
FireController targetController = GetComponent<FireController>();


Веб сборка не грузится.
skype: vbprogr
Добавить vbprogr в Skype
VBProgr
UNITрон
 
Сообщения: 319
Зарегистрирован: 24 сен 2011, 14:11

Re: Распространение огня

Сообщение GameWorld 29 сен 2013, 13:58

У кого ни будь остался этот Ассет? Или можно предложить какой ни будь другой, главное что бы огонь мог распространяться и тухнуть.
«Улучшение работающего продукта - приводит к его ухудшению.»
Аватара пользователя
GameWorld
Старожил
 
Сообщения: 620
Зарегистрирован: 11 янв 2011, 03:02
Skype: Alien3DModeller

Re: Распространение огня

Сообщение seaman 30 сен 2013, 12:26

Скрипты есть - что еще надо?
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Распространение огня

Сообщение GameWorld 03 окт 2013, 08:39

seaman писал(а):Скрипты есть - что еще надо?

Надо префаб FireManager.
«Улучшение работающего продукта - приводит к его ухудшению.»
Аватара пользователя
GameWorld
Старожил
 
Сообщения: 620
Зарегистрирован: 11 янв 2011, 03:02
Skype: Alien3DModeller

Re: Распространение огня

Сообщение seaman 03 окт 2013, 19:33

Надо префаб FireManager.

Вы не умеете перетаскивать скрипты на объект?
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Распространение огня

Сообщение GameWorld 04 окт 2013, 05:46

seaman писал(а):
Надо префаб FireManager.

Вы не умеете перетаскивать скрипты на объект?

Огонь не переходит.
И выдаёт ошибку: "Igniting failed: burningDummyPrefab in FireManager have no MeshFilter component"
«Улучшение работающего продукта - приводит к его ухудшению.»
Аватара пользователя
GameWorld
Старожил
 
Сообщения: 620
Зарегистрирован: 11 янв 2011, 03:02
Skype: Alien3DModeller

След.

Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2