- 使用场景
零部件的简单爆炸展示 - 复杂爆炸,比如物体炸开后,破碎的物体沿曲线运动,而且有动力学效果,则需要更复杂的实现,本例不作讨论。
- 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; }
- 4、爆炸的过程——插值或者pingpong
// Update is called once per frame
void Update()
{
//测试代码==================================begin
//if (Input.GetKeyDown(KeyCode.Alpha1))
//{
// Debug.Log("111");
// SetToStartTransform();
//}
//if (Input.GetKeyDown(KeyCode.Alpha2))
//{
// Debug.Log("222");
// SetToEndTransform();
//}
//测试代码==================================end
//更新物体的位置和方向——pingpong效果
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; ////// 一个组合的物体爆炸和收拢 /// 爆炸:从初始位置 移动到 结束位置(position和ratation做lerp插值运动) /// 收拢:从结束位置 移动到 初始位置(position和ratation做lerp插值运动) /// /// 编辑器状态下的功能: /// 没有爆炸前: 右键菜单《初始化【部件和开始方位】》,记录各个部件的原始方向和位置 /// 拖拽爆炸位置后:右键菜单《初始化【结束方位】》 ,记录各个部件的结束方向和位置 /// /// 说明:物体命名规则,凡是爆炸的物体(要炸开和合拢的物体),命名包含"部件"两字 /// 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 ListGoPositions = new List (); [Header("散开的时间")] [SerializeField] public float time; /// /// pingpong效果的进度条值 /// private float stepValue; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { //测试代码==================================begin //if (Input.GetKeyDown(KeyCode.Alpha1)) //{ // Debug.Log("111"); // SetToStartTransform(); //} //if (Input.GetKeyDown(KeyCode.Alpha2)) //{ // Debug.Log("222"); // SetToEndTransform(); //} //测试代码==================================end //更新物体的位置和方向——pingpong效果 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 // Editor的非running状态使用 [ContextMenu("记录【部件和开始方位】")] #endif public void InitTransformStart() { GoPositions.Clear(); root.transform.GetComponentInChildren().Cast ().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 // Editor的非running状态使用 [ContextMenu("记录【结束方位】")] #endif public void InitTransformEnd() { var allGos = root.transform.GetComponentInChildren ().Cast ().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("结束方位记录完毕"); } }



