• Unity之Fire_HeavySmoke


    突然记起来去年领导让我做了个另一个项目中火的Demo。

    要求是:首先随着时间火可进行四周漫延。

        然后在燃烧到一定时间后最选燃烧的地方熄灭。

        最后是需要沿着地面燃烧的。

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
    public class FireSystem : MonoBehaviour
    {
        public float height = 10000;
        ///// <summary>
        ///// 初始火点位置
        ///// </summary>
        //public Vector3 position;
        ///// <summary>
        ///// 大小
        ///// </summary>
        //public float size;
        ///// <summary>
        ///// 火种
        ///// </summary>
        //public GameObject fire;
        ///// <summary>
        ///// 浓烟
        ///// </summary>
        //public GameObject smoke;
    
        //void Start()
        //{
        //    fire.particleSystem.emissionRate = 1f;
        //    var f1 = Fire.Create(this, Fire.FireLife.Recession);
        //    var f2 = Fire.Create(this, Fire.FireLife.Stable);
        //    var f3 = Fire.Create(this, Fire.FireLife.Grow);
        //    f2.transform.position = f1.transform.position + speed.normalized * size;//----当size改变,size不作为...
        //    f3.transform.position = f2.transform.position + speed.normalized * size;//----size作为目标大小(当size改变过大时模型异常)
    
        //    f1.transform.localScale = new Vector3(size, 1, size);
        //    f2.transform.localScale = new Vector3(size, 1, size);
        //    f3.transform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
        //    fire.SetActive(false);
        //}
        /// <summary>
        /// 扩散速度
        /// </summary>
        public Vector2 speed;
        public Vector2 size = new Vector2(16, 16);
        Vector2 _speed;
        Vector2 _size;
        float time;
    
        void Update()
        {
            if (time != 0)
            {
                if (_size == Vector2.zero)
                {
                    _size = size;
                }
                else if (_size != size || speed != _speed)
                {
                    //var s = (size + _size) / 2;
                    int i = 0;
                    foreach (Transform item in transform)
                    {
                        if (item.gameObject.activeSelf)
                        {
                            FireRegulateSize(item, speed, new Vector2(size.x / _size.x, size.y / _size.y), i);
                            i++;
                        }
                    }
                    _size = size;
                    _speed = speed;
                }
                
                transform.localRotation = Quaternion.AngleAxis(Vector2.Angle(new Vector2(0, 1), speed), Vector3.up);
                transform.position += new Vector3(speed.x, 0, speed.y) * (Time.time - time);
                foreach (Transform t in transform)
                {
                    FireNearFloor(height, t);
                }
            }
            time = Time.time;
        }
    
        private static void FireRegulateSize(Transform t, Vector3 speed, Vector2 scale, int i)
        {
            t.localScale = new Vector3(t.localScale.x * scale.x, t.localScale.y * scale.y, 1);
            t.localPosition = new Vector3(0, 0, t.localScale.y * i);
    
            var s = scale.x * scale.y;
    
            t.particleSystem.emissionRate = t.particleSystem.emissionRate * s;
            t.particleSystem.maxParticles = (int)(t.particleSystem.maxParticles * s);
            foreach (Transform item in t)
            {
                //if (item.name == "HeavySmoke")
                {
                    item.particleSystem.emissionRate = item.particleSystem.emissionRate * s;
                    item.particleSystem.maxParticles = (int)(item.particleSystem.maxParticles * s);
                }
            }
        }
    
        private static void FireNearFloor(float height, Transform t)
        {
            RaycastHit hit = default(RaycastHit);
    
            RaycastHit hitInfo1 = new RaycastHit();
            RaycastHit hitInfo2 = new RaycastHit();
    
            var b1 = Physics.Raycast(t.position, Vector3.up, out hitInfo1) || Physics.Raycast(t.position + Vector3.up * height, -Vector3.up, out hitInfo1);
            var b2 = Physics.Raycast(t.position, -Vector3.up, out hitInfo2) || Physics.Raycast(t.position - Vector3.up * height, Vector3.up, out hitInfo2);
    
            if (b1 && !b2)
                hit = hitInfo1;
            else if (!b1 && b2)
                hit = hitInfo2;
            else if (b1 && b2)
            {
                if ((hitInfo1.point - t.position).magnitude < (hitInfo2.point - t.position).magnitude)
                    hit = hitInfo1;
                else
                    hit = hitInfo2;
            }
    
            if (hit.transform != null)
            {
                t.position = hit.point;
                for (int i = 0; i < t.childCount; i++)
                {
                    if (t.GetChild(i).name == "glow")
                    {
                        t.GetChild(i).localRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
                        break;
                    }
                }
            }
        }
    }
      1 using UnityEngine;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using System.Linq;
      5 
      6 public class FireSystem : MonoBehaviour
      7 {
      8     public float height;
      9     ///// <summary>
     10     ///// 初始火点位置
     11     ///// </summary>
     12     //public Vector3 position;
     13     ///// <summary>
     14     ///// 大小
     15     ///// </summary>
     16     //public float size;
     17     ///// <summary>
     18     ///// 火种
     19     ///// </summary>
     20     //public GameObject fire;
     21     ///// <summary>
     22     ///// 浓烟
     23     ///// </summary>
     24     //public GameObject smoke;
     25 
     26     //void Start()
     27     //{
     28     //    fire.particleSystem.emissionRate = 1f;
     29     //    var f1 = Fire.Create(this, Fire.FireLife.Recession);
     30     //    var f2 = Fire.Create(this, Fire.FireLife.Stable);
     31     //    var f3 = Fire.Create(this, Fire.FireLife.Grow);
     32     //    f2.transform.position = f1.transform.position + speed.normalized * size;//----当size改变,size不作为...
     33     //    f3.transform.position = f2.transform.position + speed.normalized * size;//----size作为目标大小(当size改变过大时模型异常)
     34 
     35     //    f1.transform.localScale = new Vector3(size, 1, size);
     36     //    f2.transform.localScale = new Vector3(size, 1, size);
     37     //    f3.transform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
     38     //    fire.SetActive(false);
     39     //}
     40     /// <summary>
     41     /// 扩散速度
     42     /// </summary>
     43     public Vector3 speed;
     44     public Vector2 Size;
     45     Vector2 _size;
     46     float time;
     47 
     48     void Update()
     49     {
     50         if (time != 0)
     51         {
     52             if (_size != Size)
     53             {
     54                 int i = 0;
     55                 foreach (Transform item in transform)
     56                 {
     57                     if (item.gameObject.activeSelf)
     58                     {
     59                         FireRegulateSize(item, Size, i);
     60                         i++;
     61                     }
     62                 }
     63                 _size = Size;
     64             }
     65 
     66             transform.position += speed * (Time.time - time);
     67             foreach (Transform t in transform)
     68             {
     69                 FireNearFloor(height, t);
     70             }
     71         }
     72         time = Time.time;
     73     }
     74 
     75     private static void FireRegulateSize(Transform t, Vector2 size, int i)
     76     {
     77         t.localScale = new Vector3(size.x, size.y, 1);
     78         t.localPosition = new Vector3(0, -size.x * i * 4, 0);
     79         //foreach (Transform item in t)
     80         {
     81             //item.Translate(new Vector3(-size, 0,0)*Time.deltaTime);//虽平移但改变了原始速度
     82             t.particleSystem.emissionRate = t.particleSystem.emissionRate * Mathf.Sqrt(size.x * size.y);
     83             t.particleSystem.maxParticles = (int)(t.particleSystem.maxParticles * Mathf.Sqrt(size.x * size.y));
     84         }
     85     }
     86 
     87     private static void FireNearFloor(float height, Transform t)
     88     {
     89         RaycastHit hit = default(RaycastHit);
     90 
     91         RaycastHit hitInfo1 = new RaycastHit();
     92         RaycastHit hitInfo2 = new RaycastHit();
     93 
     94         var b1 = Physics.Raycast(t.position, Vector3.up, out hitInfo1) || Physics.Raycast(t.position + Vector3.up * height, -Vector3.up, out hitInfo1);
     95         var b2 = Physics.Raycast(t.position, -Vector3.up, out hitInfo2) || Physics.Raycast(t.position - Vector3.up * height, Vector3.up, out hitInfo2);
     96 
     97         if (b1 && !b2)
     98             hit = hitInfo1;
     99         else if (!b1 && b2)
    100             hit = hitInfo2;
    101         else if (b1 && b2)
    102         {
    103             if ((hitInfo1.point - t.position).magnitude < (hitInfo2.point - t.position).magnitude)
    104                 hit = hitInfo1;
    105             else
    106                 hit = hitInfo2;
    107         }
    108 
    109         if (hit.transform != null)
    110         {
    111             t.position = hit.point;
    112             for (int i = 0; i < t.childCount; i++)
    113             {
    114                 if (t.GetChild(i).name == "glow")
    115                 {
    116                     t.GetChild(i).localRotation = Quaternion.FromToRotation(new Vector3(0, 0, 1), hit.normal);
    117                     break;
    118                 }
    119             }
    120         }
    121     }
    122 }
  • 相关阅读:
    谈软件开发工具的选择
    Windows下搭建Octopress博客
    Aspose Word模版使用总结篇2带示例
    强大的二分查找法(Binary Search)
    GhostDoc Pro v4.5.13017专业破解版本
    超炫的开源 JavaScript 物理引擎
    CQRS + DDD + MDP 实现快速应用程序开发
    数据结构之栈(Stack)与队列(Queue)
    插件框架实现
    集成服务监控器green.monitor发布
  • 原文地址:https://www.cnblogs.com/cathytong/p/4699122.html
Copyright © 2020-2023  润新知