private void Start()
        {
            m_clothParticleObjects = GetComponentsInChildren <ClothParticleObject>();

            ClothParticleConstraints[] clothParticleConstraints = GetComponentsInChildren <ClothParticleConstraints>();
            ParticleClothSettings      particleSettings         = new ParticleClothSettings();

            ParticleData[]         particleDatas   = new ParticleData[m_clothParticleObjects.Length];
            Stack <ConstraintData> constraintDatas = new Stack <ConstraintData>();

            for (int i = 0; i < m_clothParticleObjects.Length; i++)
            {
                ClothParticleObject obj = m_clothParticleObjects[i];
                obj.Index        = i;
                particleDatas[i] = obj.ToParticleData();
            }

            for (int i = 0; i < clothParticleConstraints.Length; i++)
            {
                ClothParticleConstraints obj = clothParticleConstraints[i];

                int indexA = obj.GetComponent <ClothParticleObject>().Index;
                for (int j = 0; j < obj.OtherClothParticles.Length; j++)
                {
                    if (obj.ValidConnection(j))
                    {
                        ClothParticleObject other          = obj.OtherClothParticles[j];
                        ConstraintData      constraintData = new ConstraintData();
                        constraintData.ParticleAIndex = indexA;
                        constraintData.ParticleBIndex = other.Index;
                        constraintData.Length         = Vector3.Distance(obj.transform.position, other.transform.position);
                        constraintDatas.Push(constraintData);
                    }
                }
            }
            particleSettings.SetGravity(m_gravity.x, m_gravity.y, m_gravity.z);
            particleSettings.SetParticles(particleDatas, constraintDatas.ToArray());

            //gather collision Objects
            ICollisionIntegrator[] collisions       = GetComponentsInChildren <ICollisionIntegrator>();
            ICollisionObject[]     collisionObjects = new ICollisionObject[collisions.Length];
            for (int i = 0; i < collisions.Length; i++)
            {
                collisionObjects[i] = collisions[i].CollisionObject();
            }
            particleSettings.SetCollisions(collisionObjects);

            m_clothParticleSystem = new ClothParticleSystem(particleSettings);
        }
        private void OnGUI()
        {
            GUILayout.BeginHorizontal();
            m_sizeX = Mathf.Max(1, EditorGUILayout.IntField("Size X", m_sizeX));
            m_sizeY = Mathf.Max(1, EditorGUILayout.IntField("Size Y", m_sizeY));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            m_distance = Mathf.Max(0, EditorGUILayout.FloatField("Distance", Mathf.Max(m_distance, .01f)));
            GUILayout.EndHorizontal();

            if (GUILayout.Button("Create"))
            {
                ClothParticleObject[,] particleMapping = new ClothParticleObject[m_sizeX, m_sizeY];
                GameObject particlePhysicUpdater = new GameObject("ParticlePhysics");
                particlePhysicUpdater.AddComponent <ClothParticleSystemUpdater>();
                GameObject cloth = new GameObject("Cloth");
                cloth.transform.SetParent(particlePhysicUpdater.transform);
                for (int x = 0; x < m_sizeX; x++)
                {
                    for (int y = 0; y < m_sizeY; y++)
                    {
                        GameObject g = new GameObject(string.Format("P {0} {1}", x, y));
                        g.transform.localPosition = new Vector3(x * m_distance, y * -m_distance);
                        g.transform.SetParent(cloth.transform);

                        ClothParticleObject p = g.AddComponent <ClothParticleObject>();
                        p.Kinematic = y == 0;
                        p.Mass      = 1 - (float)(y * y) / (m_sizeY * m_sizeY);

                        particleMapping[x, y] = p;
                    }
                }
                //hooked the joints
                for (int x = 0; x < m_sizeX; x++)
                {
                    for (int y = 0; y < m_sizeY; y++)
                    {
                        ClothParticleObject p = particleMapping[x, y];

                        Stack <ClothParticleObject> neighbours = new Stack <ClothParticleObject>();
                        //right
                        int rightIndex = x + 1;
                        if (rightIndex < m_sizeX)
                        {
                            neighbours.Push(particleMapping[rightIndex, y]);
                        }
                        //Bottom
                        int bottomIndex = y + 1;
                        if (bottomIndex < m_sizeY)
                        {
                            neighbours.Push(particleMapping[x, bottomIndex]);
                        }
                        //diagonal right
                        if (rightIndex < m_sizeX && bottomIndex < m_sizeY)
                        {
                            neighbours.Push(particleMapping[rightIndex, bottomIndex]);
                        }
                        //diagonal left
                        int leftIndex = x - 1;
                        if (leftIndex >= 0 && bottomIndex < m_sizeY)
                        {
                            neighbours.Push(particleMapping[leftIndex, bottomIndex]);
                        }

                        ClothParticleConstraints c = p.gameObject.AddComponent <ClothParticleConstraints>();
                        c.OtherClothParticles = neighbours.ToArray();
                    }
                }
            }
        }