예제 #1
0
        // 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]);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        // 基点ノードを作成
        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);
        }