Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

[Free] Using Presets at runtime

Discussion in 'Assets and Asset Store' started by MalteWeiss, Jan 31, 2019.

  1. MalteWeiss

    MalteWeiss

    Joined:
    Sep 26, 2018
    Posts:
    3
    What are (runtime) presets?

    Presets are a way to store a components values to an asset file that can be reapplied to other components either in the editor or by scripting.

    Presets have one downside though: They are placed in the UnityEditor namespace and can therefore not be used in your compiled game. Loading presets at runtime is unfourtunately not possible. This plug-in intends solve this problem.

    Runtime presets are an alternative to the Unity presets by storing components as prefabs that can then be reapplied at runtime. Using runtime presets is nearly identical to using the default Unity presets:

    Code (CSharp):
    1.  
    2. public class ApplyPreset : MonoBehaviour
    3. {
    4.     public Preset _preset;
    5.     public Light _light;
    6.  
    7.     private void Awake()
    8.     {
    9.         _preset.ApplyTo(_light);
    10.     }
    11. }
    12.  
    Setup

    If you want to get a quick overview you should check out the ⬇️ demo project.
    You can also download the ⬇️ package containing only the essential scripts.

    After downloading and importing the package, you will find a new entry Create Runtime Preset in the gear menu of a component.

    Creating a runtime preset

    Open the gear menu on any GameObjects component and click Create Runtime Preset.



    The plug-in will then create the preset in the `Assets` folder. A newly created preset will always have the default name `New Preset`. Rename it after creation to prevent it from being overwritten.



    The preset is simply a prefab with a copy of your selected component. It also has an additional component called `Preset`. Keep this in mind as we'll need it in the next step.



    Loading runtime presets

    Presets can be set in the inspector once you expose a variable of the Preset type.

    Code (CSharp):
    1. public class ApplyPreset : MonoBehaviour
    2. {
    3.     //A preset which needs to be set in the inspector
    4.     public Preset _preset;
    5.     //A light component that we want to modify
    6.     public Light _light;
    7.  
    8.     private void Awake()
    9.     {
    10.         //Presets store values of a specific component type
    11.         //Checking whether the values can be applied may be helpful
    12.         if(_preset.CanBeAppliedTo(_light))
    13.         {
    14.             //Transfers the values from the preset onto the _light component
    15.             _preset.ApplyTo(_light);
    16.         }
    17.     }
    18. }
    After compiling the script you can now set the preset and reference the light component. The preset field is restricted to only accepting presets. You won't accidentally reference something else than a preset.



    Creating presets during runtime

    Presets can also be created during runtime. You will need any component to initialize the preset with. The preset can then be used to apply the values to any component of the same type.

    Code (CSharp):
    1. public class CreatePreset : MonoBehaviour
    2. {
    3.     //A reference to a light from another gameObject
    4.     public Light otherLight;
    5.     //The preset we want to store the lights values in
    6.     private Preset _preset;
    7.  
    8.     void Start()
    9.     {
    10.         //Getting the light component of this gameObject
    11.         var light = GetComponent<Light>();
    12.         //Create a new preset from "otherLight" and apply its values to "light"
    13.         _preset = Preset.From(otherLight);
    14.         _preset.ApplyTo(light);
    15.         //Removes the temporary object created to store the runtime preset
    16.         //This is optional
    17.         _preset.Free();    
    18.     }
    19. }
    The examples might be a bit forced, but I often find myself in more complex situations where runtime presets can be a real life saver.
    I hope I can save you some time with this plug-in. Feel free to contact me if you have any questions.
     
  2. 1illGamer

    1illGamer

    Joined:
    Jul 24, 2016
    Posts:
    1
    Thank you. I was looking for something like this.
     
    Last edited: Feb 7, 2019
  3. St00nsa

    St00nsa

    Joined:
    Oct 22, 2018
    Posts:
    1
    thanks man!
     
  4. myehiah

    myehiah

    Joined:
    Feb 27, 2018
    Posts:
    2
    Hi there MalteWeiss! Great work! I have an issue though... when I come to create a preset of a MeshRenderer instead of the Light in your example, all the values are set to default values, and even those are not applied to the target. Any idea why that might be?

    I took screenshots of the source, tempObject, and target to show you what I mean.

    Source Source.jpg Temp Temp Object.jpg Target Target.jpg
     
  5. MalteWeiss

    MalteWeiss

    Joined:
    Sep 26, 2018
    Posts:
    3
    It should work now. I've added two additional example scenes: MeshRendererExample and TransferComponentValues.
    If you only want to copy values once, you can use my extension method TransferValuesFrom.

    Code (CSharp):
    1. using RuntimePresets;
    2. using UnityEngine;
    3.  
    4. public class TransferComponentValues : MonoBehaviour
    5. {
    6.     public MeshRenderer otherComponent;
    7.  
    8.     void Start()
    9.     {
    10.         var thisComponent = GetComponent<MeshRenderer>();
    11.         thisComponent.TransferValuesFrom(otherComponent);
    12.     }
    13. }

    Please let me know if the fix works for you.
     

    Attached Files:

    myehiah likes this.
  6. myehiah

    myehiah

    Joined:
    Feb 27, 2018
    Posts:
    2
    Thank you so much! Works like a charm. Thanks for the very fast reply as well, greatly appreciated!

    N.B. The TransferComponentValues scene is identical to MeshRendererExample, I switched the scripts though and it works too, just thought I'd tell you if you'd like to adjust the scenes.

    Thanks once again.
     
  7. MalteWeiss

    MalteWeiss

    Joined:
    Sep 26, 2018
    Posts:
    3
    Oops, you're right. It's now fixed.

    Glad I could help.
     
  8. freakrho

    freakrho

    Joined:
    Aug 19, 2013
    Posts:
    3
    This has been really useful!
     
  9. UDN_5c806b49-d8a0-4f67-a296-c12c91aa7396

    UDN_5c806b49-d8a0-4f67-a296-c12c91aa7396

    Joined:
    Jan 9, 2017
    Posts:
    102
    Will this work for scriptable objects?
     
  10. TyrannicGoat

    TyrannicGoat

    Joined:
    Jun 27, 2016
    Posts:
    2
    Nice work MalteWeiss! Did you consider putting this on GitHub?

    No currently it won't. The TransferValuesFrom method only works on classes that inherit from Component.
     
unityunity