Create a custom provider
Implement your own custom providers for Adaptive Performance.
Read time 6 minutesLast updated 20 days ago
Create and configure a custom provider for Adaptive Performance.
Adaptive Performance relies on providers to act as a bridge between the Unity Engine and a device's hardware sensors. Creating a custom provider involves building a self-contained package that's discoverable by the Adaptive Performance system.
Follow these steps to create a new provider:
- Create a loader.
- Configure build and runtime settings.
- Provide package metadata so Unity can recognize your provider.
Create a loader
The class manages the lifecycle of your provider's subsystems. Your provider needs a loader, which acts as the main driver for these management features.
AdaptivePerformanceManagerSettingsTo create a loader:
-
Create a subclass of. This class is a
AdaptivePerformanceLoaderthat defines the subsystems your provider requires and their load order. To handle subsystem management in a type-safe manner, derive from theScriptableObjectclass instead.AdaptivePerformanceLoaderHelper -
Implement the lifecycle methods.calls these methods to initialize, start, stop, and deinitialize (clean up) your loader's subsystems. For example:
AdaptivePerformanceManagerSettingsusing UnityEngine;using UnityEngine.AdaptivePerformance;public abstract class AdaptivePerformanceLoader : ScriptableObject{ public virtual bool Initialize() { return false; } public virtual bool Start() { return false; } public virtual bool Stop() { return false; } public virtual bool Deinitialize() { return false; } public abstract T GetLoadedSubsystem<T>() where T : class, ISubsystem; public abstract ISubsystem GetDefaultSubsystem(); public abstract IAdaptivePerformanceSettings GetSettings();} -
Add the loader to the manager settings. In the Unity Editor, add yourinstance to the Loaders list in the Adaptive Performance Manager Settings. You can add multiple loaders and arrange them by priority. At runtime, the manager attempts to initialize each loader in order. The first one that initializes successfully becomes the active loader.
AdaptivePerformanceLoader -
(Optional) Query the staticinstance to access the active loader. If all loaders fail to initialize, Unity sets
AdaptivePerformanceManagerSettings.ActiveLoaderto null.activeLoader
Configure build and runtime settings
A provider might need additional settings to help manage build issues or runtime configuration.
To configure build and runtime settings through Project Settings:
-
Add theattribute to a
AdaptivePerformanceConfigurationData.ScriptableObject -
Define properties in theto control the provider's configuration. Unity displays these options in the Adaptive Performance section of the
ScriptableObjectwindow.Project Settings?
Note: Unity manages the lifecycle of one instance of the class marked with the attribute through theconfig object API. If you don't provide a dedicated interface, configuration settings display in the Project Settings window using the standard Scriptable Object Inspector. You can create a custom Editor for your configuration settings type to replace the standard Inspector in the Project Settings window.EditorBuildSettings -
Inherit fromin a build script to pass settings from the Editor into your runtime loader. The following is an example of a simple build script:
AdaptivePerformanceBuildHelper<T>using UnityEngine.AdaptivePerformance.Editor;using UnityEngine;public class MySettings : ScriptableObject { }public class MyBuildProcessor : AdaptivePerformanceBuildHelper<MySettings>{ public override string BuildSettingsKey { get { return "MyPackageSettingsKey"; } }}
Customize the build process
You can also override build processing steps like and . Make sure to call the base class implementation to ensure your settings transfer to the built application. For example:
OnPreprocessBuildOnPostprocessBuildusing UnityEditor.Build.Reporting;using UnityEngine.AdaptivePerformance.Editor;using UnityEngine;public class MySettings : ScriptableObject { }public class MyBuildProcessor : AdaptivePerformanceBuildHelper<MySettings>{ public override string BuildSettingsKey { get { return "MyPackageSettingsKey"; } } public override void OnPreprocessBuild(BuildReport report) { base.OnPreprocessBuild(report); // Do your work here } public override void OnPostprocessBuild(BuildReport report) { base.OnPreprocessBuild(report); // Do your work here }}
If you want to support different settings per platform at build time, you can override and use the attribute to retrieve the appropriate platform settings. By default, this method uses the key associated with the settings instance to copy the entire settings object from to .
AdaptivePerformanceBuildHelper<T0>.SettingsForBuildTargetGroupbuildTargetGroupEditorUserBuildSettingsPlayerSettingsusing UnityEditor;using UnityEngine;using UnityEngine.AdaptivePerformance.Editor;public class MySettings : ScriptableObject { }public class MyBuildProcessor : AdaptivePerformanceBuildHelper<MySettings>{ public override string BuildSettingsKey { get { return "MyPackageSettingsKey"; } } public override UnityEngine.Object SettingsForBuildTargetGroup(BuildTargetGroup buildTargetGroup) { // Get platform specific settings and return them. Use something like the following // for simple settings data that isn't platform specific. UnityEngine.Object settingsObj = null; EditorBuildSettings.TryGetConfigObject(BuildSettingsKey, out settingsObj); if (settingsObj == null || !(settingsObj is T)) return null; return settingsObj; }}
Provide package metadata
For the Adaptive Performance provider management system to use your provider, you must supply metadata.
To do this, create a class that implements the following interfaces:
The system uses .NET reflection to find all types implementing the interface. It then attempts to instantiate each one and populate the metadata store with the information provided by each instance.
IAdaptivePerformancePackagePackage initialization
Implementing the package metadata allows the Adaptive Performance provider management system to automatically create and initialize your loaders and settings instances. The system passes any new instances of your settings to the method to allow your provider to initialize the new instance data after it's created, if needed.
PopulateNewSettingsInstanceExample of a minimal package setup with metadata
using System.Collections.Generic;using UnityEditor;using UnityEngine;using UnityEngine.AdaptivePerformance;using UnityEngine.AdaptivePerformance.Editor.Metadata;// The following are minimal placeholder classes required for this snippet to compile.// In your project, 'MyPackageSettings' and 'MyLoader' would contain your actual custom logic and definitions.public class MyPackageSettings : ScriptableObject { }public class MyLoader : AdaptivePerformanceLoader{ public override bool Initialize() { return true; } public override bool Start() { return true; } public override bool Stop() { return true; } public override bool Deinitialize() { return true; } public override T GetLoadedSubsystem<T>() { return null; } public override ISubsystem GetDefaultSubsystem() { return null; } public override IAdaptivePerformanceSettings GetSettings() { return null; }}class MyPackage : IAdaptivePerformancePackage{ private class MyLoaderMetadata : IAdaptivePerformanceLoaderMetadata { public string loaderName { get; } = "My Loader"; public string loaderType { get; } = typeof(MyLoader).AssemblyQualifiedName; public List<BuildTargetGroup> supportedBuildTargets { get; } = new List<BuildTargetGroup>() { BuildTargetGroup.Standalone, BuildTargetGroup.Android, BuildTargetGroup.iOS }; } private class MyPackageMetadata : IAdaptivePerformancePackageMetadata { public string packageName { get; } = "My AdaptivePerformance Provider"; public string packageId { get; } = "my.adaptiveperformance.package"; public string settingsType { get; } = typeof(MyPackageSettings).AssemblyQualifiedName; public List<IAdaptivePerformanceLoaderMetadata> loaderMetadata { get; } = new List<IAdaptivePerformanceLoaderMetadata>() { new MyLoaderMetadata() }; } private static IAdaptivePerformancePackageMetadata s_Metadata = new MyPackageMetadata(); public IAdaptivePerformancePackageMetadata metadata => s_Metadata; public bool PopulateNewSettingsInstance(ScriptableObject obj) { MyPackageSettings packageSettings = obj as MyPackageSettings; if (packageSettings != null) { return true; } return false; }}
Provider settings in the Unity Editor
You can display provider settings under both Project Settings and Build Profiles, so you can edit the settings in both locations. Provide the custom UI code by inheriting from the and adding a custom attribute.
ProviderSettingsEditorThe following example demonstrates how provider settings function if only the default UI is necessary.
using UnityEditor;using UnityEditor.Localization;using UnityEngine;using UnityEngine.AdaptivePerformance.Editor;public class BasicProviderSettings : ScriptableObject { }[CustomEditor(typeof(BasicProviderSettings))]internal class BasicProviderSettingsEditor : ProviderSettingsEditor{ protected override BuildTargetGroup CurrentTargetGroup => BuildTargetGroup.Unknown; public override bool ShowTargetGroupSelection => false; public override string UnsupportedInfo => L10n.Tr("Adaptive Performance Basic provider is not supported on this platform"); protected override bool IsAutoPerformanceModeAvailable => false; protected override bool IsBoostAvailable => false; protected override bool IsThermalActionDelayAvailable => false; public override void OnInspectorGUI() { DisplayProviderSettings(); }}