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); } }
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); } }