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 }

 

posted @ 2015-08-03 13:44  TTT童童童  阅读(539)  评论(0编辑  收藏  举报