体素爆炸

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

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

演示效果图
1146702-20171213165850629-1903724974.gif
1146702-20171213165856144-263508549.gif

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

爆炸测试脚本记录
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>());
		}
	}
}
x
182
 
1
using System.Collections;
2
using System.Collections.Generic;
3
using UnityEngine;
4
 
          
5
public class Bomb : MonoBehaviour
6
{
7
    public bool autoBomb = false;
8
    public int cullPower = 0;
9
    public float showVoxelTime = 0.1f;
10
    public GameObject modelObj;
11
    public Transform voxelParent;
12
    public ParticleSystem bombPs;
13
    public bool usePhysics = false;
14
    public float forcePower = 10;
15
    public GameObject[] voxelObj;
16
 
          
17
    float delTime;
18
    float showTime;
19
    float bombTime;
20
    bool isShow;
21
    bool isBomb;
22
    bool isDoUsePhysics;
23
    ParticleSystem.Particle[] m_Particles;
24
    List<Vector3> oriPosition;
25
 
          
26
    // Use this for initialization
27
    void Awake()
28
    {
29
        if (autoBomb)
30
        {
31
            showTime = Time.time + 1;
32
            bombTime = showTime + showVoxelTime;
33
            isShow = false;
34
            isBomb = false;
35
            isDoUsePhysics = false;
36
        }
37
 
          
38
        voxelParent.gameObject.SetActive(false);
39
        bombPs.gameObject.SetActive(false);
40
 
          
41
        oriPosition = new List<Vector3>();
42
 
          
43
        //剔除
44
        if (cullPower > 1)
45
        {
46
            int nextCull = 0;
47
            for (int i = voxelParent.childCount -1; i >= 0; --i)
48
            {
49
                if (nextCull != 0)
50
                {
51
                    DestroyImmediate(voxelParent.GetChild(i).gameObject);
52
                }
53
                nextCull = (++nextCull) % cullPower;
54
            }
55
        }
56
 
          
57
        //体素生成
58
        if (voxelObj != null && voxelObj.Length > 0)
59
        {
60
            for (int i = 0; i < voxelParent.childCount; ++i)
61
            {
62
                Transform vox = voxelParent.GetChild(i);
63
                GameObject randomVox = voxelObj[Random.Range(0, voxelObj.Length)];
64
                GameObject voxObj = Instantiate(randomVox);
65
                if (!usePhysics)
66
                {
67
                    Destroy(voxObj.GetComponent<BoxCollider>());
68
                    Destroy(voxObj.GetComponent<Rigidbody>());
69
                }
70
 
          
71
                voxObj.transform.parent = vox;
72
                voxObj.transform.localPosition = Vector3.zero;
73
                voxObj.transform.localScale = Vector3.one;
74
            }
75
        }
76
    }
77
 
          
78
    // Update is called once per frame
79
    void Update()
80
    {
81
        if (!autoBomb)
82
            return;
83
 
          
84
        if (!isShow)
85
        {
86
            if (Time.time >= showTime)
87
            {
88
                delTime = Time.time + 3;
89
                isShow = true;
90
                if (modelObj != null) modelObj.SetActive(false);
91
                voxelParent.gameObject.SetActive(true);
92
 
          
93
                for (int i = 0; i < voxelParent.childCount; ++i)
94
                {
95
                    Transform vox = voxelParent.GetChild(i);
96
                    oriPosition.Add(vox.position);
97
                }
98
            }
99
            else
100
            {
101
                return;
102
            }
103
        }
104
 
          
105
        if (Time.time >= delTime)
106
        {
107
            Destroy(gameObject);
108
        }
109
 
          
110
        if (Time.time < bombTime)
111
            return;
112
 
          
113
        if (!isBomb)
114
        {
115
            isBomb = true;
116
 
          
117
            short nVoxelCount = (short)voxelParent.childCount;
118
            m_Particles = new ParticleSystem.Particle[nVoxelCount];
119
            bombPs.emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0.0f, nVoxelCount, nVoxelCount) });
120
            bombPs.gameObject.SetActive(true);
121
            return;
122
        }
123
 
          
124
        if (!usePhysics)
125
        {
126
            Quaternion qua = bombPs.transform.rotation;
127
            int numParticlesAlive = bombPs.GetParticles(m_Particles);
128
            for (int i = 0; i < voxelParent.childCount; ++i)
129
            {
130
                if (i >= numParticlesAlive)
131
                    return;
132
 
          
133
                Transform newTrans = voxelParent.GetChild(i);
134
                newTrans.forward = qua * m_Particles[i].rotation3D;
135
                newTrans.position = oriPosition[i] + qua * m_Particles[i].position;
136
            }
137
        }
138
        else
139
        {
140
            if (!isDoUsePhysics)
141
            {
142
                isDoUsePhysics = true;
143
                Quaternion qua = bombPs.transform.rotation;
144
                int numParticlesAlive = bombPs.GetParticles(m_Particles);
145
                for (int i = 0; i < voxelParent.childCount; ++i)
146
                {
147
                    if (i >= numParticlesAlive)
148
                        return;
149
 
          
150
                    Vector3 force = qua * m_Particles[i].velocity;
151
                    force *= forcePower;
152
 
          
153
                    Transform newTrans = voxelParent.GetChild(i);
154
                    var rigi = newTrans.GetComponentInChildren<Rigidbody>();
155
                    rigi.AddForce(force);
156
                }
157
 
          
158
                bombPs.gameObject.SetActive(false);
159
            }
160
        }
161
    }
162
 
          
163
    [ContextMenu("DoBomb")]
164
    public void DoBomb()
165
    {
166
        autoBomb = true;
167
        showTime = Time.time;
168
        bombTime = showTime + showVoxelTime;
169
    }
170
 
          
171
    [ContextMenu("DelAllRender")]
172
    public void DelAllRender()
173
    {
174
        for (int i = 0; i < voxelParent.childCount; ++i)
175
        {
176
            GameObject obj = voxelParent.GetChild(i).gameObject;
177
            DestroyImmediate(obj.GetComponent<MeshFilter>());
178
            DestroyImmediate(obj.GetComponent<MeshRenderer>());
179
        }
180
    }
181
}
182
 
          





转载于:https://www.cnblogs.com/Hichy/p/8033783.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值