码迷,mamicode.com
首页 > 其他好文 > 详细

体素爆炸

时间:2017-12-13 20:05:50      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:margin   思路   ror   cal   initial   com   dex   back   code   

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





体素爆炸

标签:margin   思路   ror   cal   initial   com   dex   back   code   

原文地址:http://www.cnblogs.com/Hichy/p/8033783.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!