Recommended reading

  • CSDN home page
  • GitHub open source address
  • Unity3D plugin sharing
  • Jane’s address book
  • My personal blog
  • QQ group: 1040082875

One, foreword

In the simulation development, will encounter the model to move, enlarge, rotate, split, merge and other operations, other move, enlarge, rotate have more examples for reference, today to share how to split the object

Second, implementation ideas

There are a lot of ideas to achieve this, such as: 1, first split the model, and then record the coordinates of the object, and then split the object to move to the coordinates of the object

2, set a center point, and then other objects to this center point in the opposite direction of the additional force, so that there is a kind of bouncing effect

3. Add physics effects, such as adding collision boxes to all objects, and then separating them

4, with the object normal to add force around, so that the object discrete

5, set a center point, other objects to this center point as the target point, calculate the distance from this center point, and then multiply this distance by 2, is the new position of the object

Three, implementation,

Let’s go with the fifth idea. You set a center point, the other objects take this center point as the target point, calculate the distance from this center point, and then multiply this distance by 2, which is the new position of the object.

1, first set a center point, this center point should be the center of all objects, so that other objects can be evenly split

using System.Collections.Generic;
using UnityEngine;

public class SplitTest : MonoBehaviour
{
    public Transform m_ParObj;/ / center
}

Copy the code

2. Get all child objects

using System.Collections.Generic;
using UnityEngine;

public class SplitTest : MonoBehaviour
{
    public Transform m_ParObj;/ / center

    private void Start()
    {
        List<GameObject> m_Child = m_ParObj.GetChild();// Get all child objects}}Copy the code

Since Unity doesn’t have a function to retrieve all child objects directly, we use an extension method to retrieve all child objects:

using System.Collections.Generic;
using UnityEngine;

public static class MyExtensions
{
    public static List<GameObject> GetChild(this Transform obj)
    {
        List<GameObject> tempArrayobj = new List<GameObject>();
        foreach (Transform child in obj)
        {
            tempArrayobj.Add(child.gameObject);
        }
        returntempArrayobj; }}Copy the code

Calculate the distance from the child object and the center point, and multiply the distance by 2:

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;
}
Copy the code

4, Pass all the children into this function one by one, get the target position, then set the children to move to the target position:

using System.Collections.Generic;
using UnityEngine;

public class SplitTest : MonoBehaviour
{
    public Transform m_ParObj;/ / center

    private void Start()
    {
        List<GameObject> m_Child = m_ParObj.GetChild();// Get all child objects
        for (int i = 0; i < m_Child.Count; i++) { Vector3 tempV3 = SplitObjTest(m_ParObj, m_Child[i].transform); m_Child[i].transform.position = tempV3; }}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;
        returntempV3; }}Copy the code

5. Assign the parent object to the ParObj slot:

6. Effect Display: Initial:Up and running:7. If you want to add the animation decomposition effect, you can use DoTween:

using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class SplitTest : MonoBehaviour
{
    public Transform m_ParObj;/ / center

    private void Start()
    {
        List<GameObject> m_Child = m_ParObj.GetChild();// Get all child objects
        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); }}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;
        returntempV3; }}Copy the code

Four, afterword.

According to the opinions of my friends, I modified the code and added the functions of splitting and merging.

Put the source project into the CSDN as well

Because the model involved in the tutorial is confidential, the model in the source project is replaced by Cube, but the effect is the same, as shown below:

Modified code:

using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;

public class SplitTest : MonoBehaviour
{
    public Transform m_ParObj;/ / center
    private List<GameObject> m_Child;// All child objects
    private List<Vector3> m_InitPoint=new List<Vector3>();// The initial position

    private void Start()
    {
        m_Child = m_ParObj.GetChild();// Get all child objects
        for (int i = 0; i < m_Child.Count; i++) { m_InitPoint.Add(m_Child[i].transform.position); }}private void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            / / split
            SplitObject();
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            / / mergeMergeObject(); }}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;
        returntempV3; }}Copy the code

The source project:

wwr.lanzoui.com/iBiQ4qsz9sb