public static void PromptToUpdateSpringBonesFromList() { if (Application.isPlaying) { Debug.LogError("再生中に更新できません"); return; } var selectedSpringManagers = Selection.gameObjects .Select(gameObject => gameObject.GetComponent <SpringManager>()) .Where(manager => manager != null) .ToArray(); if (!selectedSpringManagers.Any()) { selectedSpringManagers = GameObjectUtil.FindComponentsOfType <SpringManager>().ToArray(); } if (selectedSpringManagers.Count() != 1) { Debug.LogError("一つだけのSpringManagerを選択してください"); return; } var springManager = selectedSpringManagers.First(); var queryMessage = "ボーンリストから揺れものボーンを更新しますか?\n\n" + "リストにないSpringBone情報は削除され、\n" + "モデルにないSpringBone情報は追加されます。\n\n" + "SpringManager: " + springManager.name; if (EditorUtility.DisplayDialog("ボーンリストから更新", queryMessage, "更新", "キャンセル")) { AutoSpringBoneSetup.UpdateSpringManagerFromBoneList(springManager); } }
public static void PromptToUpdateSpringBonesFromList() { if (Application.isPlaying) { Debug.LogError("Play过程中无法更新"); return; } var selectedSpringManagers = Selection.gameObjects .Select(gameObject => gameObject.GetComponent <SpringManager>()) .Where(manager => manager != null) .ToArray(); if (!selectedSpringManagers.Any()) { selectedSpringManagers = GameObjectUtil.FindComponentsOfType <SpringManager>().ToArray(); } if (selectedSpringManagers.Count() != 1) { Debug.LogError("只可以选择一个SpringManager"); return; } var springManager = selectedSpringManagers.First(); var queryMessage = "要根据所选Manager的列表更新SpringBone?\n\n" + "不在列表中的SpringBone信息会被删除、\n" + "列表中存在,但是模型上没有的SpringBone将被添加。\n\n" + "SpringManager: " + springManager.name; if (EditorUtility.DisplayDialog("从所选Manager的列表更新", queryMessage, "更新", "取消")) { AutoSpringBoneSetup.UpdateSpringManagerFromBoneList(springManager); } }
private static SpringManagerBoneGroup[] FindSpringBonesUsingCollider <T> ( Object[] components, System.Func <SpringBone, IEnumerable <T>, bool> containmentCheck ) where T : class { var colliders = components .Select(component => component as T) .Where(component => component != null) .ToArray(); var allSpringBones = GameObjectUtil.FindComponentsOfType <SpringBone>(); var matchingSpringBones = allSpringBones .Where(springBone => containmentCheck(springBone, colliders)) .Distinct() .ToArray(); System.Array.Sort(matchingSpringBones, (a, b) => string.Compare(a.name, b.name)); // Now arrange by manager var allManagers = GameObjectUtil.FindComponentsOfType <SpringManager>().ToArray(); System.Array.Sort(allManagers, (a, b) => string.Compare(a.name, b.name)); var boneGroups = new List <SpringManagerBoneGroup>(); foreach (var manager in allManagers) { var bonesForManager = matchingSpringBones .Where(bone => manager.springBones.Contains(bone)) .ToArray(); if (bonesForManager.Any()) { boneGroups.Add(new SpringManagerBoneGroup { manager = manager, bones = bonesForManager, boneCountLabel = string.Format("Bones: {0}", bonesForManager.Length) }); } } // Now find the bones with no manager var bonesWithNoManager = matchingSpringBones .Where(bone => !allManagers.Any(manager => manager.springBones.Contains(bone))) .ToArray(); if (bonesWithNoManager.Any()) { boneGroups.Add(new SpringManagerBoneGroup { manager = null, bones = bonesWithNoManager, boneCountLabel = string.Format("Bones: {0}", bonesWithNoManager.Length) }); } return(boneGroups.ToArray()); }
private static void AutoLoadDynamics() { var springManagers = GameObjectUtil.FindComponentsOfType <SpringManager>(); foreach (var springManager in springManagers) { var name = springManager.name; SpringBoneSetup.AutoLoad(springManager); System.IO.File.Delete(SpringBoneSetup.GetAutoSavePath(name)); } }
public static void DeleteSelectedBones() { var springBonesToDelete = GameObjectUtil.FindComponentsOfType <SpringBone>() .Where(bone => Selection.gameObjects.Contains(bone.gameObject)) .ToArray(); var springManagersToUpdate = GameObjectUtil.FindComponentsOfType <SpringManager>() .Where(manager => manager.springBones.Any(bone => springBonesToDelete.Contains(bone))) .ToArray(); Undo.RecordObjects(springManagersToUpdate, "Delete selected bones"); foreach (var boneToDelete in springBonesToDelete) { Undo.DestroyObjectImmediate(boneToDelete); } foreach (var manager in springManagersToUpdate) { manager.FindSpringBones(true); } }
private static void RemoveDuplicateComponents <T>() where T : Component { // Delete all components of the same type after the first var duplicateObjects = GameObjectUtil.FindComponentsOfType <Transform>() .Where(item => item.GetComponents <T>().Length > 1); if (duplicateObjects.Any()) { Undo.RecordObjects(duplicateObjects.ToArray(), "Remove duplicate components"); foreach (var transform in duplicateObjects) { var components = transform.GetComponents <T>(); for (int componentIndex = 1; componentIndex < components.Length; componentIndex++) { SpringBoneSetup.DestroyUnityObject(components[componentIndex]); } } } }
private void AcquireSourceBonesOnSideOfAxis(bool getLessThanZero) { if (boneEntries == null) { boneEntries = new List <BoneEntry>(); } // Is there a better way of defining this? System.Func <SpringBone, bool> boneMatches = item => false; if (getLessThanZero) { switch (mirrorAxis) { case Axis.X: boneMatches = item => item.transform.position.x < 0f; break; case Axis.Y: boneMatches = item => item.transform.position.y < 0f; break; case Axis.Z: boneMatches = item => item.transform.position.z < 0f; break; } } else { switch (mirrorAxis) { case Axis.X: boneMatches = item => item.transform.position.x > 0f; break; case Axis.Y: boneMatches = item => item.transform.position.y > 0f; break; case Axis.Z: boneMatches = item => item.transform.position.z > 0f; break; } } var allSpringBones = GameObjectUtil.FindComponentsOfType <SpringBone>(); var selectedBones = allSpringBones.Where(boneMatches); var newBoneEntries = selectedBones .Select(bone => new BoneEntry(bone, FindMirroredSpringBone(bone, mirrorAxis))) .Where(entry => entry.targetBone != null && entry.targetBone != entry.sourceBone); boneEntries = newBoneEntries.ToList(); }
private void InitializeData() { if (managers != null && managers.Length > 0) { return; } managers = targets .Select(target => target as Component) .Where(target => target != null) .Select(target => target.GetComponentInParent <SpringManager>()) .Where(manager => manager != null) .Distinct() .ToArray(); var pivots = targets .Where(target => target is Component) .Select(target => ((Component)target).transform) .ToArray(); bones = GameObjectUtil.FindComponentsOfType <SpringBone>() .Where(bone => pivots.Contains(bone.pivotNode)) .ToArray(); }
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 void PerformMirror() { var mirrorItems = boneEntries.Where( item => item.sourceBone != null && item.targetBone != null && item.sourceBone != item.targetBone); var undoItems = mirrorItems.Select(item => (Component)item.targetBone).ToList(); var allSkinBones = GameObjectUtil.FindComponentsOfType <SkinnedMeshRenderer>() .SelectMany(renderer => renderer.bones) .Distinct() .ToArray(); var editablePivots = mirrorItems .Select(item => item.targetBone.pivotNode) .Where(pivotNode => pivotNode != null && SpringBoneSetup.IsPivotProbablySafeToDestroy(pivotNode, allSkinBones)) .ToArray(); undoItems.AddRange(editablePivots); Undo.RecordObjects(undoItems.ToArray(), "Mirror SpringBones"); foreach (var mirrorItem in mirrorItems) { var sourceBone = mirrorItem.sourceBone; var targetBone = mirrorItem.targetBone; var rootManager = targetBone.GetComponentInParent <SpringManager>(); if (rootManager == null) { continue; } targetBone.stiffnessForce = sourceBone.stiffnessForce; targetBone.dragForce = sourceBone.dragForce; targetBone.springForce = sourceBone.springForce; targetBone.windInfluence = sourceBone.windInfluence; if (editablePivots.Contains(targetBone.pivotNode)) { MirrorPivot(sourceBone, targetBone); } targetBone.angularStiffness = sourceBone.angularStiffness; sourceBone.yAngleLimits.CopyTo(targetBone.yAngleLimits); sourceBone.zAngleLimits.CopyTo(targetBone.zAngleLimits); targetBone.yAngleLimits.min = -sourceBone.yAngleLimits.max; targetBone.yAngleLimits.max = -sourceBone.yAngleLimits.min; targetBone.lengthLimitTargets = FindMirroredComponents( rootManager.gameObject, sourceBone.lengthLimitTargets, mirrorAxis) .Where(item => item != null) .ToArray(); targetBone.radius = sourceBone.radius; targetBone.sphereColliders = FindMirroredComponents( rootManager.gameObject, sourceBone.sphereColliders, mirrorAxis) .Where(item => item != null) .ToArray(); targetBone.capsuleColliders = FindMirroredComponents( rootManager.gameObject, sourceBone.capsuleColliders, mirrorAxis) .Where(item => item != null) .ToArray(); targetBone.panelColliders = FindMirroredComponents( rootManager.gameObject, sourceBone.panelColliders, mirrorAxis) .Where(item => item != null) .ToArray(); } }
private void Start() { // Must get the ForceProviders in Start and not Awake or Unity will complain that // "the scene is not loaded" forceProviders = GameObjectUtil.FindComponentsOfType <ForceProvider>().ToArray(); }