// private // Warning: maybe dangerous! private static void DestroyPivotObjects(GameObject rootObject) { if (rootObject == null) { return; } var springBones = rootObject.GetComponentsInChildren <SpringBone>(true); var pivots = from springBone in springBones where springBone.pivotNode != null select springBone.pivotNode; var skinBones = GameObjectUtil.GetAllBones(rootObject); var maybeSafeToDestroyPivots = from pivot in pivots where IsPivotProbablySafeToDestroy(pivot, skinBones) select pivot; var objectsToDestroy = maybeSafeToDestroyPivots.Select(pivot => pivot.gameObject).ToList(); var objectCount = objectsToDestroy.Count; for (int objectIndex = 0; objectIndex < objectCount; objectIndex++) { DestroyUnityObject(objectsToDestroy[objectIndex]); } }
public static void UpdateSpringManagerFromBoneList(SpringManager springManager) { var rootObject = springManager.gameObject; var designatedSpringBones = GetBonesDesignatedForDynamics(rootObject); var currentSpringBones = rootObject.GetComponentsInChildren <SpringBone>(true); var skinBones = GameObjectUtil.GetAllBones(rootObject); var springBonesToDestroy = currentSpringBones .Where(bone => !designatedSpringBones.Contains(bone.gameObject)); foreach (var boneToDestroy in springBonesToDestroy) { var pivot = boneToDestroy.pivotNode; if (pivot != null && SpringBoneSetup.IsPivotProbablySafeToDestroy(pivot, skinBones)) { SpringBoneSetup.DestroyUnityObject(pivot.gameObject); } SpringBoneSetup.DestroyUnityObject(boneToDestroy); } var objectsToAddBonesTo = designatedSpringBones .Where(bone => bone.GetComponent <SpringBone>() == null); foreach (var newBoneOwner in objectsToAddBonesTo) { var newSpringBone = newBoneOwner.AddComponent <SpringBone>(); SpringBoneSetup.CreateSpringPivotNode(newSpringBone); } SpringBoneSetup.FindAndAssignSpringBones(springManager, true); }
public static Dictionary <Transform, List <SpringBone> > GetPivotToSpringBoneMap(GameObject rootObject) { var skinBones = GameObjectUtil.GetAllBones(rootObject); var springBones = rootObject.GetComponentsInChildren <SpringBone>(true) .Where(bone => bone.pivotNode != null && !skinBones.Contains(bone.pivotNode)); // Collect pivots and their bones var pivotDictionary = new Dictionary <Transform, List <SpringBone> >(); foreach (var springBone in springBones) { List <SpringBone> pivotBones = null; if (!pivotDictionary.TryGetValue(springBone.pivotNode, out pivotBones)) { pivotBones = new List <SpringBone>(); } pivotBones.Add(springBone); pivotDictionary[springBone.pivotNode] = pivotBones; } return(pivotDictionary); }
// 基点ノードを作成 public static GameObject CreateSpringPivotNode(SpringBone springBone) { var pivotObject = new GameObject(springBone.name + "_Pivot"); pivotObject.transform.parent = springBone.transform.parent; pivotObject.transform.rotation = GetPivotRotation(springBone); pivotObject.transform.position = springBone.transform.position; pivotObject.AddComponent <SpringBonePivot>(); var oldPivotNode = springBone.pivotNode; if (oldPivotNode != null) { var skinBones = GameObjectUtil.GetAllBones(springBone.transform.root.gameObject); if (IsPivotProbablySafeToDestroy(oldPivotNode, skinBones)) { DestroyUnityObject(oldPivotNode.gameObject); } } springBone.pivotNode = pivotObject.transform; springBone.yAngleLimits.active = true; if (springBone.yAngleLimits.min > -0.5f && springBone.yAngleLimits.max < 0.5f) { springBone.yAngleLimits.min = -20f; springBone.yAngleLimits.max = 20f; } springBone.zAngleLimits.active = true; if (springBone.zAngleLimits.min > -0.5f && springBone.zAngleLimits.max < 0.5f) { springBone.zAngleLimits.min = 0f; springBone.zAngleLimits.max = 20f; } return(pivotObject); }
#pragma warning restore 0649 private static GameObject SetupTransformFromRecord ( GameObject rootObject, Dictionary <string, Transform> objectMap, TransformSerializer serializer ) { Transform parent = null; if (!objectMap.TryGetValue(serializer.parentName, out parent)) { Debug.LogError("親が見つかりませんでした: " + serializer.parentName); return(null); } var objectTransform = GetChildByName(parent, serializer.name); if (objectTransform == null) { objectTransform = CreateNewGameObject(parent, serializer.name); if (objectTransform == null) { return(null); } } // Don't change the transform if it is a bone var skinBoneNames = GameObjectUtil.GetAllBones(rootObject) .Select(bone => bone.name); if (!skinBoneNames.Contains(serializer.name)) { objectTransform.localScale = serializer.scale; objectTransform.localEulerAngles = serializer.eulerAngles; objectTransform.localPosition = serializer.position; } return(objectTransform.gameObject); }
public static void CleanUpDynamics() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } var springManagers = GameObjectUtil.FindComponentsOfType <SpringManager>(); if (!springManagers.Any()) { return; } var queryMessage = "本当にダイナミクスのクリーンナップを行いますか?"; if (EditorUtility.DisplayDialog("ダイナミクスクリーンナップ", queryMessage, "削除", "キャンセル")) { RemoveDuplicateComponents <SpringBone>(); RemoveDuplicateComponents <DynamicsNull>(); RemoveDuplicateComponents <SpringManager>(); springManagers = GameObjectUtil.FindComponentsOfType <SpringManager>(); foreach (var springManager in springManagers) { var springBones = springManager.GetComponentsInChildren <SpringBone>(true); var allBones = GameObjectUtil.GetAllBones(springManager.gameObject); var maybeUnusedGameObjects = new HashSet <GameObject>(); var unusedSpheres = springManager.GetComponentsInChildren <SpringSphereCollider>(true) .Where(collider => !springBones.Any(springBone => springBone.sphereColliders.Contains(collider))); foreach (var collider in unusedSpheres) { maybeUnusedGameObjects.Add(collider.gameObject); SpringBoneSetup.DestroyUnityObject(collider); } var unusedCapsules = springManager.GetComponentsInChildren <SpringCapsuleCollider>(true) .Where(collider => !springBones.Any(springBone => springBone.capsuleColliders.Contains(collider))); foreach (var collider in unusedCapsules) { maybeUnusedGameObjects.Add(collider.gameObject); SpringBoneSetup.DestroyUnityObject(collider); } var unusedPanels = springManager.GetComponentsInChildren <SpringPanelCollider>(true) .Where(collider => !springBones.Any(springBone => springBone.panelColliders.Contains(collider))); foreach (var collider in unusedPanels) { maybeUnusedGameObjects.Add(collider.gameObject); SpringBoneSetup.DestroyUnityObject(collider); } var gameObjectsToDelete = maybeUnusedGameObjects .Where(gameObject => !allBones.Contains(gameObject.transform)); foreach (var gameObject in gameObjectsToDelete) { if (gameObject.GetComponents <Component>().Length <= 1) { SpringBoneSetup.DestroyUnityObject(gameObject); } } // Next remove all empty entries from SpringBones Undo.RecordObjects(springBones.ToArray(), "SpringBone cleanup"); foreach (var springBone in springBones) { springBone.capsuleColliders = springBone.capsuleColliders.Where(item => item != null).ToArray(); springBone.panelColliders = springBone.panelColliders.Where(item => item != null).ToArray(); springBone.sphereColliders = springBone.sphereColliders.Where(item => item != null).ToArray(); springBone.lengthLimitTargets = springBone.lengthLimitTargets.Where(item => item != null).ToArray(); } } } }
public static void DeleteAllChildCollidersFromSelection() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } if (Selection.gameObjects.Length == 0) { return; } var queryMessage = "本当に選択中のオブジェクトの全子供のコライダーを削除しますか?"; if (!EditorUtility.DisplayDialog("選択コライダーを削除", queryMessage, "削除", "キャンセル")) { return; } var charaBones = Selection.gameObjects .SelectMany(gameObject => GameObjectUtil.GetAllBones(gameObject.transform.root.gameObject)) .Distinct(); var colliderTypes = SpringColliderSetup.GetColliderTypes(); var deadColliders = new List <Component>(); foreach (var gameObject in Selection.gameObjects) { foreach (var type in colliderTypes) { deadColliders.AddRange(gameObject.GetComponentsInChildren(type, true)); } } deadColliders = deadColliders.Distinct().ToList(); var probablyDeadGameObjects = deadColliders.Select(collider => collider.gameObject) .Distinct() .Where(gameObject => !charaBones.Contains(gameObject.transform) && gameObject.GetComponents <Component>().Count() <= 1 && gameObject.transform.childCount == 0) .ToArray(); var springBones = GameObjectUtil.FindComponentsOfType <SpringBone>(); var undoObjects = new List <Object>(springBones.Select(item => (Object)item)); undoObjects.AddRange(deadColliders.Select(item => (Object)item)); undoObjects.AddRange(probablyDeadGameObjects.Select(item => (Object)item)); Undo.RecordObjects(undoObjects.ToArray(), "Remove all selected child colliders"); foreach (var springBone in springBones) { springBone.sphereColliders = springBone.sphereColliders.Where(collider => !deadColliders.Contains(collider)).ToArray(); springBone.capsuleColliders = springBone.capsuleColliders.Where(collider => !deadColliders.Contains(collider)).ToArray(); springBone.panelColliders = springBone.panelColliders.Where(collider => !deadColliders.Contains(collider)).ToArray(); } foreach (var deadCollider in deadColliders) { SpringBoneSetup.DestroyUnityObject(deadCollider); } foreach (var gameObject in probablyDeadGameObjects) { SpringBoneSetup.DestroyUnityObject(gameObject); } }
private static bool BuildSpringBoneFromSerializer ( SpringBoneSetupMaps setupMaps, SpringBoneSerializer serializer ) { var baseData = serializer.baseData; Transform childBone = null; if (!setupMaps.allChildren.TryGetValue(baseData.boneName, out childBone)) { Debug.LogError("ボーンが見つかりません: " + baseData.boneName); return(false); } var springBone = childBone.gameObject.AddComponent <SpringBone>(); springBone.stiffnessForce = baseData.stiffness; springBone.dragForce = baseData.drag; springBone.springForce = baseData.springForce; springBone.windInfluence = baseData.windInfluence; springBone.angularStiffness = baseData.angularStiffness; springBone.yAngleLimits = BuildAngleLimitsFromSerializer(baseData.yAngleLimits); springBone.zAngleLimits = BuildAngleLimitsFromSerializer(baseData.zAngleLimits); springBone.radius = baseData.radius; springBone.lodLevel = baseData.lodLevel; springBone.lodMode = (SpringBone.LODMode)baseData.lodMode; springBone.lengthLimitStiffness = baseData.lengthLimitStiffness; springBone.isLengthLimitPercentage = baseData.isLengthLimitPercentage; springBone.lengthLimitMode = (SpringBone.LengthLimitMode)baseData.lengthLimitMode; // Pivot node var pivotNodeName = baseData.pivotName; Transform pivotNode = null; if (pivotNodeName.Length > 0) { if (!setupMaps.allChildren.TryGetValue(pivotNodeName, out pivotNode)) { Debug.LogError("Pivotオブジェクトが見つかりません: " + pivotNodeName); pivotNode = null; } } if (pivotNode == null) { pivotNode = springBone.transform.parent ?? springBone.transform; } else { var skinBones = GameObjectUtil.GetAllBones(springBone.transform.root.gameObject); if (pivotNode.GetComponent <SpringBonePivot>() && SpringBoneSetup.IsPivotProbablySafeToDestroy(pivotNode, skinBones)) { pivotNode.position = springBone.transform.position; } } springBone.pivotNode = pivotNode; springBone.lengthLimitTargets = baseData.lengthLimits .Where(lengthLimit => setupMaps.allChildren.ContainsKey(lengthLimit.objectName)) .Select(lengthLimit => setupMaps.allChildren[lengthLimit.objectName]) .ToArray(); springBone.sphereColliders = serializer.colliderNames .Where(name => setupMaps.sphereColliders.ContainsKey(name)) .Select(name => setupMaps.sphereColliders[name]) .ToArray(); springBone.capsuleColliders = serializer.colliderNames .Where(name => setupMaps.capsuleColliders.ContainsKey(name)) .Select(name => setupMaps.capsuleColliders[name]) .ToArray(); springBone.panelColliders = serializer.colliderNames .Where(name => setupMaps.panelColliders.ContainsKey(name)) .Select(name => setupMaps.panelColliders[name]) .ToArray(); return(true); }