虚拟仿真Unity3D中拆分模型教程(多种类型模型拆分)
Posted 恬静的小魔龙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟仿真Unity3D中拆分模型教程(多种类型模型拆分)相关的知识,希望对你有一定的参考价值。
推荐阅读
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
今天有小伙伴在我这篇文章【虚拟仿真】Unity3D对物体进行拆分实现下面问我如何一秒一拆:
虽然我已经给出了思路,但是离实现还是有点思路,正好我对于我这篇文章也是不满意,就解答一下小伙伴的疑惑,然后再将文章内容进行升级。
原文章:【虚拟仿真】Unity3D对物体进行拆分实现 的思路是获取子物体跟父物体之间的距离,然后拆分的时候让子物体移动到跟父物体距离的两倍的位置上,这种方法只能拆分完全对称镜像
的模型,比如这样的:
但是,其他类型的,奇奇怪怪的模型估计就不那么好用了,所以本篇文章升级了一下,可以拆分更多模型,快来看看吧。
二、实现一秒一拆
首先,解决小伙伴一秒一拆代码的实现。本小节根据【虚拟仿真】Unity3D对物体进行拆分实现这篇文章基础上进行实现。
新建个项目,模板选3D,我用的是Unity3D版本是Unity 2019.4.7f1
:
搭建场景,简简单单搭一个十字模型:
将DoTween插件导入:
新建脚本SplitTest.cs
,双击打开脚本,修改代码:
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SplitTest : MonoBehaviour
private Transform m_ParObj;//中心点
private List<GameObject> m_Child;//所有子对象
private List<Vector3> m_InitPoint = new List<Vector3>();//初始位置
private int m_IsSplitState = 0;
private float m_TimeTotal = 0;//总时间
private float m_Timecurrent = 0;//当前时间
private int m_TimeDisRe = 0;//时间间隔 记录
private int IndexCount = 0;//计数
public int m_TimeDistance = 1;//时间间隔
void Start()
m_ParObj = GetComponent<Transform>();
m_Child = GetChild(m_ParObj);
for (int i = 0; i < m_Child.Count; i++)
m_InitPoint.Add(m_Child[i].transform.position);
m_TimeTotal = m_Child.Count* m_TimeDistance;
//获取所有子对象
public List<GameObject> GetChild(Transform obj)
List<GameObject> tempArrayobj = new List<GameObject>();
foreach (Transform child in obj)
tempArrayobj.Add(child.gameObject);
return tempArrayobj;
void Update()
if (Input.GetKeyDown(KeyCode.W))
m_Timecurrent = 0;
m_TimeDisRe = 0;
IndexCount = 0;
m_IsSplitState = 1;
if (Input.GetKeyDown(KeyCode.S))
m_Timecurrent = 0;
m_TimeDisRe = 0;
IndexCount = 0;
m_IsSplitState = 2;
if (m_IsSplitState == 1)
//拆分
SplitObject();
else if(m_IsSplitState == 2)
//合并
MergeObject();
private void SplitObject()
m_Timecurrent += Time.deltaTime;
if (m_Timecurrent <= m_TimeTotal && IndexCount< m_Child.Count)
if (Mathf.FloorToInt(m_Timecurrent) == m_TimeDisRe)
m_TimeDisRe += m_TimeDistance;
Vector3 tempV3 = SplitObjTest(m_ParObj.transform, m_Child[IndexCount].transform);
m_Child[IndexCount].transform.DOMove(tempV3, 1f, false);
IndexCount++;
private void MergeObject()
m_Timecurrent += Time.deltaTime;
if (m_Timecurrent <= m_TimeTotal && IndexCount < m_Child.Count)
if (Mathf.FloorToInt(m_Timecurrent) == m_TimeDisRe)
m_TimeDisRe += m_TimeDistance;
m_Child[IndexCount].transform.DOMove(m_InitPoint[IndexCount], 3f, false);
IndexCount++;
public Vector3 SplitObjTest(Transform m_ParObj, Transform _TargetObj)
Vector3 tempV3;
tempV3.x = (_TargetObj.position.x - m_ParObj.position.x) * 2;
tempV3.y = (_TargetObj.position.y - m_ParObj.position.y) * 2;
tempV3.z = (_TargetObj.position.z - m_ParObj.position.z) * 2;
return tempV3;
效果图:
三、对称型模型拆分
模型样例:
这种规则的,对称的,镜像的,正方形的,都可以使用下面的代码。
新建脚本SplitCube.cs,修改代码:
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SplitCube : MonoBehaviour
private Transform m_ParObj;//中心点
private List<GameObject> m_Child;//所有子对象
private List<Vector3> m_InitPoint = new List<Vector3>();//初始位置
private void Start()
m_ParObj = transform;
m_Child = GetChild(m_ParObj);//获取所有子对象
for (int i = 0; i < m_Child.Count; i++)
m_InitPoint.Add(m_Child[i].transform.position);
//获取所有子对象
public List<GameObject> GetChild(Transform obj)
List<GameObject> tempArrayobj = new List<GameObject>();
foreach (Transform child in obj)
tempArrayobj.Add(child.gameObject);
return tempArrayobj;
private void Update()
if (Input.GetKeyDown(KeyCode.W))
//拆分
SplitObject();
if (Input.GetKeyDown(KeyCode.S))
//合并
MergeObject();
private void SplitObject()
for (int i = 0; i < m_Child.Count; i++)
Vector3 tempV3 = SplitObjTest(m_ParObj, m_Child[i].transform);
m_Child[i].transform.DOMove(tempV3, 3f, false);
private void MergeObject()
for (int i = 0; i < m_InitPoint.Count; i++)
m_Child[i].transform.DOMove(m_InitPoint[i], 3f, false);
public Vector3 SplitObjTest(Transform m_ParObj, Transform _TargetObj)
Vector3 tempV3;
tempV3.x = (_TargetObj.position.x - m_ParObj.position.x) * 2;
tempV3.y = (_TargetObj.position.y - m_ParObj.position.y) * 2;
tempV3.z = (_TargetObj.position.z - m_ParObj.position.z) * 2;
return tempV3;
效果图:
四、不规则形状模型拆分
搭建一个不规则的模型:
如果还用原来的代码就会有些问题:
那么就可以使用预先拆分法来拆分模型。
先把原模型复制一份出来,然后将零件移动到想要的位置上:
新建脚本SplitAnomaly.cs,修改脚本:
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SplitAnomaly : MonoBehaviour
public Transform m_ChildPointParent;//要移动的子对象的父物体
private List<GameObject> m_Child;//所有子对象
private List<Vector3> m_InitPoint = new List<Vector3>();//初始位置
public Transform m_TargetPointParent;//目标点对象的父物体
private List<GameObject> m_TargetChild;//目标点所有子对象
private List<Vector3> m_TargetPoint = new List<Vector3>();//要移动的位置
private void Start()
m_Child = GetChild(transform);//获取所有子对象
for (int i = 0; i < m_Child.Count; i++)
m_InitPoint.Add(m_Child[i].transform.position);
m_TargetChild = GetChild(m_TargetPointParent);//获取所有目标点子对象
for (int i = 0; i < m_TargetChild.Count; i++)
m_TargetPoint.Add(m_TargetChild[i].transform.position);
//获取所有子对象
public List<GameObject> GetChild(Transform obj)
List<GameObject> tempArrayobj = new List<GameObject>();
foreach (Transform child in obj)
tempArrayobj.Add(child.gameObject);
return tempArrayobj;
private void Update()
if (Input.GetKeyDown(KeyCode.W))
//拆分
SplitObject();
if (Input.GetKeyDown(KeyCode.S))
//合并
MergeObject();
private void SplitObject()
for (int i = 0; i < m_Child.Count; i++)
m_Child[i].transform.DOMove(m_TargetPoint[i], 3f, false);
private void MergeObject()
for (int i = 0; i < m_InitPoint.Count; i++)
m_Child[i].transform.DOMove(m_InitPoint[i], 3f, false);
给任意对象添加上SplitAnomaly 脚本组件,将对象对象拖入卡槽中:
效果图:
五、总结
再来总结一下实现的思路,首先获取到子对象到父对象的距离,将这个距离乘以2,然后将子对象移动到这个位置就实现了拆分。
但是,这在面对复杂模型的时候就不太好用了,这时候就可以使用第二种,不规则形状模型的拆分方法,也就是预拆法,先拆好,然后将子对象移动到要拆分的位置就可以了。
最后:
本篇文章的代码都是博主思考一遍遍调试修改来的,付出了不少心血。
如果这篇文章对你有帮助,受累一键三连。
博主还有跟多宝藏文章等待你的发掘哦:
专栏 | 方向 | 简介 |
---|---|---|
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |
以上是关于虚拟仿真Unity3D中拆分模型教程(多种类型模型拆分)的主要内容,如果未能解决你的问题,请参考以下文章