Unity实战——简易炉火

Unity实战——简易炉火

这一次感受了unity的粒子系统,并设计了一个简单的炉火,通过代码控制不同情况下炉火的外形。

最终效果

简易火炉



项目源码


制作火焰

  1. 创建空对象,命名为 file,添加组件Particle System

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-在这里插入图片描述



  1. 修改 Emission 属性中的 Rate over Time,让系统在同一时间释放更多粒子
    在这里插入图片描述



  1. Shape 属性中修改形状为 Box,修改x方向的 Rotation-90,使粒子向上飘

    在这里插入图片描述



  1. 为了让粒子系统更有火焰的形状,勾选 Size over LifeTime 属性,编辑波形,使其更接近火焰的形状

    在这里插入图片描述

在这里插入图片描述



  1. 为了让颜色更接近火焰,勾选 Color over LifeTime,调整颜色

在这里插入图片描述

在这里插入图片描述



  1. 调整基本的参数,让视觉效果更好

    在这里插入图片描述



  1. Fire 拖到 Assets 中作为预制




脚本编写

从两个方面区分小火、中火和大火

  • 火苗数量
  • 火苗大小、形状

根据上述标准编写脚本调整火焰



本次脚本的结构较简单,是经典的mvc结构的简化

FirstController.cs:程序的主控制器,负责加载资源、控制和回收火焰

以下对脚本中的方法进行介绍

Start: 加载资源,对数据初始化

void Start()
{
    fireList = new List<GameObject>();
    userGUI = gameObject.AddComponent<UserGUI>();
    status = userGUI.GetStatus();
}


Update: 监听 status 属性,并调用响应函数控制火焰的变化

void Update()
{
    int oldStatus = status;
    status = userGUI.GetStatus();

    if(oldStatus != status){
        if(oldStatus > 0 && status == 0){
            OffFire();
        }
        else{
            if(status == 1){
                SmallFire();
            }
            if(status == 2){
                MiddleFire();
            }
            if(status == 3){
                LargeFire();
            }
        }
    }
}


SmallFire, MiddleFire, LargeFire: 加载并调整粒子系统的属性

小火一共加载5个火苗,中火7个,大火9个。对应的scale,rateOverTime,startLifetime也通过代码修改,作为区分

public void SmallFire(){
    DestroyFire();
    for(int i = 0; i < 5; i++){
        fire = Instantiate(Resources.Load("Prefabs/Fire"), 
        					new Vector3(small_pos[i], 0f, z), 
        					Quaternion.identity) 
        	   as GameObject;
        fireList.Add(fire);
        ParticleSystem ps = fire.GetComponent<ParticleSystem>();
        var sh = ps.shape;
        sh.radius = 0.69f;
        sh.scale = new Vector3(0.1f, 0.1f, 0);

        var em = ps.emission;
        em.rateOverTime = 300f;
    }
}

public void MiddleFire(){
    DestroyFire();
    for(int i = 0; i < 7; i++){
        fire = Instantiate(Resources.Load("Prefabs/Fire"), 
        					new Vector3(middle_pos[i], 0f, z), 
        					Quaternion.identity) 
        	   as GameObject;
        fireList.Add(fire);
        ParticleSystem ps = fire.GetComponent<ParticleSystem>();
        var sh = ps.shape;
        sh.radius = 0.69f;
        sh.scale = new Vector3(0.5f, 0.5f, 0);

        var em = ps.emission;
        em.rateOverTime = 500f;
    }
}

public void LargeFire(){
    DestroyFire();
    for(int i = 0; i < 9; i++){
        fire = Instantiate(Resources.Load("Prefabs/Fire"), 
        					new Vector3(large_pos[i], 0f, z), 
        					Quaternion.identity) 
        	   as GameObject;
        fireList.Add(fire);
        ParticleSystem ps = fire.GetComponent<ParticleSystem>();
        var sh = ps.shape;
        sh.radius = 0.69f;
        sh.scale = new Vector3(1f, 1f, 0);

        var em = ps.emission;
        em.rateOverTime = 700f;

        var main = ps.main;
        main.startLifetime = 1.8f;
    }
}


OffFire: 熄灭火苗,方法是将粒子系统的loop属性改为False

public void OffFire(){
    foreach(GameObject fire in fireList){
        ParticleSystem ps = fire.GetComponent<ParticleSystem>();
        var main = ps.main;
        main.loop = false;
    }
}


DestroyFire: 销毁列表中的火苗

public void DestroyFire(){
    foreach(GameObject fire in fireList){
    	fire.SetActive(false);
    }
    fireList.Clear();
}

UserGUI.cs: 用户的主界面

public class UserGUI : MonoBehaviour
{
    private FirstController firstController;
    GUIStyle textStyle;
    GUIStyle topicStyle;
    int status;
    // Start is called before the first frame update
    void Start()
    {
        SetStyle();
        status = 0;
    }

    // Update is called once per frame
    void Update()
    {
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");
    }

    void SetStyle(){
        textStyle = new GUIStyle();
        textStyle.normal.textColor = Color.black;
        textStyle.fontSize = 30;

        topicStyle = new GUIStyle();
        topicStyle.normal.textColor = Color.black;
        topicStyle.fontSize = 60;
    }


    void OnGUI(){
        if (GUI.Button(new Rect(Screen.width/2 - 300, Screen.width/2 - 300, 60, 50), "熄灭"))
        {
            status = 0;
        }

        if (GUI.Button(new Rect(Screen.width/2 - 300, Screen.width/2 - 240, 60, 50), "小火"))
        {
            status = 1;
        }

        if (GUI.Button(new Rect(Screen.width/2 - 300, Screen.width/2 - 180, 60, 50), "中火"))
        {
            status = 2;
        }

        if (GUI.Button(new Rect(Screen.width/2 - 300, Screen.width/2 - 120, 60, 50), "大火"))
        {
            status = 3;
        }
    }

    public int GetStatus(){
        return status;
    }
}

参考资源
博客
Unity手册–粒子系统

猜你喜欢

转载自blog.csdn.net/weixin_51930942/article/details/128632675