Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Moving multiple controllers at once
#21
Dude, you have no idea how helpful that was. I never even considered the other array, I thought Unity would add slots if you tried to write to an empty slot. Thanks man.
However, the custom editor did cause issues so I tried a different approach but I couldn't figure out how to get GUI to work without the editor inheritance. But I guess I learned about  InitializeOnLoad and static functions and calling functions in other scripts, so... Rolleyes 

Using custom editor with SplineController messes up the inspector as you saw, so it might be some odd quirk I missed. After checking it looks like I could use the Unitys default layout for said component, but I don't get how. Do you have any knowledge of this?

I  used a workaround and use custom editor with Transform instead (which messes that one up,  using a custom TransformInspector code to get it back to normal, it's hacky though).

So now everything finally works as intended (I think).
I found a new way, remaking it.

This is what it looks like. https://imgur.com/a/8lIuUVa
Reply
#22
Glad I could help. When debugging, never assume anything, verify everything.
Thanks for sharing the code
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply
#23
Here's the new script with no CustomEditor or workaround hacks.
Code:
using UnityEngine;
using UnityEditor;
using FluffyUnderware.Curvy.Controllers;
using System.Linq;
using System.Collections.Generic;


namespace FluffyUnderware.CurvyEditor.Controllers
{
    [InitializeOnLoad]
    public static class MoveMultipleControllers
    {
        static int[] clampStyle;
        static bool forceClamp = false;
        static bool clamp = false;
        static bool endDrag = false;
        static bool cancel = false;
        static float slider = 0;
        static float[] orgPos;
        static float[] maxPos;
        static float offset = 0;
        static float orgPosMax = 0;
        static float orgPosMin = 0;
        static float maxPosMax = 0;
        static Color bgC = new Color(0.6117f, 0.6274f, 0.6356f, 0.75f);
        static Rect boxW = new Rect(0, 0, 260, 100);
        static Rect boxS = new Rect(10, 20, 240, 10);
        static Rect boxC = new Rect(10, 10, 10, 10);
        static Rect boxT = new Rect(10, 40, 100, 40);
        static int index = 0;
        static List<SplineController> selectedItems;

        static MoveMultipleControllers()
        {
            EditorApplication.update += update;
        }

        public static void update()
        {
            Selection.selectionChanged = checkSelection;
        }

        public static void checkSelection()
        {
            selectedItems = Selection.transforms.Select(t => t.gameObject.GetComponent<SplineController>()).Where(c => c != null).ToList();

            if (selectedItems.Count > 1)
            {
                forceClamp = false;
                index = 0;
                orgPos = new float[selectedItems.Count];
                maxPos = new float[selectedItems.Count];
                clampStyle = new int[selectedItems.Count];
                selectedItems.ToArray();

                foreach (SplineController checkController in selectedItems)
                {
                    if (checkController.Spline == null) //Is controller on a spline?
                    {
                        index++;
                        continue;
                    }
                    orgPos[index] = checkController.AbsolutePosition;
                    maxPos[index] = checkController.Spline.Length;
                    clampStyle[index] = (int)checkController.Clamping;
                    index++;
                }
                if (clampStyle.Contains(0) || clampStyle.Contains(2)) //Forces clamping unless all controllers are Loop.
                {
                    forceClamp = true;
                    clamp = true;
                }
                orgPosMax = orgPos.Max();
                orgPosMin = orgPos.Min();
                maxPosMax = maxPos.Min(); //In case they are on different splines.
                SceneView.duringSceneGui += DrawGUI;
            }
            else
            {
                SceneView.duringSceneGui -= DrawGUI;
            }
        }

        public static void DrawGUI(SceneView sceneview)
        {
            if (!EditorApplication.isPlaying)
            {
                if (cancel)
                {
                    cancel = false;
                }
                //Events must be before GUI, else inputs will be eaten.
                if (Event.current.rawType == EventType.MouseUp && Event.current.button == 1 && !cancel && endDrag) //Cancel move. MouseDown doesn't work, will not reset slider if you click while moving mouse.
                {
                    endDrag = false;
                    cancel = true;
                    slider = 0;
                    index = 0;

                    foreach (SplineController checkController in selectedItems)
                    {
                        if (checkController.Spline == null)
                        {
                            index++;
                            continue;
                        }
                        checkController.AbsolutePosition = orgPos[index];
                        maxPos[index] = checkController.Spline.Length;
                        index++;
                    }
                    orgPosMax = orgPos.Max(); //In case spline has changed.
                    orgPosMin = orgPos.Min();
                    maxPosMax = maxPos.Min();
                }

                else if (Event.current.rawType == EventType.MouseUp && Event.current.button == 0 && !cancel && endDrag) //Confirm move.
                {
                    endDrag = false;
                    cancel = true;
                    slider = 0;
                    index = 0;

                    foreach (SplineController checkController in selectedItems)
                    {
                        if (checkController.Spline == null)
                        {
                            index++;
                            continue;
                        }
                        orgPos[index] = checkController.AbsolutePosition;
                        maxPos[index] = checkController.Spline.Length;
                        index++;
                    }
                    orgPosMax = orgPos.Max();
                    orgPosMin = orgPos.Min();
                    maxPosMax = maxPos.Min();

                }
                GUI.BeginGroup(new Rect(Screen.width - 270, Screen.height - 80, 260, 35), "");
                GUI.backgroundColor = bgC;
                GUI.contentColor = Color.black;
                GUI.Box(boxW, "Offset Selected Controllers Position");
                clamp = GUI.Toggle(boxC, clamp, new GUIContent("", "Force Clamping? Always\non unless all controllers\nare set to Loop."));
                GUI.Label(boxT, GUI.tooltip);
                slider = GUI.HorizontalSlider(boxS, slider, -100, 100);
                GUI.Button(boxW, "", GUIStyle.none); //Prevents miss click.
                GUI.EndGroup();

                if (forceClamp && !clamp)
                {
                    clamp = true;
                }

                if (GUI.changed && !cancel)
                {
                    endDrag = true;
                    index = 0;
                    slider = Mathf.Floor(slider);
                    if (slider > 0 && slider + orgPosMax > maxPosMax - 1 && clamp)
                    {
                        offset = maxPosMax - orgPosMax - 1;
                    }
                    else if (slider < 0 && orgPosMin + slider < 1 && clamp)
                    {
                        offset = orgPosMin * -1 + 1;
                    }
                    else
                    {
                        offset = slider;
                    }
                    foreach (SplineController checkController in selectedItems)
                    {
                        if (checkController.Spline == null)
                        {
                            index++;
                            continue;
                        }
                        Undo.RecordObject(checkController, "Offset");
                        checkController.AbsolutePosition = orgPos[index] + offset;
                        index++;
                    }
                }
            }
        }
    }
}

Can I make a small suggestion to have something similar to this added to the official version? It's veeeeeeeeeeeeeery useful.
Reply
#24
I will assess these changes later. I will let you know if I think if this, or a similar solution, is needed in Curvy
Please consider leaving a review for Curvy. This will help a lot keeping Curvy relevant in the eyes of the Asset Store algorithm.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Distance travelled across multiple splines jh092 1 7 02-23-2024, 09:44 AM
Last Post: _Aka_
  Best practice for controllers slowing down/speeding up along the spline Curry 1 5 08-06-2023, 09:47 PM
Last Post: _Aka_
  Moving object down or up the spline using gravity velikizlivuk 6 16 07-26-2023, 10:06 PM
Last Post: _Aka_
  Multiple Splines and Generators Performantly for Road System drock 1 6 07-17-2023, 10:31 AM
Last Post: _Aka_

Forum Jump: