Copy link to clipboard
Copied
Hi all,
I've got a script I'm working on that in part applies a pretty complex expression to various expression-able properties and one thing I'm looking to do it make it user-proof. In that I mean if I reference a layer in an expression via the layer name...what if the user changes the layer name? Expressions aren't auto-updating to my knowledge... If I reference the layer by index, what if the user moves it?
Right now my best thought is to use a Layer Control because that tracks both layer position and name changes. The one drawback is that it's user editable. In my case, that value needs to never change.
My question is two-fold: 1) Is there a way to make a Layer Control uneditable to the user? 2) If not, does anyone know of any other way to track a layer in an expression except by index or name?
I know it's a little excessive but I just like to go the extra effort to design my stuff so the user can't make little mistakes and it still works. As long as it's reasonably within my ability to do...I like to do it and avoid having a "You broke it, you own it." policy.
THANKS!
Calvin
Copy link to clipboard
Copied
Layer names in expressions auto-update, if the layer name is clearly visible in the program code
thisComp.layer("my layer name").transform.position
will automatically be changed if the layer name changes.
thisComp.layer("my la"+"yer name").transform.position
Will not auto-update.
Copy link to clipboard
Copied
what if the user changes the layer name? Expressions aren't auto-updating to my knowledge...
They are. There are however conditions when it doesn't, which takes us to Mathias comment:
Layer names in expressions auto-update, if the layer name is clearly visible in the program code
Not entirely true. They only update when they are
References to effects constructed e.g. from string operations or using eval() to find the right object will not work. Conversely, expressions may not update content in try()catch() because obviously one of the conditions is always met. In addition, even if none of the previous is an issue, the reference may not update, if based on the current condition it is not involved in the evaluation. This can happen when you use complex conditionals and loops with flow operators like break; in them. And finally, the name may not update if the code is written sloppily, not closing the reference with a semicolon or writing separate reference on a new line for each. Additionally addressing pop-up controls and certain text layer/ shape layer stuff can cause trouble and break connections. So it's not all that simple, though of course for the typical three-line expressions it should not be an issue. It only becomes critical on more complex projects.
Mylenium
Copy link to clipboard
Copied
To add to Mylenium list, expressions won't be updated if the names are set in between single quotes:
L = thisComp.layer("Controller"); // name will be updated
L = thisComp.layer('Controller'); // won't be updated --> expression error if renamed
Xavier.
Copy link to clipboard
Copied
This is great guys!
It has been my experience that names don't auto update so it's nice to know they potentially can work. I am doing a pretty complex expression with variables and control structures so maybe that's what's throwing it off. I'm pretty strict about syntax...so I generally don't forget semi-colon's or write code sloppily.
As far as "writing separate reference on a new line for each", are you saying storing data in variables and a new line for each might affect the name auto-update? Is it a good practice to make expressions as few lines as possible? I break things out into variable because it makes the expression that much more readable and understandable even though it makes the expression "longer."
However, it still brings up the issue of a) times when the name doesn't auto update and b) time when the user renames the layer to a name already used by another layer. I'd like to make this as bulletproof as possible.
Also, any thoughts on making an expression control uneditable? Probably not possible since it's not in the documentation but I've found you can do some pretty interesting things if you get creative...
Copy link to clipboard
Copied
Defining functions and variables rarely makes sense for expressions. This is a strict line-by-line interpreter and in fact defining such stuff may bring you back to the point I already mentioned: If a specific function is not part of the current evaluation loop, its content won't be traced and thus references contained inside it not updated. Therefore it's usually more important to have any operations in the actual order they are meant to process inside the expression. This will also help with keeping the evaluation going since it forces the engine to comb through the entire code block rather than just jumping from breakpoint to breakpoint as it would with containerized functions and variables.
Writing line by line is meant to refer to the actual external effect references mostly. Strangely enough sometimes AE messes up if multiple effect references are on the same line and then retrieves wrong values. Otherwise there is no way to bullet-proof layer references just based on their name. It's simply how AE works. If you want to check integrity, you have to apply something extra to the layer which you can check, e.g. a dummy effect that has a specific name and who generates a fixed value based on its own internal expression, but even that can of course be manipulated and break down.
Mylenium