Page 3 of 3

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Mon Feb 08, 2021 1:11 pm
by Daxel
Thank you! It means a lot coming from some of the people I've learnt from (:

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Mon Feb 08, 2021 5:24 pm
by gilcartunista
Dear Daxel, it would be possible to post an example file, as I still can't understand ... thank you.

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Mon Feb 08, 2021 7:36 pm
by Daxel
I'm not allowed to share this rig, but It will be more useful to explain it. I don't know how much experiece you have but I will try to explain for begginers, so they can benefit. If you don't have experience with smartbones, then start learning that first, and come here later. This is a more advanced technique that makes use of them.

How to download and install the script

This layer sorting system is only possible thanks to LK_SortByZScaleSSamFix, a script made by Lukas and fixed by SimplSam that I uploaded here: https://1drv.ms/u/s!AiyKCw6Xey5TgZR_AfevEDlXwQQBVw

There are different types of scripts, but this one is a layer script that is only activated this way: open a layer's settings and, at the bottom of the General tab, you have the option to use an embbeded script. Select this script, press apply, and that's it.


Function of this script

It sorts the layers by their Z scale value, a number that you can see, edit or keyframe selecting one layer and then the Layer Transform Tool. The Z scale value doesn't have a purpose for 2D and that's why Lukas decided to use it to control the layer order with this script.
You don't need to activate the script on all the layers. You activate it on a parent layer like a group or a bone layer, and all its children layers are automatically sorted by their Z scale value, so the layers that have a higher Z scale value will be seen on top, and you can keyframe their Z scale value at any given time to change the layer's order.


Controlling the Z scale value with smartbones

Now that you have a parent layer with the script activated, the layer order of its children layers will depend on their respective Z value, that you can manually change with the Transform Layer Tool, but as you probably know, you can also control almost any keyframeable value with a smartbone. So the idea is to have a bunch of smarbones that are set to control the Z values (and therefore the order) of each layer just rotating the smartbone at any given time. It helps to make them horizontally, and that the layer's Z scale value is set higher the higher the smartbone is pointing. This will make easier to visually understand and control them, but there will be moments where you have too many layers and it will be harder to see wich smartbones are pointing higher or lower, and wich layers correspond to each of those smartbones, and that's why I made the HalfMoon System, just to make it easier to see and control.


The HalfMoon System

The trick is to use target bones. Any bone can be set to be a target bone of another particular bone, and then this particular bone will always automatically be pointing at the target bone.
We will create a pin bone, and then select one of those smartbones we created to control the Z scale of some layer, and open the Bone Constraints panel, look for the Target option and select the pin bone that you want to set as the target. From now on, the smartbone will always automatically point to the target bone, so now you can control the layer order moving that pin bone up and down. If you arrange the smartbones and the target pin bones like in this photo, you can always see, understand and control the layer order in a second.
To differenciate between these Z scale controlling smartbones and smartactions and the ones controlling the actual body parts positions, I named them Z ______. For example: Z Arm Left for the smartbone, always the same name for its smartaction, and Arm Left Z for its target pin bone. That's just a tip to make your life easier.


I will keep experimenting with this system, and it may have perks or limitations that I still haven't noticed, and this could probably be improved so any suggestions are welcomed.
One little annoyance that it has is that when you change the Z scale vale on, lets say, the frame 24, it needs another frame to process the change and sort the layers, so the order will actually change on the frame 25. Once you know this, you can just remember to make the keyframe one frame before you need the change. If someone knows how to modify the script to make the change on the same frame, that would be nice. And of course if Victor and Mike are reading this, as you already know, layer sorting is one of the things that give us more work and headaches, so any improvement on this area would be amazing.

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Tue Feb 09, 2021 8:52 am
by Lukas
hayasidist wrote: Sun Feb 07, 2021 11:06 am
Lukas wrote: Tue Jun 23, 2020 9:08 am
Daxel wrote: Sat May 23, 2020 2:22 amI'm using your script and it is amazingly useful, but I keep getting this error "LK_sortByZScale.lua:20: attempt to call method 'Layer' (a nil value)" very often.
'''
Sorry, I don't have any time to look into it, but I'll try and remember to check it out some other time.
I think SimplSam has cracked the "attempt to call method 'Layer' (a nil value)" issue .. http://www.lostmarble.com/forum/viewtop ... 12&t=33764
Oh nice! Thanks SimplSam :)

Nice work Daxel, that's an interesting way of using the script

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Mon Aug 05, 2024 2:31 pm
by lucasfranca
Oh my God, I didn't know I needed this until I met**

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Mon Aug 05, 2024 4:11 pm
by lucasfranca
Eagerly waiting for update to Mh 14.2.

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Tue Aug 06, 2024 12:23 pm
by Lae82
Thank you Lukas! Two thumbs up. You really help improving moho workflows and solving production problems.

Re: Group layer Depth Sort: Sort layers by Y-Position

Posted: Tue Aug 13, 2024 5:33 pm
by bibendumchamalow
ImageHi everyone, I'd like to share my research inspired by the scripts "LK_SortByYPos" and "LK_SortByZScale" by Lukas Krepel.

To simplify and expand upon these concepts, I've developed a script that utilizes a tagging system within the names of group layers or bone layers. The goal is to automatically organize child layers based on their positions along the X, Y, Z axes, or by their ZScale (where larger scales bring the layer to the foreground and smaller scales push it to the background).

To use this script, simply load the AC_SortByTag.lua script through the embedded script options in a group or bone layer. This script dynamically and automatically organizes the order of layers according to different modes (X, Y, Z, ZScale) based on the tags in the layer's name.

You can rename the group layer as you wish, but it must include one of the following tags: "_X", "_Y", "_Z", or "_ZScale". Additionally, you can add a "_Reverse" tag to any of these to invert the sorting order, regardless of the mode. For example, renaming a layer to "LayerName_ZScale_Reverse" will sort the layers by ZScale in reverse order.

Code: Select all

-- **************************************************
-- Script Name: AC_SortByTag.lua
-- Original Script: "LK_SortByYPos" and "LK_SortByZScale" by Lukas Krepel
-- Modified and Extended by: Alexandre Cousin
-- Assistance Provided by: ChatGPT
-- Description: This script allows sorting of child layers within a group or bone layer based on X, Y, Z position, or Z scale, determined by a tag in the group's name or a preset mode. It can also reverse the order if a '_Reverse' tag is present.
-- **************************************************

function LayerScript(moho)
    -- Check the layer type
    if (moho.layer:LayerType() == MOHO.LT_GROUP or moho.layer:LayerType() == MOHO.LT_BONE) then
        local thisLayer = moho:LayerAsGroup(moho.layer)
        thisLayer:EnableLayerOrdering(true)
        local order = {}
        local layerOrderChan = thisLayer:GetLayerOrdering()

        -- Sorting mode - default is ZScale, or determined by a tag in the layer's name
        local sortMode = "ZScale"
        local layerName = moho.layer:Name()

        -- Conflict resolution: check for ZScale before Z
        if string.find(layerName, "_ZScale") then
            sortMode = "ZScale"
        elseif string.find(layerName, "_X") then
            sortMode = "X"
        elseif string.find(layerName, "_Y") then
            sortMode = "Y"
        elseif string.find(layerName, "_Z") then
            sortMode = "Z"
        end

        -- Check if reverse order is needed
        local reverseOrder = false
        if string.find(layerName, "_Reverse") then
            reverseOrder = true
        end

        for i = thisLayer:CountLayers() - 1, 0, -1 do
            local layer = thisLayer:Layer(i)
            local sortValue = 0

            -- Choose the sorting value based on the selected mode
            if sortMode == "X" then
                sortValue = layer.fTranslation.value.x
            elseif sortMode == "Y" then
                sortValue = layer.fTranslation.value.y
            elseif sortMode == "Z" then
                sortValue = layer.fTranslation.value.z
            elseif sortMode == "ZScale" then
                sortValue = layer.fScale.value.z
            end

            table.insert(order, {i, sortValue})
        end

        -- Sort the layers based on the selected value, with optional reverse
        table.sort(order,
            function(a, b)
                if reverseOrder then
                    return (a[2] > b[2])
                else
                    return (a[2] < b[2])
                end
            end)

        -- Apply the new layer order
        local newOrder = ""
        for i, v in ipairs(order) do
            newOrder = newOrder .. thisLayer:Layer(v[1]):UUID() .. "|"
        end
        layerOrderChan:SetValue(0, newOrder)
        order = nil
    else
        print("''AC_SortByTag.lua'' should only be embedded into group or bone layers, ''" .. moho.layer:Name() .. "'' is not a group or bone layer.")
    end
end
Image
Image
Image
Image
Image
Image