コード例 #1
0
    void CreateClone(GameObject from, GameObject to)
    {
        DBCUtils.CreateConstraints(from, new GameObject[] { to });
        foreach (var to_child in to.Children())
        {
            var res   = from.Children().Where(x => x.name == to_child.name);
            var count = res.Count();
            if (count > 1)
            {
                throw new Exception("Creating rotation clone failed: found duplicate names");
            }

            if (count < 1)
            {
                Debug.LogWarning($"Could not find bone named {to_child.name}");
            }

            CreateClone(res.First(), to_child);
        }
    }
コード例 #2
0
    void ForEachParentAndSibling(Action <GameObject, List <GameObject> > action)
    {
        var parent       = _constraintSource;
        var siblings     = _constrainedObj;
        var nextSiblings = new List <GameObject>();

        while (siblings.Count > 0)
        {
            nextSiblings.Clear();
            action(parent, siblings);

            parent = DBCUtils.FindNextInChain(parent, _rootName);

            if (parent == null)
            {
                return;
            }

            siblings = siblings.SelectMany(x => x.Children()).ToList();
        }
    }
コード例 #3
0
    void OnGUI()
    {
        _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);

        // [GUI] Logo
        if (!_logo)
        {
            _logo = (Texture)EditorGUIUtility.Load("Assets/Nara/Editor/Resources/DBCLogo.png");
        }

        UI.Centered(() =>
                    GUILayout.Label(_logo)
                    );

        UI.Space(16);

        // [GUI] Constraint source options
        _constraintSource = (GameObject)EditorGUILayout.ObjectField($"Constraint source root", _constraintSource, typeof(GameObject), true);

        _modifySource = EditorGUILayout.Toggle("Modify source constraint", _modifySource);

        if (!_constraintSource && !_modifySource)
        {
            EditorGUILayout.HelpBox("A constraint source root is needed to generate constraints. Or use modify source constraint to generate a new source object.", MessageType.Warning);
        }

        if (!_constraintSource && _modifySource)
        {
            EditorGUILayout.HelpBox("A new Gameobject as constraint source will be generated under the parent of the first element of the constraint bones. Children of source object might have their positions altered.", MessageType.Info);
        }

        _rootName = _constraintSource ? Regex.Match(_constraintSource.name, @"^(.*?)_?\d*$").Groups[1].Value : "";

        UI.Space(16);

        // [GUI] Constrained objects count
        _constrainedObjCount = EditorGUILayout.IntField("Constrained objects count", _constrainedObjCount);
        if (_constrainedObjCount <= 0)
        {
            _constrainedObj.Clear();
            _constrainedObjCount = 1;
        }

        // [GUI] Constrained objects manual selection
        UI.Foldout(ref _showConstrainedObj, "Constrained objects", () => {
            EditorGUI.indentLevel++;

            List <GameObject> constraintBonesTemp = new List <GameObject>(_constrainedObjCount);
            for (int i = 0; i < _constrainedObjCount; i++)
            {
                GameObject cBone = i < _constrainedObj.Count ? _constrainedObj[i] : null;

                cBone = (GameObject)EditorGUILayout.ObjectField($"Element {i}", cBone, typeof(GameObject), true);

                constraintBonesTemp.Add(cBone);
            }
            _constrainedObj = constraintBonesTemp.Where(x => x != null).ToList();

            EditorGUI.indentLevel--;
        });

        // [GUI] Constrained objects automatic selection
        UI.Horizontal(() =>
        {
            if (GUILayout.Button("From selection"))
            {
                _constrainedObj = Selection.gameObjects
                                  .Where(x => x != _constraintSource)
                                  .Reverse()
                                  .ToList();
                _constrainedObjCount = Math.Max(_constrainedObj.Count, _constrainedObjCount);
            }
            if (GUILayout.Button("Select similar"))
            {
                var parents = _constrainedObj.Select(x => x.Parent()).Distinct();
                var names   = _constrainedObj.Select(x => Regex.Replace(x.name, @"(_?\d+)*$", "")).Distinct();

                _constrainedObj = parents
                                  .SelectMany(x => x.Children())
                                  .Where(x => names.Any(name => x.name.StartsWith(name)))
                                  .Where(x => x != _constraintSource)
                                  .ToList();
                _constrainedObjCount = _constrainedObj.Count;
            }
        });

        UI.Space(24);

        // [GUI] Generator buttons
        var canMakeConstraints = _constraintSource != null;
        var canGenerateSource  = _modifySource;
        var canMagic           = canMakeConstraints || canGenerateSource;

        // [GUI] Best button <3
        using (new EditorGUI.DisabledScope(!canMagic))
            if (GUILayout.Button("✧・゚: *✧・゚:*    Setup constraints    *:・゚✧*:・゚✧", GUILayout.Height(45)))
            {
                if (_modifySource)
                {
                    if (_constraintSource == null)
                    {
                        _constraintSource      = DBCUtils.CreateSource(_constrainedObj);
                        _rootName              = $"{_constraintSource.name}_source";
                        _constraintSource.name = $"{_rootName}_0";
                    }

                    Debug.Log("Extending chain and setting heights");
                    DBCUtils.ExtendChain(_constraintSource, _constrainedObj, _rootName);

                    var position = _constraintSource.transform.position;
                    ForEachParentAndSibling(DBCUtils.SetSourceChainY);
                    _constraintSource.transform.position = position;
                }

                Debug.Log("Creating constraints.");
                ForEachParentAndSibling(DBCUtils.CreateConstraints);
                ForEachParentAndSibling(DBCUtils.ActivateConstraints);
                Debug.Log("Done!");

                Selection.activeGameObject = _constraintSource;
            }

        UI.Space(24);

        // [GUI] Manual generation buttons
        UI.Foldout(ref _showManualButtons, "Manual setup", () => {
            EditorGUILayout.HelpBox("You probably don't need  any this, unless you really know what you're doing.", MessageType.Info);

            using (new EditorGUI.DisabledScope(canMakeConstraints))
                if (GUILayout.Button("Generate source chain"))
                {
                    _constraintSource      = DBCUtils.CreateSource(_constrainedObj);
                    _rootName              = $"{_constraintSource.name}_source";
                    _constraintSource.name = $"{_rootName}_0";

                    DBCUtils.ExtendChain(_constraintSource, _constrainedObj, _rootName);
                    ForEachParentAndSibling(DBCUtils.SetSourceChainY);
                }

            using (new EditorGUI.DisabledScope(!canMakeConstraints))
                if (GUILayout.Button("Add constraint components"))
                {
                    ForEachParentAndSibling(DBCUtils.CreateConstraints);
                }

            if (GUILayout.Button("Activate constraints"))
            {
                ForEachParentAndSibling(DBCUtils.ActivateConstraints);
            }

            if (GUILayout.Button("Remove constraints"))
            {
                ForEachParentAndSibling(DBCUtils.RemoveConstraints);
            }

            if (GUILayout.Button("Create rotation puppet"))
            {
                _constrainedObj.ForEach(x => CreateClone(_constraintSource, x));
            }
        });

        EditorGUILayout.EndScrollView();
    }