Group layer Depth Sort: Sort layers by Y-Position
Moderators: Víctor Paredes, Belgarath, slowtiger
Re: Group layer Depth Sort: Sort layers by Y-Position
Thank you! It means a lot coming from some of the people I've learnt from (:
- gilcartunista
- Posts: 55
- Joined: Mon Mar 14, 2016 7:13 pm
- Location: https://www.facebook.com/gil.cartunista
- Contact:
Re: Group layer Depth Sort: Sort layers by Y-Position
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
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.
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
Oh nice! Thanks SimplSamhayasidist wrote: ↑Sun Feb 07, 2021 11:06 amI think SimplSam has cracked the "attempt to call method 'Layer' (a nil value)" issue .. http://www.lostmarble.com/forum/viewtop ... 12&t=33764

Nice work Daxel, that's an interesting way of using the script
- lucasfranca
- Posts: 180
- Joined: Sat Oct 07, 2017 11:47 pm
Re: Group layer Depth Sort: Sort layers by Y-Position
Oh my God, I didn't know I needed this until I met**
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.
I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.
https://youtube.com/animai2D
Passionate about animation, after getting old, he decides to make it his hobby.
I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.
https://youtube.com/animai2D
- lucasfranca
- Posts: 180
- Joined: Sat Oct 07, 2017 11:47 pm
Re: Group layer Depth Sort: Sort layers by Y-Position
Eagerly waiting for update to Mh 14.2.
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.
I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.
https://youtube.com/animai2D
Passionate about animation, after getting old, he decides to make it his hobby.
I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.
https://youtube.com/animai2D
Re: Group layer Depth Sort: Sort layers by Y-Position
Thank you Lukas! Two thumbs up. You really help improving moho workflows and solving production problems.
- bibendumchamalow
- Posts: 24
- Joined: Mon Jul 05, 2021 9:15 pm
Re: Group layer Depth Sort: Sort layers by Y-Position
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





