Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Bug?] Changes to RectTransform of base prefab aren't propagated variant

Discussion in 'Prefabs' started by StephanieRowlinson, Jul 25, 2018.

  1. StephanieRowlinson

    StephanieRowlinson

    Joined:
    Jul 23, 2014
    Posts:
    137
    I'm exploring the possibilities of creating UI's with new Improved Prefabs and so I've made 2 buttons, BasicButton and a variant RedButton. However when I change the size of BasicButton, the RectTransform of RedButton remains unaffected. Similarly changes to the size of RedButton don't show up as overrides, whereas the colour change does.

    I placed a cube, created a variant of it and changed the sizes there. These do propagate from the base to the variant and show up as overrides. Is this intended behaviour for RectTransforms or should I submit a bug report? If it is intended, this is super annoying and really puts a damper on my ability to use the new system for a UI framework.
     
    BazookasZerreth and JesOb like this.
  2. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Hi,

    Some properties on Prefab instances to not inherit changes from the Prefab Asset they derive from. This is described here (section "Alignment is specific to Prefab instance"):
    https://docs.google.com/document/d/...3gUrvo5x3EXi9AGbw/edit#heading=h.hq5our40rul5

    This is not a new behaviour; it's been that way for Prefab instances always, but it does have some new implications for Prefab Variants. Since the base of a Prefab Variant is a Prefab instance, the base work the same way: alignment is specific to the instance (inside the Variant) so doesn't receive changes from the base Prefab Asset.

    As such, it's not a bug per se, but we'll take up for consideration if the behaviour for base Prefab instances inside Variants should work in a different way than Prefab instances normally do in order to address issues like the one you're seeing.
     
    philipecarter likes this.
  3. StephanieRowlinson

    StephanieRowlinson

    Joined:
    Jul 23, 2014
    Posts:
    137
    Thanks for the answer and link to the manual, I couldn't find it yesterday. ^^;

    I understand position being independent, but it's kind of annoying to have to resize all those buttons. It'd be nice to have the ability to adjust height and width in the base and have variants react like they do to scale changes with a regular Transform.
     
  4. BazookasZerreth

    BazookasZerreth

    Joined:
    Dec 8, 2016
    Posts:
    17
    As it is indeed related to this topic I'll continue here:

    ISSUE 1 (Design Issue?)
    Steps to reproduce:
    1) Create a prefab with a RectTransform, (e.g. in a canvas) with 100x100 size.
    2) Now change that prefab size in the scene to 200x200.
    3) Go into the prefab (prefab edit mode) and change it to 300x300. The instance in the scene won't have these changes replicated as these properties are not inherited (thus forcing you to re-instantiating the prefab) and there is no revert button for these properties either.

    In the system of olde, this made sense, as it was extremely easy to unintentionally revert values or make overrides.
    In the new system, it;s blatantly obvious that you're doing overrides, and you can easily revert each property. You can even easily replicate the old functionality by having the transform property be overridden by default when placing into a scene and having the "revert all" button revert everything but the transform. But still have the option to manually revert when needed. Making everybody happy.

    In other words, why would you ever exempt the Transform/RecTransform from inheritance/override in the new system ? The only thing it does is break usability of the new workflows. As SRowlinson pointed out, this breaks workflows for creating UI. We have a 2D Character creator setup and it makes for all sorts of problems. We end up having a custom transform script attached to the prefab just so the values can be replicated to its variants.

    ISSUE 2 (Legitimate Bug)
    Steps to reproduce:
    1) Continue on from the previous example with a prefab instance in the scene (200x200) having a different size than its source prefab (300x300).
    2) Create a prefab Variant from that instance.
    3) Now enter prefab edit mode on that variant and set the size to 400x400.
    4) Save & Exit prefab edit mode and instantiate an object from that variant. The size reads (300x300) ?????
    5) Re-Enter edit mode on the variant and you'll see that it is magically stuck on 300x300, aka the size it had when the variant was originally created.
     
    StephanieRowlinson likes this.
  5. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Let's discuss this idea.

    Let's say Apply All and Revert All will apply/revert everything except the root transform, but you can explicitly apply or revert the root transform by itself or any single property on it. Apply will make the Prefab Asset values match the Prefab instance and revert will make the Prefab instance values match the Prefab Asset.

    Now, after having done such an explicit apply or revert on the root Transform, would you want the root Transform to
    A) receive updates automatically from the Prefab Asset (like any regular non-overridden property)?
    B) behave as having overridden properties still, so it won't receive automatic updates but can still be reverted in the future to sync manually with the Prefab Asset?

    You need A) if you want to e.g. make size changes to a Rect Transform and have it automatically affect all instances in the scene. But A) will also mean that if you apply the root Transform of an instance, and later apply the root Transform of another instance, the first instance will move to the position of the second. It will be very easy to shoot yourself in the foot with this, when it is no longer guaranteed that instances always keep their own alignment.

    I suppose a third option - let's say C) - could be the same as A) but not have any way to apply or revert the whole root Transform component - only individual properties on it. This way people would only get into the situation where Prefab instances get their positions moved around based on the Asset if they explicitly applied or reverted the Position.
     
  6. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Thanks good catch. It looks like any default override properties in Variants don't get saved, which is quite serious. We're on it.
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    For non-RectTransform prefab instances, the rules for the transform properties seems to be pretty simple:
    - ignore the prefab's .localPosition
    - ignore the prefab's .localRotation
    - apply the prefab's .localScale.

    That makes a lot of sense. Position and rotation are very individual values, and pretty much every prefab instance will have their own values for those. If that wasn't the rule, the problem you're describing in A) would be the case for all prefab instances, and the Apply button would teleport every prefab that was previously applied to the same position. Bad stuff.

    Now, for RectTransforms, it seems like all the values (anchorMin, anchorMax, anchoredPosition, sizeDelta, pivot) have the same rules as .localPosition and .localRotation; ignore the prefab's values.

    I think you'd achieve what @BazookasZerreth and @SRowlinson is asking for if .sizeDelta followed the same rules as .localScale. You'd also dodge the issue you're describing, as the position is based on anchoredPosition.

    This would of course be a breaking change, but probably a good one, as it'd make it possible to scale UI prefabs. Before prefab nesting, complex UI prefab setups wasn't that big of a deal, so I don't think it's a too hard change to work around.
     
  8. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    I was discussing the proposal from BazookasZerreth, which was to no longer exempt Transform/RectTransform from inheritance/overrides. Your proposal is different from his so let's keep these things separate.

    For UI elements without stretching, this does make sense, but RectTransform does support stretching, and for stretching elements, position and size is intertwined (and even connected with AnchorMin/AnchorMax too). Thus, having position be unique per instance but still inherit changes to sizeDelta (the underlying property which controls size) can give results that are hard to predict and often undesirable.

    Thus, simply using the same solution as today but with a smaller set of properties that don't include sizeDelta is not a viable solution.
     
  9. StephanieRowlinson

    StephanieRowlinson

    Joined:
    Jul 23, 2014
    Posts:
    137
    As a long time WPF user I do get where you're coming from. I also don't think this is a big problem though, as long as the documentation makes it clear which element takes precedent over others in determining the eventual size of the GUI element. And there's a way of debugging/seeing which element is influencing which, perhaps overrides could be used for this?

    I realise this is turning into a big feature request and not something that everyone will need. I'm personally dealing with a use case that has a large and complex GUI, so the ability to change a lot of elements in one go would be great to have. And luckily the new prefabs already provide a lot of options for this. :)
     
  10. BazookasZerreth

    BazookasZerreth

    Joined:
    Dec 8, 2016
    Posts:
    17
    Sorry for the late reply, we're nearing a release deadline and I haven't been checking the forums as much.

    Option A would indeed lead to unintentional property changes, so I wouldn't do that. BUT at the same time there are use cases where you would want it to work like that.

    What we're essentially talking about here is toggling automatic updates on the prefab transform. Usually when reverting you want it to receive updates from the original prefab, but in this case you want to have the option to just revert the property values, but not receive updates. Maybe have 3 options in the right click menu:
    • "Revert Values and Link" //Old school revert
    • "Override & Unlink" //Changing a property, aka Override
    • "Revert Values" //Reverting values without changing the "linking" aka update subscription to the original prefab.
    Because right now, you can only "override and unlink" it by changing the property to something else and changing it back again. (to avoid unintentional overrides I presume)

    So this is something that makes sense as well, As you would like to have control over the scale, rotation, position, essentially any property overrides separately just like any other component. If I want to revert just the rotation, I should have that option to do so. So yes, absolutely. You can put in the extra safety net of not allowing you to revert the whole transform property at once as you suggested.

    You're still leaving yourself open for unintentional property changes here with option C, but together with the explicit linking and unlinking I proposed it should be very obvious what you're doing, minimizing the risk.
     
    Last edited: Aug 22, 2018
  11. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Considering option C) without the unlinking suggestion, what would be examples of use cases where you'd easily shoot yourself in the foot?

    I guess I'm not clear on when you'd want to revert to Prefab's value for some properly but not want to receive future updates from the Prefab after that. In my mind, not accidentally reverting e.g. position or rotation just because you wanted to revert e.g. scale is the critical thing; I'd like to understand your point better.
     
  12. BazookasZerreth

    BazookasZerreth

    Joined:
    Dec 8, 2016
    Posts:
    17
    in option C)
    1) let's say I place a prefab instance in a scene and want its position as an override:
    the position property is automatically marked as override when placing it in the scene
    2) I want it to update with the prefab again so I revert the position value
    3) For some reason I want the property to be an override again:
    I want it to override the instance property and thus not update with the prefab but the value I want the override to be matches the one in the prefab, so it isn't marked as an override. (to avoid unintentional overrides I presume)
    So I'm forced to change it to a different value and back again to register it as an override as a workaround for not having a "override" right click option. (this rings true for all properties on all components)

    Usecase 1)
    The usecase is mostly as a level designer you want to place prefab instances in the scene. Let's say I absolutely know that a property should be some value and at that time that value matches the value set in the prefab. Then it won't be marked as an override except if I explicitly change it's value and back again.

    Down the line someone decides that the default value of that property (as set in the prefab) should be something else.
    All instances everywhere will update and everything not marked as an override would change with it, potentially leading to unintended changes if the level designer didn't do the workaround to make sure that the property was overridden.

    Usecase 2)
    Prefabs can also serve as containers for the default values of the variants. Every local scene override or variant would then like the option to "revert the property values" without it losing the override.
     
  13. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Thanks for the input. From your description it sounds like the ability to "revert but keep overridden" might be equally useful for any property override and is not particularly specific to root Transform properties? E.g. is there any reason why a designer would want e.g. the scale of an object to match the scale in the Prefab at a specific time and not going forward, but not equally want the color/speed/whatever to match the Prefab at a specific time but not going forward? It's this question of why you find it specifically important for properties on root Transform that is unclear to me and why you think you might *more* shoot yourself in the foot without this feature for root Transform properties than for other properties in a Prefab?
     
  14. BazookasZerreth

    BazookasZerreth

    Joined:
    Dec 8, 2016
    Posts:
    17
    Well you might be happy with a dark color of tree in a scene and want to keep it that certain shade. A few months from now the decision could be made that going forward the default shade of green for the tree prefab will be lighter, thereby possibly destroying the careful work a designer put into creating & lighting a scene to look a certain way.

    Now the argument could be made that those changes should have been stored in a variant. But the reality is that by changing the values in the original prefab all those trees that were meant to originally have a darker shade will now be lighter. And someone now has to create a darker variant and replace all those currently in the scene. So effectively "broken until replaced".

    If the designer had the option to mark that color property as an override ("revert but keep overridden") then everything would be fine and dandy. And everybody would be safe to change anything they wanted. Leaving the designer to make that decision to override or not. So resulting in: "working but it should be replaced down the line".

    I try to set up workflows where we can work iteratively on something without having to go back to fix things every time we change something in a prefab. The argument could be made that a good practice would be to create a variant preemptively in that case, but I think that you'll end up having lots and lots of useless variants in that case if we don't end up changing things down the line.

    The same goes for any transform property as would for any other property.

    Well if everything works like option C) and there is an extra "revert but keep overridden", and you now have control over all the transform properties separately like any other component then we'll have everything we wanted and would fix all issues in all the examples above. Not allowing the revert on the entire transform component, but allowing it on the separate transform properties is something I'll leave up to you as it is just an extra safety net.

    If you're asking why you would allow it on the root transform:

    It's to allow 2D workflows like creating a UI library or 2D Character customization to work without having to store the recttransform values in a custom script and initializing the transform with those values via "execute in editor" or custom editorinspector. (effectively a workaround)

    And 3D workflows like having a object oriented in a certain way and you want every instance of it to have that orientation. Giving us the control over this and only overriding it when you choose to. (default overrides when placing a prefab/variant in your scene would be an extra safety net) Something that could be achieved via script but why would you have to do it when everything else works the same way.
     
  15. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Right, you're arguing that "revert but keep overridden" is good to have for properties in general; not just root Transform.

    My point here is that we prefer not to conflate different issues. One question is if we should let properties in general have a "revert but keep overridden" option; another question is if we should let root Transform work like regular properties (but not allow reverting or applying entire component at once, for safety).

    For the "revert but keep overridden" idea, you're the only one so far who have requested this, so we're unlikely to prioritize this for the moment. Whereas being able to get updates to properties in root Transforms from Prefabs has been a recurring request from many users, which we are more likely to prioritize.

    This is why, if there is a reason why "revert but keep overridden" is *specifically* important in relation to treating root Transform properties like any other properties, then we'd like to be aware of that, but if it's just a general request which would be nice to have for properties in general, then it's not directly related as such, and we would like to keep the discussion focused on issues directly related to root Transforms.
     
  16. BazookasZerreth

    BazookasZerreth

    Joined:
    Dec 8, 2016
    Posts:
    17
    Alright gotcha, np I'll make a separate request for that one then with some good examples. :)
     
    runevision likes this.
  17. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    SugoiDev likes this.
  18. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    SRowlinson, BazookasZerreth and Baste, would it be possible for you to check out the build (see previous message) and see how it works for you?

    We'd like to address the issues you've discussed in this thread, but we can't move forward with changing this behavior without confidence that it's the right thing to do.
     
    StephanieRowlinson likes this.
  19. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    I'm looking at some quite busy days right ahead of me. I'll try to check it out by tomorrow, but no promises.
    By the way, it seems like you've set it so it's not possible to PM you in the forums. Is that intentional?
     
    runevision likes this.
  20. runevision

    runevision

    Joined:
    Nov 28, 2007
    Posts:
    1,892
    Thanks, I hope it'll be possible. :)

    Yeah, there was much too much noise when it was enabled to work out for me. People would 1) ask me random support questions I didn't know about which would be better asked in the forum, and 2) ask me things where the reply would benefit others as well so would be better to post publicly and ping me if necessary. My job is not to provide private one-on-one support and that is how many people were using it.