Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to add custom project settings to your project?

Discussion in 'Scripting' started by Zergling103, Mar 31, 2020.

  1. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I'm wanting to add custom Project Settings assets to my project. Similar to for example DynamicsManager.asset, which is stored in the ProjectSettings folder next to the Assets folder of your project.

    In my search I was brought to this peice of documentation:
    https://docs.unity3d.com/2019.1/Doc...5.1201776124.1585628469-1082801306.1528154012

    It provides an example on how to use this class to add extra project settings to your project. The only problem with the example is that it doesn't appear to allow you to define project-wide data that is available in builds. Every class provided in the example, including the class containing the data itself, depends on something from the UnityEditor namespace, which is unavailable in builds.

    Is there a way to create something similar to DynamicsManager.asset, where:
    • It is a singleton to provide project-wide values.
    • Is accessible in the editor and in builds.
    • Can be modified in the editor and saved with the project.
    • Is available immediately upon request in code (similar to
      UnityEngine.Physics
      without needing special initialization steps).
    • Integrates nicely with the editor.
    Ideally I'd want to use what Unity already seems to provide for its built-in features like Physics.

    Previously I'd use "normal"
    ScriptableObject
    s, where the scriptable object is lazily initialized when it is needed. It looks for or creates an instance of this object with a specific name in the resources folder. While this works, it isn't quite as nice as having a projects setting asset that is specifically designed to be used this way.
     
  2. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Any luck with that?

    I'm trying to solve the same problem, and an instance of ScriptableObject somewhere in Resources, just as you described, is the only solution I came up with so far.
     
    Last edited: May 23, 2020
  3. Moe_Baker

    Moe_Baker

    Joined:
    Oct 22, 2017
    Posts:
    36
    I have accomplished this with the help of
    Code (CSharp):
    1.  
    2. InternalEditorUtility.SaveToSerializedFileAndForget()
    3. InternalEditorUtility.LoadSerializedFileAndForget()
    4.  
    These two functions allow me to save an instance of a scriptable object to a path, and to load it back.
    So, the idea is that I load or create a new instance of my scriptable object, set its hideflags so it isn't saved or unloaded, and then call DestroyImmediate on it before the assemblies are reloaded and I lose reference to it; so as to not inflict a memory leak.
    On build I create an asset of that scriptable object, save it to a certain path, insert it into Unity's preloaded assets array, then delete it after the build is over, and as such, it's included in build.

    This is the code I'm using, it references some other code in my personal library, but it should be easy to replace if you want to
     
    _geo__, NotaNaN, Novack and 1 other person like this.
  4. landosilva

    landosilva

    Joined:
    Oct 23, 2014
    Posts:
    5
    Hey, did you manage to handle it somehow?
    I'm at the exact same step as you described, trying to find a solution to make exactly what you described as well.
    Please let me know if you solved it!
     
  5. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    625
    I did read the whole code and I think I understand what's happening.
    You have a lot of editor functions to save and load the scriptable object and to make sure to include it in the build.

    What I didn't understand from your message was how this solves the runtime part.

    But at runtime, OnEnable() is called for all scriptable objects that are in the "always include" list, and you use it to register it as singleton instance. So you have access to it from everywhere (which is perfect for a settings asset).

    Clever.
    Thanks for sharing your code. ^^
     
    _geo__ likes this.