public static void DeleteSpringBonesAndManagers() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } if (Selection.gameObjects.Length != 1) { Debug.LogError("一つだけのルートオブジェクトを選択してください"); return; } var rootObject = Selection.gameObjects.First(); var queryMessage = "本当にこのオブジェクトとその子供に入っている全ての\n" + "スプリングボーンとスプリングマネージャーを削除しますか?\n\n" + rootObject.name; if (EditorUtility.DisplayDialog( "スプリングボーンとマネージャーを削除", queryMessage, "削除", "キャンセル")) { SpringBoneSetup.DestroySpringManagersAndBones(rootObject); AssetDatabase.Refresh(); } }
public static void AssignSpringBonesRecursively() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } if (Selection.gameObjects.Length < 1) { Debug.LogError("一つ以上のオブジェクトを選択してください。"); return; } var springManagers = new HashSet <SpringManager>(); foreach (var gameObject in Selection.gameObjects) { SpringBoneSetup.AssignSpringBonesRecursively(gameObject.transform); var manager = gameObject.GetComponentInParent <SpringManager>(); if (manager != null) { springManagers.Add(manager); } } foreach (var manager in springManagers) { SpringBoneSetup.FindAndAssignSpringBones(manager, true); } AssetDatabase.Refresh(); }
public static void DeleteSpringBonesAndManagers() { if (Application.isPlaying) { Debug.LogError("请退出Play模式。"); return; } if (Selection.gameObjects.Length != 1) { Debug.LogError("只可以选择一个Root对象"); return; } var rootObject = Selection.gameObjects.First(); var queryMessage = "确定要把以下对象及其子对象中的\n" + "SpringBone与SpringManager都删除吗?\n\n" + rootObject.name ; if (EditorUtility.DisplayDialog( "考虑清楚,真的要删掉嘛", queryMessage, "删除", "取消")) { SpringBoneSetup.DestroySpringManagersAndBones(rootObject); AssetDatabase.Refresh(); } }
public static SpringManager PerformSetup ( GameObject rootObject, IEnumerable <GameObject> newSpringBones, AutoSetupParameters parameters ) { SpringBoneSetup.DestroySpringManagersAndBones(rootObject); SpringColliderSetup.DestroySpringColliders(rootObject); var springBones = new List <SpringBone>(); foreach (var boneParent in newSpringBones.Where(boneParent => boneParent.transform.childCount > 0)) { springBones.Add(boneParent.AddComponent <SpringBone>()); } var manager = rootObject.AddComponent <SpringManager>(); SpringBoneSetup.FindAndAssignSpringBones(manager, true); if (parameters.createPivots) { foreach (var springBone in springBones) { SpringBoneSetup.CreateSpringPivotNode(springBone); } } return(manager); }
public void BuildObjects(GameObject springBoneRoot, GameObject colliderRoot, IEnumerable <string> requiredBones) { var managerProperties = PersistentSpringManagerProperties.Create( springBoneRoot.GetComponentInChildren <SpringManager>()); SpringBoneSetup.DestroySpringManagersAndBones(springBoneRoot); if (requiredBones != null) { FilterBoneRecordsByRequiredBonesAndCreateUnrecordedBones(springBoneRoot, requiredBones); } var initialTransforms = GameObjectUtil.BuildNameToComponentMap <Transform>(springBoneRoot, true); foreach (var record in pivotRecords) { BuildPivotFromSerializer(initialTransforms, record); } var setupMaps = SpringBoneSetupMaps.Build(springBoneRoot, colliderRoot); foreach (var record in springBoneRecords) { BuildSpringBoneFromSerializer(setupMaps, record); } var springManager = springBoneRoot.AddComponent <SpringManager>(); if (managerProperties != null) { managerProperties.ApplyTo(springManager); } SpringBoneSetup.FindAndAssignSpringBones(springManager); }
private void FilterBoneRecordsByRequiredBonesAndCreateUnrecordedBones ( GameObject springBoneRoot, IEnumerable <string> requiredBones ) { var boneRecordsToUse = springBoneRecords .Where(record => requiredBones.Contains(record.baseData.boneName)); var recordedBoneNames = boneRecordsToUse.Select(record => record.baseData.boneName); var bonesWithoutRecords = requiredBones .Except(recordedBoneNames) .Select(boneName => GameObjectUtil.FindChildByName(springBoneRoot, boneName)) .Where(item => item != null) .Select(item => item.gameObject); foreach (var bone in bonesWithoutRecords) { var springBone = bone.AddComponent <SpringBone>(); SpringBoneSetup.CreateSpringPivotNode(springBone); } // Report the skipped bone records so the user knows var skippedBoneRecords = springBoneRecords.Except(boneRecordsToUse); foreach (var skippedRecord in skippedBoneRecords) { Debug.LogWarning(skippedRecord.baseData.boneName + "\nボーンリストにないので作成しません"); } springBoneRecords = boneRecordsToUse; }
public static void UpdateSpringManagerFromBoneList(SpringManager springManager) { var rootObject = springManager.gameObject; var designatedSpringBones = GetBonesDesignatedForDynamics(rootObject); var currentSpringBones = rootObject.GetComponentsInChildren <SpringBone>(true); var skinBones = GameObjectExtensions.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); }
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)); } }
private static void RemoveDuplicateComponents <T>() where T : Component { // Delete all components of the same type after the first var duplicateObjects = GameObjectExtensions.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]); } } } }
public static void CreatePivotForSpringBones() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } if (Selection.gameObjects.Length < 1) { Debug.LogError("一つ以上のオブジェクトを選択してください。"); return; } var selectedSpringBones = Selection.gameObjects .Select(gameObject => gameObject.GetComponent <SpringBone>()) .Where(bone => bone != null); foreach (var springBone in selectedSpringBones) { SpringBoneSetup.CreateSpringPivotNode(springBone); } }
public static void AddToOrUpdateSpringManagerInSelection() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } if (Selection.gameObjects.Length <= 0) { Debug.LogError("一つ以上のオブジェクトを選択してください。"); return; } foreach (var gameObject in Selection.gameObjects) { var manager = gameObject.GetComponent <SpringManager>(); if (manager == null) { manager = gameObject.AddComponent <SpringManager>(); } SpringBoneSetup.FindAndAssignSpringBones(manager, true); } }
public static void CleanUpDynamics() { if (Application.isPlaying) { Debug.LogError("再生モードを止めてください。"); return; } var springManagers = GameObjectExtensions.GameObjectUtil.FindComponentsOfType <SpringManager>(); if (!springManagers.Any()) { return; } var queryMessage = "本当にダイナミクスのクリーンナップを行いますか?"; if (EditorUtility.DisplayDialog("ダイナミクスクリーンナップ", queryMessage, "削除", "キャンセル")) { RemoveDuplicateComponents <SpringBone>(); RemoveDuplicateComponents <DynamicsNull>(); RemoveDuplicateComponents <SpringManager>(); springManagers = GameObjectExtensions.GameObjectUtil.FindComponentsOfType <SpringManager>(); foreach (var springManager in springManagers) { var springBones = springManager.GetComponentsInChildren <SpringBone>(true); var allBones = GameObjectExtensions.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 => GameObjectExtensions.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 = GameObjectExtensions.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); }
private static void UpdateBoneList(SpringManager manager) { Undo.RecordObject(manager, "SpringBoneリストを更新"); SpringBoneSetup.FindAndAssignSpringBones(manager, true); }
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 static void UpdateBoneList(SpringManager manager) { SpringBoneSetup.FindAndAssignSpringBones(manager, true); }
private void OnDestroy() { SpringBoneSetup.AutoSave(this); }