public static void RotatePivotForMeshless(GameObject meshlessObject, Quaternion newRotation, bool preserveState) { if (preserveState) { childrenStatesBeforePivotMod = UtilityServices.SaveChildrenStates(meshlessObject); } meshlessObject.transform.rotation = newRotation; //new UtilityServices().RunAfter(()=> { RestoreChildrenStates(); }, new WaitForEndOfFrame()); if (preserveState) { UtilityServices.RestoreChildrenStates(childrenStatesBeforePivotMod); } }
public static GameObject CreateChildNavMeshObs(GameObject forObject, bool forPosition) { string navMeshObsName = ""; var navMeshObstacle = forObject.GetComponent <NavMeshObstacle>(); if (navMeshObstacle == null) { return(null); } navMeshObsName = forObject.name + "_NavMeshObstacle"; navMeshObsName = "**" + navMeshObsName + "_DON'T DELETE**"; GameObject childNavMeshObs = UtilityServices.DuplicateGameObject(forObject, navMeshObsName, false, false); foreach (Component component in childNavMeshObs.GetComponents <Component>()) { if (component is Transform || component is NavMeshObstacle) { continue; } DestroyImmediate(component); } navMeshObstacle.enabled = false; childNavMeshObs.transform.position = forObject.transform.position; childNavMeshObs.transform.rotation = forObject.transform.rotation; childNavMeshObs.transform.parent = forObject.transform; childNavMeshObs.AddComponent <NavObsRecognize>(); return(childNavMeshObs); }
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); } }
public static GameObject CreateChildCollider(GameObject forObject, bool forPosition, Vector3?newPivotPos, Quaternion?newPivotRot) { string colliderName = ""; var colliders = forObject.GetComponents <Collider>(); if (colliders == null || colliders.Length == 0) { return(null); } #region Setting name of the child collider and disabling original colliders ColliderType lastType = ColliderType.None; foreach (Collider collider in colliders) { ColliderType currentType; //collider.enabled = false; if (collider is BoxCollider) { currentType = ColliderType.BoxCollider; colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType); if (lastType != ColliderType.None) { if (lastType != currentType) { colliderName = forObject.name + "_MixedColliders"; break; } else { colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType) + "s"; } } lastType = currentType; } else if (collider is CapsuleCollider) { currentType = ColliderType.CapsuleCollider; colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType); if (lastType != ColliderType.None) { if (lastType != currentType) { colliderName = forObject.name + "_MixedColliders"; break; } else { colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType) + "s"; } } lastType = currentType; } else if (collider is SphereCollider) { currentType = ColliderType.SphereCollider; colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType); if (lastType != ColliderType.None) { if (lastType != currentType) { colliderName = forObject.name + "_MixedColliders"; break; } else { colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType) + "s"; } } lastType = currentType; } else if (collider is MeshCollider) { currentType = ColliderType.MeshCollider; colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType); if (lastType != ColliderType.None) { if (lastType != currentType) { colliderName = forObject.name + "_MixedColliders"; break; } else { colliderName = forObject.name + "_" + Enum.GetName(typeof(ColliderType), currentType) + "s"; } } lastType = currentType; } } #endregion Setting name of the child collider and disabling original colliders colliderName = "**" + colliderName + "_DON'T DELETE**"; GameObject childCollider = UtilityServices.DuplicateGameObject(forObject, colliderName, false, false); foreach (Component component in childCollider.GetComponents <Component>()) { if (component is Transform || component is Collider) { continue; } DestroyImmediate(component); } foreach (Collider collider in forObject.GetComponents <Collider>()) { if (collider.enabled && forPosition) { collider.enabled = true; } else { collider.enabled = false; } } childCollider.transform.parent = forObject.transform; childCollider.AddComponent <CollRecognize>(); Collider coll = forObject.GetComponent <Collider>(); if (coll && coll is MeshCollider) { if (newPivotPos != null) { //childCollider.transform.position = (Vector3)newPivotPos; } else if (newPivotRot != null) { //childCollider.transform.rotation = (Quaternion)newPivotRot; } } return(childCollider); }