|
推荐阅读
CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客QQ群:1040082875
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新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;publicclassSplitTest:MonoBehaviour{privateTransform m_ParObj;//中心点private List<GameObject> m_Child;//所有子对象private List<Vector3> m_InitPoint =newList<Vector3>();//初始位置privateint m_IsSplitState =0;privatefloat m_TimeTotal =0;//总时间privatefloat m_Timecurrent =0;//当前时间privateint m_TimeDisRe =0;//时间间隔 记录privateint IndexCount =0;//计数publicint m_TimeDistance =1;//时间间隔voidStart(){
- 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 =newList<GameObject>();foreach(Transform child in obj){
- tempArrayobj.Add(child.gameObject);}return tempArrayobj;}voidUpdate(){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();}elseif(m_IsSplitState ==2){//合并MergeObject();}}privatevoidSplitObject(){
- 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++;}}}privatevoidMergeObject(){
- 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++;}}}publicVector3SplitObjTest(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;publicclassSplitCube:MonoBehaviour{privateTransform m_ParObj;//中心点private List<GameObject> m_Child;//所有子对象private List<Vector3> m_InitPoint =newList<Vector3>();//初始位置privatevoidStart(){
- 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 =newList<GameObject>();foreach(Transform child in obj){
- tempArrayobj.Add(child.gameObject);}return tempArrayobj;}privatevoidUpdate(){if(Input.GetKeyDown(KeyCode.W)){//拆分SplitObject();}if(Input.GetKeyDown(KeyCode.S)){//合并MergeObject();}}privatevoidSplitObject(){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);}}privatevoidMergeObject(){for(int i =0; i < m_InitPoint.Count; i++){
- m_Child[i].transform.DOMove(m_InitPoint[i],3f,false);}}publicVector3SplitObjTest(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;publicclassSplitAnomaly:MonoBehaviour{publicTransform m_ChildPointParent;//要移动的子对象的父物体private List<GameObject> m_Child;//所有子对象private List<Vector3> m_InitPoint =newList<Vector3>();//初始位置publicTransform m_TargetPointParent;//目标点对象的父物体private List<GameObject> m_TargetChild;//目标点所有子对象private List<Vector3> m_TargetPoint =newList<Vector3>();//要移动的位置privatevoidStart(){
- 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 =newList<GameObject>();foreach(Transform child in obj){
- tempArrayobj.Add(child.gameObject);}return tempArrayobj;}privatevoidUpdate(){if(Input.GetKeyDown(KeyCode.W)){//拆分SplitObject();}if(Input.GetKeyDown(KeyCode.S)){//合并MergeObject();}}privatevoidSplitObject(){for(int i =0; i < m_Child.Count; i++){
- m_Child[i].transform.DOMove(m_TargetPoint[i],3f,false);}}privatevoidMergeObject(){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和坑,让后来人可以有些参考。 |
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|