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

[RELEASED] Module Generator

Discussion in 'Assets and Asset Store' started by Sidema, Sep 29, 2016.

  1. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Module Generator

    Asset Store link
    Documentation

    Module Generator is a multi-purpose random part generator.

    It revolves around the Module component that gives game objects the ability to randomly and deterministically generate parts at specific attach points. Module creation is made easy by a powerful custom editor with prefab and undo support.

    Different modes exist that let you decide when generation (and clearing) of parts should occur: on enable; according to the distance from an object (camera for example); by trigger collider; by the presence of an object within a zone; or by script. You can also generate parts directly from the inspector.

    This asset is most useful to add some variation to existing assets, fully randomized objects, random level generation, culling and much more.

    Screenshot01.png ModuleInspectorScreenshot.png
    Below is the first part of a tutorial explaining the basics of Module Generator. The second part will be published soon.



    Assets used for the tutorial video and the screenshots above are from the 3DForge's Village Exteriors Kit.

    v1.4 (Released: Jul 17, 2020)
    Added:
    • Seeding options:
      • Manual: The manually entered seed is used.
      • Auto: a value fetched from the UnityEngine.Random class is used.
      • Position: The hash value of the position and the rotation is used.
    • Material handler
      • Change the material of an object in runtime randomly dependent on the seeding.
    v1.3
    Changes:
    • Adapted the scripts to support Unity API changes in 2017.1 (deprecated functions)


    Edit: Updated asset store link... now in the right category.
     
    Last edited: Jul 30, 2020
    S4G4N likes this.
  2. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello community.

    The package has now been submitted and its review is pending.
     
  3. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    The package has been updated and resubmitted for review. This may take a little longer.
     
  4. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello everyone.

    The package has been released. You can get it there.
     
  5. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    The second part of our tutorial on how to use Module Generator has been uploaded here.
     
  6. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Hello
    Watching the movies, this looks great!
    But is it also possible to generate a chosen selection of parts, manually or by script?
    And can i script parts to be not generated? And to re-generate?
    It would be also great to save a configuration of chosen parts(even different transforms)!

    Cheers and wishing great success :)
    Michael

    Edit: And can you explain more about Generation Modes?
     
    Last edited: Oct 20, 2016
  7. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello, glad you like it :)

    That's a great idea to extend the module. Right now we have a function that chooses a part for every part set randomly based on the weights assigned to the parts: it takes a part set, a random number generator and returns a part index. What you would like is a function that can return a fixed index. This could be done quite easily. By curiosity, did you have a particular use case in mind?

    You have access to the list of part set and parts by script so you can decide to put a weight of 0 on a particular part to tell the random algorithm to never choose that part. This might be included as a specific feature linked to the changes needed to define a specific part to choose (or not in that case). We already have some ideas about that.

    If by re-generate you mean clear and generate the parts again at runtime, this is possible indeed.

    Again, as you have access to that information by script, you could save that information without any problem.

    Generation mode lets you decide how and when to generate parts. In our video we only showed the Manual and Always mode.
    In Manual mode, you decide to trigger the generation of the parts by either pressing the Generate Parts button in the inspector (as in the video), or you can also call the module's function GenerateParts in your own scripts.
    In Always mode, the parts are generated once the module is enabled (or as soon as possible depending on certain factors). It could be a module present in your scene, another one instanciated by script or even one that was disabled. In this mode, the generation is automatic.
    Other automatic modes exists that let you generate parts when an object is within a zone, at a certain distance, etc.
    We're currently preparing a video that explains the different generation modes in details so... stay tuned.

    Thank you :)
     
    Last edited: Oct 21, 2016
  8. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Hello
    Thanks for your reply!

    I know that your asset is meant for random generation of different buildups of parts. And i know that setting the weight to zero would not generate a part. We have an architectural configuration app, where we can setup for example different walls and roofs and I wondered if i can use your interface to setup something like that easily. So saving different configurations would definitely helpful.

    Btw, bought it already :)

    Cheers
    Michael
     
  9. CSCAPromo

    CSCAPromo

    Joined:
    Aug 5, 2015
    Posts:
    4
    Very interesting!

    May I offer a suggestion? Redo the tutorial video and upload it to youtube. The video has some weird audio lagging that is very distracting, every 5 or 10 seconds there is a weird halt in audio. And also (this is a personal request) I personally find vimeo annoying. I don't know why people use it, it seems less user friendly.
     
  10. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    @mensch-mueller great! Ok, I'm still thinking about how we could make this even more user friendly to save things around. Meanwhile, you may be able to serialize the result of the partSets property on module.

    @CSCAPromo Well, we may follow your suggestion then ;). I didn't notice any lagging though. We'll take a closer look.
     
  11. Metron

    Metron

    Joined:
    Aug 24, 2009
    Posts:
    1,137
    Hmmm... I watched the videos and didn't hear any lag in the sound...
     
  12. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Hello
    Just had some time to play with it. I´m on OSX (Unity 5.4p3)and unfortunately any of the buttons showed up(Preview selected, Bounding boxes...). When I want to edit a part the label "Editing Part" showed up correctly, but whats worse, i can´t apply or cancel it, because buttons are missing. I think it has to do with flawed Retina support of Unity. Could this be fixed?
    And it would be also great if we can rename Part Sets.

    Cheers
    Michael
     
  13. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello @mensch-mueller ... erm that's a pity. Sorry for that. I'll try to have a look as soon as possible (no mac here to test). If I can reproduce and fix that bug I'll send you that.

    You mean rename from "Part Set n" where n is the index of the part set to something custom? We could also make the part set take the name of the currently associated attach point. We'll have to add options I guess :)

    Thank you for your feedback. Right now we're pretty busy with a contract but a new version is planned after that.
     
    Last edited: Oct 31, 2016
  14. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    @mensch-mueller I could not reproduce your bug on our Mac as, of course, it doesn't have a retina display... As you've said I'm pretty sure the new retina support in 5.4 is not really helping here. Could you take a screenshot by the way?

    As a temporary workaround try to launch the Unity editor in low resolution as mentionned here:
    https://forum.unity3d.com/threads/any-way-to-disable-retina-scene-view.436373/#post-2821285

    Also try to update Unity to the latest patch (or even 5.5 beta if you can) to see if that has been fixed... I couldn't find anything about that in the patch release notes so far though.
     
  15. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello!

    Undo/Redo functionality bug

    updated 15/11/16: We reported a bug to Unity to clarify if the problem comes from our side or from Unity.
    updated 16/11/16: See next post for fix


    We found a major bug while recording our next tutorial video and we want to let you know we're aware of it.

    The bug occurs in two known cases:
    1. when you undo an operation and a mesh renderer is also present on the same object as the module component.
    2. when you drag and drop some material into the scene view (even when an object with a module is not selected)
    In both cases, you'll get error messages, lose current part selections in module inspector and undoing operations on your module won't work as expected; further, you'll have to restart Unity to fully recover undo capability for modules.

    Until we've fixed that issue, avoid those two manipulations. If you really want to put a mesh renderer on the same object (we never did actually), as a workaround you can do all your editing by copying your mesh related components on a child object and copy them back we you're finished...
     
    Last edited: Nov 16, 2016
  16. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello everyone.

    Unity reported to us today that the bug we talked about in the previous post was indeed a bug from Unity that has been fixed in version 5.5 (tested on 5.5b11). At least for the breaking Undo functionality (see below for the inspector reset). For those of you who don't want to switch to 5.5 we'll have to find a workaround for this issue, maybe to limit the Undo functionality. As a side note, we also noticed some improvements in overall Undo/Redo functionality by updating to this version, like names for Redo operation that matches the actual Undo name, etc.

    Nonetheless, there is still a problem with the state of the inspector being reset when a MeshRenderer is also present along with a Module component. Unity is also aware of that problem and have that related issue already tracked. This is easily avoided though and we explained a workaround procedure in the previous post.

    For those who are curious this previous "bug" is caused by the material editor displayed below the components when at least one material is assigned to the MeshRenderer. Whenever you undo, this material editor trigger the rebuild of the entire inspector window which also reset our component inspector's internal state. We'll see if we can work around this one but that's not a priority. UPDATE: corrected in 5.6 according to Unity
     
    Last edited: Jan 25, 2017
  17. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    We have planned to do a patch release next week, fixing some bugs and, if time permits, adding also some asked functionalities.

    Thanks to our early adopters! Don't hesitate to ask questions and report any issues you have!
     
    S4G4N likes this.
  18. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Hi
    Totally missed it. Was able to even import it in Unity 5.3 without the mentioned interface glitches(and without error). But i have to switch back to 5.4. And completely struggled setting the weight of a PartSet Part by code(because i´m a noob coder). Get to the point ... GetComponents<Sidema.ModuleGenerator.Module.
    Would vote for methods of setting weight and transforms of Parts in PartSets are build in. Also Methods for setting Seed.
    Thanks for temporary workaround try to launch the Unity editor in low resolution, didn´t know that!

    Cheers
    Michael
     
  19. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Setting the seed of a module is rather easy. There's a property called "seed" on the Module that you can use. You can assign it an integer from 0 to 18446744073709551615 (64-bit ulong).

    Code (CSharp):
    1. using Sidema.ModuleGenerator;
    2. ...
    3. var module = GetComponent<Module>();
    4. if (module != null)
    5. {
    6.   module.seed = 9999;
    7. }
    8. ...
    9.  
    As for the weight, it's a little bit more involved. If you want to set a single part (assuming your module has at least 3 part sets and 2 parts in the 3rd):
    Code (CSharp):
    1. using Sidema.ModuleGenerator;
    2. ...
    3. var module = GetComponent<Module>();
    4.  
    5. if (module != null)
    6. {
    7.   module.GetPartSet(2).parts[1].weight = 2;
    8. }
    9.  
    For setting in batches you might want to use this:
    Code (CSharp):
    1. using Sidema.ModuleGenerator;
    2. ...
    3. var module = GetComponent<Module>();
    4.  
    5. if (module != null)
    6. {
    7.   var partSets = module.partSets;
    8.  
    9.   if (partSets != null)
    10.   {
    11.     // Set the weight of every parts to 2 for every part sets
    12.     for (int i = 0; i < partSets.Length; i++)
    13.     {
    14.       var partSet = partSets[i];
    15.  
    16.       for (int j = 0; j < partSet.parts.Length; j++)
    17.       {
    18.         partSet.parts[j].weight = 2;
    19.       }
    20.     }
    21.   }
    22. }
    23. ...
    We hope this helps.

    EDIT: added an example for single change
     
    Last edited: Nov 28, 2016
    Inspeinre likes this.
  20. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Great, thanks :)
    Perhaps this could be added to script reference!
    Michael
     
  21. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Script reference contains this under "Module -> Variables -> partSets". PartSet and Part are themselves in the Script reference. Maybe we'll insist on the way you can access the values...

    By the way, for the more advanced user, we're using structs where we should actually use classes... right now it's a bit confusing because the struct is mutable. I suppose it won't take too long for that choice to come back and bite us...
     
    S4G4N likes this.
  22. mensch-mueller

    mensch-mueller

    Joined:
    Nov 25, 2014
    Posts:
    156
    Yeah, i mean as an example! The rest i found out, but what i´m struck is that it´s a stuct. And i found no way to access it. So a example would help!
    Michael
     
  23. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Indeed, actually you don't need to reassign the array of struct after modifying a part (reference to same array of parts as stored internally by the module) but you must reassign it if you modify an attach point. That's not what you would expect. We'll certainly change struct to class. I'll let you know next week what to expect as it's a breaking change.
     
    Last edited: Nov 17, 2016
    S4G4N likes this.
  24. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Sorry for the delay, v1.1 has only been submitted for review today. This update is mostly bug fixes, changes to documentation and two breaking changes. Unfortunately, we did not find a workaround for the breaking Undo/Redo functionality for Unity 5.3, 5.4. However as indicated in a previous post Unity 5.5b11 fixes that bug.

    Here are the breaking changes:
    1. We did change the PartSet and Part structs into classes. We also added much more information about that property to help you know (we hope) all the implications of setting it with your own data.
    2. We renamed the property "parts" of the Module class to "partObjects" to reflect its real usage which is to retrieve all the part objects generated for each part set.
    Thank you and have fun!

    EDIT: Version 1.1 is available.
     
    Last edited: Dec 2, 2016
    S4G4N likes this.
  25. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello everyone.

    We've tested Module Generator in 5.6 beta which was released yesterday. This version is fixing several bugs we encountered in Module Generator which were actually Unity related. The first is the state of the inspector being reset when you use Undo/Redo while a MeshRenderer component is also present on the module object. The second is the NullReferenceException spams you get when you drag and drop materials from the project panel onto the scene view while a Module is selected. We may find workarounds for these in 5.3, 5.4 and 5.5 versions but in the meantime try to avoid these cases.

    Have fun!
     
    Last edited: Dec 14, 2016
    S4G4N likes this.
  26. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,932
    Love this and want it so much. But we are in 5.4 and most likely won't go to 5.6 for a few weeks until the rest of you tell me it is safe. However, I plan to use it for city building so can't wait to test it and show off the results.

    If you do find work arounds, please let us know. I will buy it immediately.
     
    S4G4N likes this.
  27. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello Teila, we're happy you're interested in our little tool.

    Technically, there are workarounds: avoid doing certain operations like adding a MeshRenderer on the same object as a Module (you can put it on an child object, which we prefer anyway) or drag and drop material from project panel to scene view while an object with a Module is selected.

    If you forget, all that should happen is that, from that point on, you'll be unable to Undo/Redo modifications on any part while you're in part editing mode. You'll see it quickly and all you'll have to do is to restart Unity. It shouldn't break the module itself.

    We didn't find any other workaround that would avoid those little problems to happen unfortunately. The only solutions we thought about were to limit certain functionalities or we could have restricted download to 5.6 version of Unity but we decided those bugs weren't worth the restrictions.

    If you do decide to buy it anyway, we'll be happy to see how you use it for your project!
     
    Last edited: Jan 25, 2017
    S4G4N and Teila like this.
  28. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,932
    Oh I will buy it. :) My head is spinning from all the ways I can use it.
     
    S4G4N likes this.
  29. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    I have been considering purchasing this asset but I'm having trouble justifying the price. This just looks like a script that has a list of prefabs it chooses randomly based on weight/seed with parameters for when to trigger generation; I have made similar systems within a day (minus the custom editor/seed generation). What sets this apart from being just a list of parts with a fancy editor? Is there a documentation pdf open to the public?
     
  30. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,932
    I guess what sets it apart in my eyes is that it will save me time and my programmers can concentrate on other things. Many assets on the store can be made by skilled programmers. But someone here made one that he is selling to the rest of us. :)
     
    S4G4N likes this.
  31. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    I own a game development company and we publish assets as well so I know how it is, Looking at this for a personal project though and I like to consider if I can make it myself or not And in a fair amount of time. If this offered a few more bells and whistles I might not think of they it would be easier for me to justify it. Still considering though. Anyone know if the prefab you assign to the module have to be in a resources folder?
    Edit: sorry for my sentences I'm out in the cold on my phone.
     
  32. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello FirefightGI. Prefabs can be in any folder you want. We give the source code away so you could start from there and improve as you wish ;). We've also made the documentation available online, that's a good point. You can find it here.
     
    ParadoxSolutions and S4G4N like this.
  33. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,932
    I am absolutely confused as to why someone would actually come to a thread like this and tell the developer "I am trying to figure out if I can justify the price or make it my own" unless they are hoping to get the developer to lower the price or give it to them for free.

    Way too much of this on the asset store. If this was not your intention, then I apologize but what you write really sounds like this is your intention. ;) Would it not have been better to ask questions and keep the decision to make it yourself to yourself rather than posting on the forums?

    The price for this item looks well worth the cost. I discovered it from a link in a Skype forum with other developers and we were all excited about it. I am sure it will sell well, especially when we all start posting reviews and pictures of thing things we are making with it. :)
     
  34. S4G4N

    S4G4N

    Joined:
    Mar 13, 2013
    Posts:
    3,213
    It is a very easy decision, how long are you willing to work to earn $39 ?

    1 hour, 2 hours, 3 hours, maybe 4 hours, depending on what you do?
    So if you can do it in less and you need to include future input time when there is bugs as well, then don't buy it.
    Plus buying this here, you getting an army of other users that first of all will also test and give feedback and help make the tool WAY more robust then just you yourself will have the testing and bug fix time to have.
    In my opinion is it WAY under priced for just the time-save on using it will provide after getting familiar with it.

    If you decide to make it, spending weeks and months of your time, then come see how much you will be willing to sell it for.
    You would also want to be compensated for time already spent and future loss if time that you will be investing into the product.

    Come on friend, if you need this and it is for you, buy it, give the dev the thumbs up by giving a fair and good review and be part of the growing Development scene here at Unity, being an owner of a Game Development Company, you know what I am talking about ;):)

    At the end we all have the same goal here.
    I support other devs on the Asset Store, buying my characters, sounds and MANY tools and give constructive feedback that their hard work deserve
     
  35. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    My intention was not to be rude or have the price lowered, I merely felt like I was missing Some information that would be a selling point for me personally. Hence why I inquired about the documentation, I fully support the asset store and the developers that put their time into making assets and meant no disrespect. This asset would save me a lot of time I could spend working on other things and that is what's great about it I just am looking for more information about it and the dev put up a link to the documentation. Sorry for the confusion, it is hard to pass along tone and emotion through text and I had no intent of coming across as snarky or as begging. :)
     
    Teila, S4G4N and Sidema like this.
  36. S4G4N

    S4G4N

    Joined:
    Mar 13, 2013
    Posts:
    3,213
    Hey @FirefightGI , I did not see it as rude,
    Really just wanted to give a different perspective on the asset store and the great advantage to buy from it and support others.
    I love the Asset Store, have been here full-time here now for more then 4 years, with my only regret that I did not arrive sooner :);) I did not mean to come across critical towards anyone, just looking at things from a developer side and the great partnerships that dev basically build by engaging with them by buying there assets and let them do what they good at.
    See you around :);)

    The art asset that was used there was mine by the way. Village Exteriors Kit
    Very strong modular package that suits tool sets like these very well and will give you miles of re-usage
    Cheers
    Cobus
     
    Metron likes this.
  37. Teila

    Teila

    Joined:
    Jan 13, 2013
    Posts:
    6,932
    It certainly is difficult. I am glad that was not your intention and that I was wrong. :) I see far too many people do things like this in other threads and I guess I feel the need to defend the fabulous developers. Glad you are of the same mind.
     
  38. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Enjoy 30% OFF ModuleGenerator on the Asset Store mega sales!

    Have fun!
     
    Teila and Inspeinre like this.
  39. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Hey there, just wanted to check and see how this does in a client/server deterministic environment? Seems rather interesting.
     
  40. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    It is seed based so you just need to make sure that all clients are passed the seed and are running the same version of your game in case a module was changed between versions, thus changing output of the seed. The thing with anything seed based especially for early access titles is that you may have to do resets/wipes if something major gets changed that would negatively alter the game world.
     
  41. ParadoxSolutions

    ParadoxSolutions

    Joined:
    Jul 27, 2015
    Posts:
    325
    Oh and Gizmos need to updated to 2017, fixing the warning messages each time I import the package is getting old.
     
  42. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hi,

    Sorry, we weren't aware that there was a problem with the handles. I took a look at it and I fixed it. Currently downloading Unity 5.3 for backward compability.

    I submit a new package asap.

    BTW. Module Generator has a new price and is currently on 20% sale.
     
  43. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello everyone,

    I've submitted V1.3 of the package. The package contains the Gzmo updates.

    Sorry for the inconvenience. Don't forget to drop us a line if you need any other changes.
     
    ParadoxSolutions likes this.
  44. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hello everyone,

    the updated package has been accepted. You can find it here:

    Module Generator

    Have a good day :)
     
  45. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    The package has been checked against 2018.1 and everything works as expected
     
  46. StevenPicard

    StevenPicard

    Joined:
    Mar 7, 2016
    Posts:
    859
    I left a review on this very useful asset. Five stars but with some feedback. I hope you are willing to do a quick update with the suggested two seed methods of "auto" and "position" recommended by a previous reviewer and now me.

    Regardless, the code is there and I can add these features myself.

    Great asset!
     
  47. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Thanks for the feedback and the review. We'll look into these request beginning next week.

    Could you tell me which Unity version you're using?
     
    StevenPicard likes this.
  48. StevenPicard

    StevenPicard

    Joined:
    Mar 7, 2016
    Posts:
    859
    I was using 2019.3 (it worked great in that version) but I just moved to 2019.4 LTS. I still need to test it in the new version but I don't anticipate any problems. I'll let you know if I find any.
     
  49. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Thanks for your reply. I'll get back to you probably on thursday next week. We have quite some workload currenrly.
     
  50. Sidema

    Sidema

    Joined:
    Jan 5, 2016
    Posts:
    58
    Hi,

    just to give a feedback. I started working on implementing the requested features.

    Sorry for the delay. We have a lot of work :)

    Best regards,
    Stefan
     
    StevenPicard likes this.