예제 #1
0
        public static void RotatePivot(GameObject forObject, Quaternion newRotation, bool preserveState)
        {
            RecognizeObject(forObject);

            if (!CheckObject(forObject))
            {
                return;
            }


            // Transform.TransformPoint and InversetransformPoint have high performance implications


            if (preserveState)
            {
                var collRecognize   = forObject.GetComponentsInChildren <CollRecognize>();
                var navObsRecognize = forObject.GetComponentsInChildren <NavObsRecognize>();


                if (collRecognize == null || collRecognize.Length == 0)
                {
                    GameObject childColl = UtilityServices.CreateChildCollider(forObject, false, null, newRotation);
                    if (childColl)
                    {
                        Debug.Log(string.Format("<b><i><color=#0080ffff>The Collider(s) on \"{0}\" has been disabled.Due to pivot modification colliders get incorrectly oriented.To preserve the same collider orientation as the one before pivot modification, the original collider has been added to a child GameObject \"{1}\" use that as the collider for this GameObject. Please don't delete this child object otherwise any subsequent changes made to modify pivot cannot guarantee correct collider orientation. </color></i></b>", forObject.name, childColl.name));
                    }
                }


                if (navObsRecognize == null || navObsRecognize.Length == 0)
                {
                    GameObject childNavObs = UtilityServices.CreateChildNavMeshObs(forObject, true);
                    if (childNavObs)
                    {
                        Debug.Log(string.Format("<b><i><color=#0080ffff>The NavMeshObstacle on \"{0}\" has been disabled.Due to pivot modifcation NavMeshObstacles get incorrectly oriented.To preserve the same orientation as the one before pivot modification, the original NavMeshObstacle has been added to a child GameObject \"{1}\" use that as the NavMeshObstacle for this GameObject. Please don't delete this child object otherwise any subsequent changes made to modify pivot cannot guarantee correct NavMeshObstacle orientation. </color></i></b>", forObject.name, childNavObs.name));
                    }
                }

                // Save children positions before pivotal modifications
                childrenStatesBeforePivotMod = UtilityServices.SaveChildrenStates(forObject);
                // Save the postion and rotation of the collider before pivotal modification
                //SaveColliderState();
            }



            GameObject tempObject = new GameObject();

            tempObject.transform.parent   = forObject.transform;
            tempObject.transform.rotation = newRotation;
            Quaternion inverseRotation = Quaternion.Inverse(tempObject.transform.localRotation);


            Quaternion prevRotation = forObject.transform.rotation;

            DestroyImmediate(tempObject);


            //Vector3 oldScale = forObject.transform.localScale;
            //forObject.transform.localScale = new Vector3(1, 1, 1);

            Matrix4x4 transformationMatrix = Matrix4x4.Rotate(inverseRotation);

            forObject.transform.rotation = newRotation;

            Vector3[] vertices = selectedObjectMesh.vertices;
            Vector3[] normals  = selectedObjectMesh.normals;


            //Debug.Log("submeshes count  " + forObject.GetComponent<MeshFilter>().sharedMesh.subMeshCount + "  vertex count   "  + vertices.Length);


            for (int a = 0; a < vertices.Length; a++)
            {
                vertices[a] = transformationMatrix.MultiplyPoint3x4(vertices[a]);
                normals[a]  = transformationMatrix.MultiplyPoint3x4(normals[a]);
            }

            selectedObjectMesh.vertices = vertices;
            selectedObjectMesh.normals  = normals;

            selectedObjectMesh.RecalculateBounds();



            if (preserveState)
            {
                // Restore children positions and rotations as they were before pivotal modifications
                //new UtilityServices().RunAfter(() => { RestoreChildrenStates(); }, new WaitForEndOfFrame);
                UtilityServices.RestoreChildrenStates(childrenStatesBeforePivotMod);
            }
        }
예제 #2
0
        public static void MovePivot(GameObject forObject, Vector3 moveTo, bool preserveState)
        {
            RecognizeObject(forObject);

            if (!CheckObject(forObject))
            {
                return;
            }

            NavMeshObstacle      obs   = forObject.GetComponent <NavMeshObstacle>();
            NavMeshObstacleShape shape = NavMeshObstacleShape.Box;

            if (preserveState)
            {
                var collRecognize   = forObject.GetComponentsInChildren <CollRecognize>();
                var navObsRecognize = forObject.GetComponentsInChildren <NavObsRecognize>();

                if (collRecognize == null || collRecognize.Length == 0)
                {
                    GameObject childColl = UtilityServices.CreateChildCollider(forObject, true, moveTo, null);
                    if (childColl)
                    {
                        Debug.Log(string.Format("<b><i><color=#0080ffff>The Collider(s) on \"{0}\" has been disabled.Due to pivot modification colliders get incorrectly oriented.To preserve the same collider orientation as the one before pivot modification, the original collider has been added to a child GameObject \"{1}\" use that as the collider for this GameObject. Please don't delete this child object otherwise any subsequent changes made to modify pivot cannot guarantee correct collider orientation. </color></i></b>", forObject.name, childColl.name));
                    }
                }


                if (navObsRecognize == null || navObsRecognize.Length == 0)
                {
                    GameObject childNavObs = UtilityServices.CreateChildNavMeshObs(forObject, true);
                    if (childNavObs)
                    {
                        Debug.Log(string.Format("<b><i><color=#0080ffff>The NavMeshObstacle on \"{0}\" has been disabled.Due to pivot modifcation NavMeshObstacles get incorrectly oriented.To preserve the same orientation as the one before pivot modification, the original NavMeshObstacle has been added to a child GameObject \"{1}\" use that as the NavMeshObstacle for this GameObject. Please don't delete this child object otherwise any subsequent changes made to modify pivot cannot guarantee correct NavMeshObstacle orientation. </color></i></b>", forObject.name, childNavObs.name));
                    }
                }


                // Save children positions before pivotal modifications
                childrenStatesBeforePivotMod = UtilityServices.SaveChildrenStates(forObject);

                // Save the position and rotation of the collider before pivotal modification
                collStateBeforeMod = UtilityServices.SaveColliderState(forObject);

                if (obs)
                {
                    shape = obs.shape;
                    if (shape == NavMeshObstacleShape.Box)
                    {
                        obs.shape = NavMeshObstacleShape.Capsule;
                    }
                    else
                    {
                        obs.shape = NavMeshObstacleShape.Box;
                    }
                }
            }



            Vector3[] vertices = selectedObjectMesh.vertices;

            //Vector3 objCenterWorldSpace = selectedObject.transform.TransformPoint(selectedObjCenterLocalSpace);   // The world space position where the pivot will be moved and centered to the object

            Vector3 pivotOffsetLocalSpace = forObject.transform.InverseTransformVector(forObject.transform.position - moveTo);

            Matrix4x4 transformationMatrix = Matrix4x4.Translate(pivotOffsetLocalSpace);

            //var stopWatch = new System.Diagnostics.Stopwatch();
            //stopWatch.Start();


            for (int a = 0; a < vertices.Length; a++)
            {
                vertices[a] = transformationMatrix.MultiplyPoint3x4(vertices[a]);
            }


            //stopWatch.Stop();
            //UnityEngine.Debug.Log("Editor time for pivot centralization  " + stopWatch.ElapsedMilliseconds + "  for iterations  " + vertices.Length);

            selectedObjectMesh.vertices = vertices;    //Assign the vertex array back to the mesh

            selectedObjectMesh.RecalculateBounds();



            forObject.transform.position = moveTo;   // Move the object to the previous position


            if (preserveState)
            {
                if (obs)
                {
                    obs.shape = shape;
                }

                UtilityServices.RestoreColliderState(forObject, collStateBeforeMod);
                // Restore children positions and rotations as they were before pivotal modifications
                //new UtilityServices().RunAfter(()=> { RestoreChildrenStates();  }, new WaitForEndOfFrame);
                UtilityServices.RestoreChildrenStates(childrenStatesBeforePivotMod);
            }
        }