示例#1
0
    // Only called if action_idx has changed since last time
    void UpdateLoopList(LetterAnimation animation)
    {
        // add any new loops from the next action index to the loop list
        ActionLoopCycle loop;

        for (int idx = 0; idx < animation.NumLoops; idx++)
        {
            loop = animation.GetLoop(idx);

            if (loop.m_start_action_idx == m_anim_state_vars.m_action_index)
            {
                // add this new loop into the ordered active loop list
                int new_loop_cycle_span = loop.SpanWidth;

                int loop_idx = 0;
                foreach (ActionLoopCycle active_loop in m_anim_state_vars.m_active_loop_cycles)
                {
                    if (loop.m_start_action_idx == active_loop.m_start_action_idx && loop.m_end_action_idx == active_loop.m_end_action_idx)
                    {
                        // This loop is already in the active loop list, don't re-add
                        loop_idx = -1;
                        break;
                    }

                    if (new_loop_cycle_span < active_loop.SpanWidth)
                    {
                        break;
                    }

                    loop_idx++;
                }

                if (loop_idx >= 0)
                {
                    m_anim_state_vars.m_active_loop_cycles.Insert(loop_idx, loop.Clone());
                }
            }
        }
    }
    private void DrawLoopTree(LetterAnimation selected_animation)
    {
        if (font_manager.NumAnimations == 0)
            return;

        var main_editor_height = Instance.position.height - WINDOW_BORDER_TOP - WINDOW_BORDER_BOTTOM;
        var num_actions = selected_animation.NumActions;
        var gui_y_offset = WINDOW_BORDER_TOP;
        var action_idx = 0;

        gui_y_offset = WINDOW_BORDER_TOP;

        // Draw A's
        m_state_node_rects = new Rect[num_actions];

        EditorGUI.LabelField(new Rect(state_overview_x, gui_y_offset, 100, LINE_HEIGHT * 2), "Loops [" + selected_animation.NumLoops + "]", EditorStyles.boldLabel);
        gui_y_offset += LINE_HEIGHT * 2;

        if (GUI.Button(new Rect(state_overview_x, gui_y_offset, 60, LINE_HEIGHT), new GUIContent(m_display_loops_tree ? "Hide" : "Show", (m_display_loops_tree ? "Hide" : "Show") + " the loops setup menu.")))
            m_display_loops_tree = !m_display_loops_tree;
        gui_y_offset += LINE_HEIGHT * 2;

        LOOP_SCROLL_POS = GUI.BeginScrollView(new Rect(state_overview_x, gui_y_offset, MainEditorX - state_overview_x - 14, main_editor_height - (gui_y_offset - WINDOW_BORDER_TOP)), LOOP_SCROLL_POS, new Rect(0, 0, MainEditorX - 35, selected_animation.NumActions * ACTION_NODE_SPACING));

        gui_y_offset = 0;

        for (action_idx = 0; action_idx < selected_animation.NumActions; action_idx++)
        {
            GUI.Label(new Rect(20, gui_y_offset, 40, 20), "A" + action_idx, EditorStyles.boldLabel);

            if (m_display_loops_tree)
                m_state_node_rects[action_idx] = new Rect(20 - ACTION_NODE_MARGIN, gui_y_offset - ACTION_NODE_MARGIN, 20 + (2 * ACTION_NODE_MARGIN), 20 + (2 * ACTION_NODE_MARGIN));

            gui_y_offset += ACTION_NODE_SPACING;
        }

        if (m_display_loops_tree)
        {
            // Draw existing loops
            Vector2 point1, point2;

            // Draw Loop assignment-in-progress line, triggered by users click and drag on action nodes
            if (m_mouse_down_node_idx >= 0)
                DrawLine(m_mouse_down_pos, new Vector2(m_mouse_down_pos.x, m_mouse_drag_pos.y), Color.gray, 3);

            state_overview_width = 0;

            var num_loops = selected_animation.NumLoops;
            var my_style = EditorStyles.miniButton;
            my_style.alignment = TextAnchor.MiddleLeft;
            my_style.normal.textColor = Color.black;

            // Loop through loop list, drawing loop line representations on loop timeline and adding loop list entries
            float loops_list_x;
            ActionLoopCycle loop_cycle;
            var last_span_width = -1;
            var indent_num = 0;
            float line_offset_x = 0;
            float loop_list_line_y = 0;

            GUI.SetNextControlName("LoopsTitle");

            // Display loop list header
            EditorGUI.LabelField(new Rect(loop_tree_width + 60, loop_list_line_y, 100, LINE_HEIGHT), "Active Loops", EditorStyles.boldLabel);
            loop_list_line_y += LINE_HEIGHT;

            EditorGUI.LabelField(new Rect(loop_tree_width + 52, loop_list_line_y, 30, LINE_HEIGHT), new GUIContent("From", "The index of the action to start this loop."), EditorStyles.miniBoldLabel);
            EditorGUI.LabelField(new Rect(loop_tree_width + 87, loop_list_line_y, 20, LINE_HEIGHT), new GUIContent("To", "The index of the action to end this loop."), EditorStyles.miniBoldLabel);
            EditorGUI.LabelField(new Rect(loop_tree_width + 110, loop_list_line_y, 42, LINE_HEIGHT), new GUIContent("#Loops", "The number of times to run through this loop. Enter zero to run loop infinitely."), EditorStyles.miniBoldLabel);
            EditorGUI.LabelField(new Rect(loop_tree_width + 190, loop_list_line_y, 40, LINE_HEIGHT), new GUIContent("Type", "The type/behaviour of this loop."), EditorStyles.miniBoldLabel);
            EditorGUI.LabelField(new Rect(loop_tree_width + 262, loop_list_line_y, 70, LINE_HEIGHT), new GUIContent("DFO [?]", "'Delay First Only' - Letter action delays (non-constant) will only be applied for the first forward pass through the loop. This stops the letters getting more and more out of sequence with every loop interation."), EditorStyles.miniBoldLabel);
            loop_list_line_y += LINE_HEIGHT;

            for (var loop_idx = 0; loop_idx < num_loops; loop_idx++)
            {
                loop_cycle = selected_animation.GetLoop(loop_idx);

                if (last_span_width == -1)
                    last_span_width = loop_cycle.SpanWidth;

                // Check for invalid loops
                if (loop_cycle.m_start_action_idx >= num_actions || loop_cycle.m_end_action_idx >= num_actions)
                {
                    // invalid loop. Delete it.
                    selected_animation.RemoveLoop(loop_idx);
                    loop_idx--;
                    num_loops--;
                    continue;
                }

                // Represent loop as a line on the Action timeline
                if (last_span_width != loop_cycle.SpanWidth)
                {
                    last_span_width = loop_cycle.SpanWidth;
                    indent_num++;
                }

                line_offset_x = 20 + (indent_num * LOOP_LINE_OFFSET);

                if (loop_cycle.m_start_action_idx != loop_cycle.m_end_action_idx)
                {
                    point1 = m_state_node_rects[loop_cycle.m_start_action_idx].center + new Vector2(line_offset_x, 0);
                    point2 = m_state_node_rects[loop_cycle.m_end_action_idx].center + new Vector2(line_offset_x, 0);

                    DrawLine(point1, point2, loop_cycle.m_loop_type == LOOP_TYPE.LOOP ? LOOP_COLOUR : LOOP_REVERSE_COLOUR, 2);

                    DrawLine(point1 + new Vector2(0, -2), point1 + new Vector2(0, 2), loop_cycle.m_loop_type == LOOP_TYPE.LOOP ? LOOP_COLOUR : LOOP_REVERSE_COLOUR, 6);
                    DrawLine(point2 + new Vector2(0, -2), point2 + new Vector2(0, 2), loop_cycle.m_loop_type == LOOP_TYPE.LOOP ? LOOP_COLOUR : LOOP_REVERSE_COLOUR, 6);
                }
                else
                {
                    point1 = m_state_node_rects[loop_cycle.m_start_action_idx].center + new Vector2(line_offset_x, -2);
                    point2 = m_state_node_rects[loop_cycle.m_end_action_idx].center + new Vector2(line_offset_x, 2);

                    DrawLine(point1, point2, loop_cycle.m_loop_type == LOOP_TYPE.LOOP ? LOOP_COLOUR : LOOP_REVERSE_COLOUR, 6);
                }

                // Display loop number
                my_style.normal.textColor = loop_cycle.m_loop_type == LOOP_TYPE.LOOP ? LOOP_COLOUR : LOOP_REVERSE_COLOUR;
                EditorGUI.LabelField(new Rect(point1.x, (point1.y + point2.y) / 2 - 10, loop_cycle.m_number_of_loops > 9 ? 30 : 20, 20), loop_cycle.m_number_of_loops <= 0 ? "~" : "" + loop_cycle.m_number_of_loops, my_style); //EditorStyles.miniButton);

                // Display list view of loop cycle
                loops_list_x = loop_tree_width;
                EditorGUI.LabelField(new Rect(loops_list_x, loop_list_line_y, 100, LINE_HEIGHT), "Loop " + (loop_idx + 1));
                loops_list_x += 58;
                EditorGUI.LabelField(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), "" + loop_cycle.m_start_action_idx);
                loops_list_x += 30;
                EditorGUI.LabelField(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), "" + loop_cycle.m_end_action_idx);
                loops_list_x += 32;
                loop_cycle.m_number_of_loops = EditorGUI.IntField(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), loop_cycle.m_number_of_loops);
                loops_list_x += 30;
                loop_cycle.m_loop_type = (LOOP_TYPE)EditorGUI.EnumPopup(new Rect(loops_list_x, loop_list_line_y, 110, LINE_HEIGHT), loop_cycle.m_loop_type);
                loops_list_x += 130;
                loop_cycle.m_delay_first_only = EditorGUI.Toggle(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), loop_cycle.m_delay_first_only);
                loops_list_x += 30;
                if (GUI.Button(new Rect(loops_list_x, loop_list_line_y, 24, LINE_HEIGHT), "x"))
                {
                    selected_animation.RemoveLoop(loop_idx);
                    num_loops--;
                    continue;
                }

                loop_list_line_y += LINE_HEIGHT;
            }

            loop_list_line_y += 5;

            // "Add new loop" line
            loops_list_x = loop_tree_width;
            EditorGUI.LabelField(new Rect(loops_list_x, loop_list_line_y, 100, LINE_HEIGHT), "New", EditorStyles.boldLabel);
            loops_list_x += 58;
            new_loop_from = EditorGUI.IntField(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), new_loop_from);
            loops_list_x += 30;
            new_loop_to = EditorGUI.IntField(new Rect(loops_list_x, loop_list_line_y, 20, LINE_HEIGHT), new_loop_to);
            loops_list_x += 32;
            if (GUI.Button(new Rect(loops_list_x, loop_list_line_y, 40, LINE_HEIGHT), "Add"))
            {
                selected_animation.AddLoop(new_loop_from, new_loop_to, false);
                font_manager.PrepareAnimationData();

                new_loop_from = 0;
                new_loop_to = 0;

                // Force keyboard focus loss from any of the loop adding fields.
                GUI.FocusControl("LoopsTitle");
            }

            // Set the width of the loop tree segment
            loop_tree_width = (int)line_offset_x + BASE_LOOP_LIST_POSITION_OFFSET;

            // Add additional width of loop list menu
            state_overview_width = loop_tree_width + LOOP_LIST_WIDTH;

            var eventType = Event.current.type;
            var mousePos = Event.current.mousePosition;

            if (eventType == EventType.MouseDown && mousePos.x < MainEditorX)
            {
                var rect_idx = 0;
                foreach (var node_rect in m_state_node_rects)
                {
                    if (node_rect.Contains(mousePos))
                    {
                        m_mouse_down_node_idx = rect_idx;
                        m_mouse_down_pos = node_rect.center;
                        m_mouse_drag_pos = m_mouse_down_pos;
                    }

                    rect_idx ++;
                }
            }
            else if (eventType == EventType.MouseDrag)
            {
                if (m_mouse_down_node_idx >= 0)
                {
                    m_mouse_drag_pos = mousePos;

                    Instance.Repaint();
                }
            }
            else if (eventType == EventType.MouseUp)
            {
                if (m_mouse_down_node_idx >= 0 && mousePos.x < MainEditorX)
                {
                    var rect_idx = 0;
                    foreach (var node_rect in m_state_node_rects)
                    {
                        if (node_rect.Contains(mousePos))
                        {
        //							Debug.LogError("you joined : " + m_mouse_down_node_idx + " and " + rect_idx + " with button " + Event.current.button);

                            int start, end;
                            if (m_mouse_down_node_idx < rect_idx)
                            {
                                start = m_mouse_down_node_idx;
                                end = rect_idx;
                            }
                            else
                            {
                                start = rect_idx;
                                end = m_mouse_down_node_idx;
                            }

                            selected_animation.AddLoop(start, end, Event.current.button == 1);
                            font_manager.PrepareAnimationData();

                            break;
                        }

                        rect_idx ++;
                    }
                }

                m_mouse_down_node_idx = -1;
                Instance.Repaint();
            }
        }
        else
            state_overview_width = 0;

        GUI.EndScrollView();
    }
示例#3
0
    // Only called if action_idx has changed since last time
    private void UpdateLoopList(LetterAnimation animation)
    {
        // add any new loops from the next action index to the loop list
        ActionLoopCycle loop;
        for (var idx = 0; idx < animation.NumLoops; idx++)
        {
            loop = animation.GetLoop(idx);

            if (loop.m_start_action_idx == m_anim_state_vars.m_action_index)
            {
                // add this new loop into the ordered active loop list
                var new_loop_cycle_span = loop.SpanWidth;

                var loop_idx = 0;
                foreach (var active_loop in m_anim_state_vars.m_active_loop_cycles)
                {
                    if (loop.m_start_action_idx == active_loop.m_start_action_idx && loop.m_end_action_idx == active_loop.m_end_action_idx)
                    {
                        // This loop is already in the active loop list, don't re-add
                        loop_idx = -1;
                        break;
                    }

                    if (new_loop_cycle_span < active_loop.SpanWidth)
                        break;

                    loop_idx++;
                }

                if (loop_idx >= 0)
                    m_anim_state_vars.m_active_loop_cycles.Insert(loop_idx, loop.Clone());
            }
        }
    }
    public static int ImportLegacyData(this LetterAnimation letter_anim, List <object> data_list, int index_offset = 0)
    {
        KeyValuePair <string, string> value_pair;
        string key, value;
        int    idx;
        int    loop_idx = 0, action_idx = 0;

        for (idx = index_offset; idx < data_list.Count; idx++)
        {
            value_pair = (KeyValuePair <string, string>)data_list[idx];
            key        = value_pair.Key;
            value      = value_pair.Value;

            if (key.Equals("ANIM_DATA_END"))
            {
                // reached end of this animations import data
                break;
            }

            switch (key)
            {
            case "m_letters_to_animate":
                List <object> letter_list = value.StringToList(';');
                letter_anim.m_letters_to_animate = new List <int>();
                if (letter_list != null)
                {
                    foreach (object obj in letter_list)
                    {
                        letter_anim.m_letters_to_animate.Add(int.Parse(obj.ToString()));
                    }
                }
                break;

            case "m_letters_to_animate_custom_idx":
                letter_anim.m_letters_to_animate_custom_idx = int.Parse(value); break;

            case "m_letters_to_animate_option":
                letter_anim.m_letters_to_animate_option = (LETTERS_TO_ANIMATE)int.Parse(value); break;


            // LOOP DATA IMPORT
            case "LOOP_DATA_START":
                if (loop_idx == letter_anim.NumLoops)
                {
                    letter_anim.AddLoop();
                }
                break;

            case "LOOP_DATA_END":
                loop_idx++; break;

            case "m_delay_first_only":
                letter_anim.GetLoop(loop_idx).m_delay_first_only = bool.Parse(value); break;

            case "m_end_action_idx":
                letter_anim.GetLoop(loop_idx).m_end_action_idx = int.Parse(value); break;

            case "m_loop_type":
                letter_anim.GetLoop(loop_idx).m_loop_type = (LOOP_TYPE)int.Parse(value); break;

            case "m_number_of_loops":
                letter_anim.GetLoop(loop_idx).m_number_of_loops = int.Parse(value); break;

            case "m_start_action_idx":
                letter_anim.GetLoop(loop_idx).m_start_action_idx = int.Parse(value); break;


            // ACTION DATA IMPORT
            case "ACTION_DATA_START":
                if (action_idx == letter_anim.NumActions)
                {
                    letter_anim.AddAction();
                }
                idx = letter_anim.GetAction(action_idx).ImportLegacyData(data_list, idx + 1);
                action_idx++;
                break;
            }
        }

        // Remove any extra LoopData or LetterAction instances that existed prior to importing
        if (letter_anim.NumLoops > loop_idx)
        {
            letter_anim.RemoveLoops(loop_idx, letter_anim.NumLoops - loop_idx);
        }

        if (letter_anim.NumActions > action_idx)
        {
            letter_anim.RemoveActions(action_idx, letter_anim.NumActions - action_idx);
        }

        return(idx);
    }