一、简单的爆炸
- 使用场景
零部件的简单爆炸展示 - 复杂爆炸,比如物体炸开后,破碎的物体沿曲线运动,而且有动力学效果,则需要更复杂的实现,本例不作讨论。
二、实现的过程
- 1、爆炸过程
从初始位置 移动到 结束位置(position和ratation做lerp插值运动) - 2、收拢过程
从结束位置 移动到 初始位置(position和ratation做lerp插值运动)
中间所有的物体都是在两点之间做匀速直线运动
- 3、爆炸前和爆炸后的方位信息记录
物体方位信息表 自定义的类-【物体和方位信息】
[Serializable]
public class goPositions{
[Header("物体")]
[SerializeField]
public GameObject go;
[Header("爆炸前的位置")]
[SerializeField]
public Vector3 positionStart;
[Header("爆炸前的方向")]
[SerializeField]
public Quaternion rotationStart;
[Header("爆炸后的位置")]
[SerializeField]
public Vector3 positionEnd;
[Header("爆炸后的方向")]
[SerializeField]
public Quaternion rotationEnd;
}
void Update()
{
stepValue = Mathf.PingPong(Time.time, time) / time;
GoPositions.ForEach(x =>
{
x.go.transform.position = Vector3.Lerp(x.positionStart, x.positionEnd, stepValue);
x.go.transform.rotation = Quaternion.Lerp(x.rotationStart, x.rotationEnd, stepValue);
});
}
三、代码清单
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
public class baozha : MonoBehaviour
{
[Serializable]
public class goPositions{
[Header("物体")]
[SerializeField]
public GameObject go;
[Header("爆炸前的位置")]
[SerializeField]
public Vector3 positionStart;
[Header("爆炸前的方向")]
[SerializeField]
public Quaternion rotationStart;
[Header("爆炸后的位置")]
[SerializeField]
public Vector3 positionEnd;
[Header("爆炸后的方向")]
[SerializeField]
public Quaternion rotationEnd;
}
[Header("部件的根物体")]
[SerializeField]
public GameObject root;
[Header("部件以及方位信息列表")]
[SerializeField]
public List<goPositions> GoPositions = new List<goPositions>();
[Header("散开的时间")]
[SerializeField]
public float time;
private float stepValue;
void Start()
{
}
void Update()
{
stepValue = Mathf.PingPong(Time.time, time) / time;
GoPositions.ForEach(x =>
{
x.go.transform.position = Vector3.Lerp(x.positionStart, x.positionEnd, stepValue);
x.go.transform.rotation = Quaternion.Lerp(x.rotationStart, x.rotationEnd, stepValue);
});
}
void SetToStartTransform()
{
GoPositions.ForEach(
x=>
{
x.go.transform.position = x.positionStart;
x.go.transform.rotation = x.rotationStart;
});
}
void SetToEndTransform()
{
GoPositions.ForEach(
x =>
{
x.go.transform.position = x.positionEnd;
x.go.transform.rotation = x.rotationEnd;
});
}
#if UNITY_EDITOR
[ContextMenu("记录【部件和开始方位】")]
#endif
public void InitTransformStart()
{
GoPositions.Clear();
root.transform.GetComponentInChildren<Transform>().Cast<Transform>().ToList()
.ForEach(item =>
{
if (item.name.Contains("部件"))
{
goPositions gp = new goPositions();
gp.go = item.gameObject;
gp.positionStart = item.gameObject.transform.position;
gp.rotationStart = item.gameObject.transform.rotation;
GoPositions.Add(gp);
}
else
{
}
});
Debug.Log("初始方位记录完毕");
}
#if UNITY_EDITOR
[ContextMenu("记录【结束方位】")]
#endif
public void InitTransformEnd()
{
var allGos = root.transform.GetComponentInChildren<Transform>().Cast<Transform>().ToList();
GoPositions.ForEach(x=>
{
x.positionEnd = allGos.Where(go => go.gameObject.name == x.go.name).ToList()[0].position;
x.rotationEnd = allGos.Where(go => go.gameObject.name == x.go.name).ToList()[0].rotation;
});
Debug.Log("结束方位记录完毕");
}
}
|