zoukankan      html  css  js  c++  java
  • 体素爆炸

    基本思路:
        离线把怪物死亡那帧的模型数据生成体素信息保存起来
        在死亡的时候,隐藏原本的模型,用体素数据生成体素
        低端机型用特效数据做爆炸,高端机型用真实物理
        体素数量可以在生成时调整(低画质之初20分之一的体素)

    结果:
        看不太出来是从模型样式开始爆炸的,最后使用了纯特效实现

    演示效果图

    体素生成代码使用地图体素信息导出工具临时改的,最终没有用这个方案就没有细化

    爆炸测试脚本记录
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Bomb : MonoBehaviour
    {
    	public bool autoBomb = false;
    	public int cullPower = 0;
    	public float showVoxelTime = 0.1f;
    	public GameObject modelObj;
    	public Transform voxelParent;
    	public ParticleSystem bombPs;
    	public bool usePhysics = false;
    	public float forcePower = 10;
    	public GameObject[] voxelObj;
    
    	float delTime;
    	float showTime;
    	float bombTime;
    	bool isShow;
    	bool isBomb;
    	bool isDoUsePhysics;
    	ParticleSystem.Particle[] m_Particles;
    	List<Vector3> oriPosition;
    
    	// Use this for initialization
    	void Awake()
    	{
    		if (autoBomb)
    		{
    			showTime = Time.time + 1;
    			bombTime = showTime + showVoxelTime;
    			isShow = false;
    			isBomb = false;
    			isDoUsePhysics = false;
    		}
    
    		voxelParent.gameObject.SetActive(false);
    		bombPs.gameObject.SetActive(false);
    
    		oriPosition = new List<Vector3>();
    
    		//剔除
    		if (cullPower > 1)
    		{
    			int nextCull = 0;
    			for (int i = voxelParent.childCount -1; i >= 0; --i)
    			{
    				if (nextCull != 0)
    				{
    					DestroyImmediate(voxelParent.GetChild(i).gameObject);
    				}
    				nextCull = (++nextCull) % cullPower;
    			}
    		}
    
    		//体素生成
    		if (voxelObj != null && voxelObj.Length > 0)
    		{
    			for (int i = 0; i < voxelParent.childCount; ++i)
    			{
    				Transform vox = voxelParent.GetChild(i);
    				GameObject randomVox = voxelObj[Random.Range(0, voxelObj.Length)];
    				GameObject voxObj = Instantiate(randomVox);
    				if (!usePhysics)
    				{
    					Destroy(voxObj.GetComponent<BoxCollider>());
    					Destroy(voxObj.GetComponent<Rigidbody>());
    				}
    
    				voxObj.transform.parent = vox;
    				voxObj.transform.localPosition = Vector3.zero;
    				voxObj.transform.localScale = Vector3.one;
    			}
    		}
    	}
    
    	// Update is called once per frame
    	void Update()
    	{
    		if (!autoBomb)
    			return;
    
    		if (!isShow)
    		{
    			if (Time.time >= showTime)
    			{
    				delTime = Time.time + 3;
    				isShow = true;
    				if (modelObj != null) modelObj.SetActive(false);
    				voxelParent.gameObject.SetActive(true);
    
    				for (int i = 0; i < voxelParent.childCount; ++i)
    				{
    					Transform vox = voxelParent.GetChild(i);
    					oriPosition.Add(vox.position);
    				}
    			}
    			else
    			{
    				return;
    			}
    		}
    
    		if (Time.time >= delTime)
    		{
    			Destroy(gameObject);
    		}
    
    		if (Time.time < bombTime)
    			return;
    
    		if (!isBomb)
    		{
    			isBomb = true;
    
    			short nVoxelCount = (short)voxelParent.childCount;
    			m_Particles = new ParticleSystem.Particle[nVoxelCount];
    			bombPs.emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0.0f, nVoxelCount, nVoxelCount) });
    			bombPs.gameObject.SetActive(true);
    			return;
    		}
    
    		if (!usePhysics)
    		{
    			Quaternion qua = bombPs.transform.rotation;
    			int numParticlesAlive = bombPs.GetParticles(m_Particles);
    			for (int i = 0; i < voxelParent.childCount; ++i)
    			{
    				if (i >= numParticlesAlive)
    					return;
    
    				Transform newTrans = voxelParent.GetChild(i);
    				newTrans.forward = qua * m_Particles[i].rotation3D;
    				newTrans.position = oriPosition[i] + qua * m_Particles[i].position;
    			}
    		}
    		else
    		{
    			if (!isDoUsePhysics)
    			{
    				isDoUsePhysics = true;
    				Quaternion qua = bombPs.transform.rotation;
    				int numParticlesAlive = bombPs.GetParticles(m_Particles);
    				for (int i = 0; i < voxelParent.childCount; ++i)
    				{
    					if (i >= numParticlesAlive)
    						return;
    
    					Vector3 force = qua * m_Particles[i].velocity;
    					force *= forcePower;
    
    					Transform newTrans = voxelParent.GetChild(i);
    					var rigi = newTrans.GetComponentInChildren<Rigidbody>();
    					rigi.AddForce(force);
    				}
    
    				bombPs.gameObject.SetActive(false);
    			}
    		}
    	}
    
    	[ContextMenu("DoBomb")]
    	public void DoBomb()
    	{
    		autoBomb = true;
    		showTime = Time.time;
    		bombTime = showTime + showVoxelTime;
    	}
    
    	[ContextMenu("DelAllRender")]
    	public void DelAllRender()
    	{
    		for (int i = 0; i < voxelParent.childCount; ++i)
    		{
    			GameObject obj = voxelParent.GetChild(i).gameObject;
    			DestroyImmediate(obj.GetComponent<MeshFilter>());
    			DestroyImmediate(obj.GetComponent<MeshRenderer>());
    		}
    	}
    }
    





  • 相关阅读:
    我是菜鸟,开始学习计划
    我是菜鸟,学习计划4月19日笔录
    用HttpSessionListener与HttpSessionBindingListener实现在线人数统计
    mac系统InetAddress.getLocalHost().getHostAddress() 很慢
    获取n位数m进制的随机数 js
    cordova开发环境搭建
    遇到网页中无法选择的文本时或需要登录才可复制时可用
    今天摸的鱼就是以后加的班
    国际化vuei18n 向语言包中传入参数
    vue3 技术浏览 收藏
  • 原文地址:https://www.cnblogs.com/Hichy/p/8033783.html
Copyright © 2011-2022 走看看