I have a build script and before calling
BuildPipeline.BuildPlayer()
I wanna be able to set which Remote COnfig environemnt will be used.
Where can I set that?
I have a build script and before calling
BuildPipeline.BuildPlayer()
I wanna be able to set which Remote COnfig environemnt will be used.
Where can I set that?
This is explained here: Environments API
EnvironmentsApi.Instance.ActiveEnvironmentName
CodeSmile is right, but I want to bring highlight to https://docs.unity.com/ugs/en-us/manual/overview/manual/environments-api#Build_and_runtime
.
If you set the environment in-code like this, this will be used.
var options = new InitializationOptions()
.SetEnvironmentName(environment);
await UnityServices.InitializeAsync(options);
If not, we will use what you select in the dropdown.
If not, we will use “production”.
I hope this clears things up.
Thank you that’s helpful.
I guess my question wasn’t valid then, there isn’t really a way to set the environment at build time (as it will always default to “production” for production builds).
I’ll have to save the different environment name for each build somewhere and then pass it in initialization options.
In this case, would it be considered bad practice to store the environment name as plain text? In something like a text file or scriptable object?
I see, in that case, the API that CodeSmile is exactly what you need. It basically gives you programmatic access to the dropdown ; you’re modifying the dropdown through code.
You can modify the environment right before you build it.
(I believe you may need to call “RefreshAsync” first)
However, if you can tell me what your usecase is, it could prove insightful for further development!
Cheers!
My use case(simplified here) is that I want to deploy the game to steam in it’s full and demo versions separately, where the demo version simply hides some menu options and restricts access to certain levels.
I was hoping to deploy the same build on both simply pointing at different remote configs, and guide activation/deactivation of features from those environments.
I understand that it might not be the safest approach as someone could tinker with the game and access the full game from the demo version, but I’m not really concerned.
Awesome, the above will help you set the correct environments for each version, so you can keep analytics and all the information separate (if thats what you want).
However, if you use preprocessors you can also prevent the extra code from being made available, this will make it impossible for anyone to access that code by hacking the game code.
Preprocessor code complete eliminated from the final binary. It wont
They can be enabled, disabled via the project settings > player > script define symbols
I would be surprised if there’s not something equivalent for assets, though I’m not familiar with that.
Remote Config would be more of the capacity to turn on/off features dynamically, like enabling a xmas event, that kind of thing. You can use it the way you want though, up to you!
Cheers
Hi sorry I put this aside for a few days.
So I’ve tried using the EnvironmentsApi as suggested, and I’m getting a weird error (possibly unrelated to the Services.Core api?).
Basically I’m not able to use using Unity.Services.Core.Editor.Environments;
The code deosn’t compile saying the Unity.Services.Core.Editor namespace doesn’t exists, while in fact it does exist (I even get intellisense)
Here’s a build test script I was testing:
using System;
using System.Diagnostics;
using System.Linq;
using Unity.Services.Core.Editor.Environments;
using UnityEditor;
using UnityEngine;
public class EditorTest
{
[MenuItem("MyTools/Windows Build With Postprocess")]
public static async void BuildGame()
{
// Get filename.
var path = EditorUtility.SaveFolderPanel("Choose Location of Built Game", "", "");
string[] levels =
{
"my-scene-name1", "my-scene-name2"
};
await EnvironmentsApi.Instance.RefreshAsync();
EnvironmentInfo info = new();
var env = EnvironmentsApi.Instance.Environments.First(x => x.Id.ToString() == "my-environment-id");
if (env == null)
{
throw new Exception("Error finding the environment");
}
EnvironmentsApi.Instance.SetActiveEnvironment(env);
// Build player.
BuildPipeline.BuildPlayer(levels, path + "/BuiltGame.exe", BuildTarget.StandaloneWindows,
BuildOptions.None);
// Run the game (Process class from System.Diagnostics).
var proc = new Process();
proc.StartInfo.FileName = path + "/BuiltGame.exe";
proc.Start();
}
}
This script is inside an Editor folder.
I’ve tried deleting all csproj files, and regenerating project files
I’ve tried creating a new blank Unity project and go the same problem
I’ve tried switching between Visual Studio and Rider
Hello!
The assembly is not automatically referenced (not sure why we made that choice, but it’s generally safer to be explicit in my experience).
let me know if that works for you
Thanks again
Creating an asmdef for the editor scripts did the trick and I was able to access the EnvironemntsApi
(definitely a wake up call to learn more about asmdef, so thanks for that as well)
Still, the problems remains as the EnvironmentsApi can only really change the environment for the editor.
That said, I don’t know why I was so stuck on setting the environment at build time, I ended up implementing it so that I save the env name in a scriptable object and use that at runtime.
are you setting the environment in code? i.e. do you have
.SetEnvironmentName("something")
somewhere?
Recall that the dropdown is secondary to code.
Code > Dropdown > Prod
the dropdown will only set the runtime environment if its not set explicitly in code
Yes I made sure to remove any environement set explicitily in code.
Note that the dropdown in proj settings only sets the editor environment, so it does make sense that modififying that wouldn’t work for a build
So to clarify, calling EnvironmentsApi.Instance.SetActiveEnvironment(env);
in my build script would succesfully modify my value in the Proj Settings → Services → Environments dropdown , but the build produced by BuildPipeline.BuildPlayer(...)
is not using that same environment
That sounds like a bug, does it work in debug runtime (ie without building player?)
Ill raise it up to the team. what version of everything are you using?
Core package, unity version, and com.unity.services.deployment
Sorry about that
Hey neviovalsa, I will be assisting you on that one.
I created a small repro project with thew following versions:
if (env == null) {...}
given that the function First throws if no element satisfies the predicate.using System.Threading.Tasks;
using TMPro;
using Unity.Services.Authentication;
using Unity.Services.Core;
using UnityEngine;
using Unity.Services.RemoteConfig;
public class RuntimeTest : MonoBehaviour
{
// attach this to a text mesh pro text component
public TextMeshProUGUI text;
public struct userAttributes {
}
public struct appAttributes {
}
async Task InitializeRemoteConfigAsync()
{
// initialize handlers for unity game services
await UnityServices.InitializeAsync();
// remote config requires authentication for managing environment information
if (!AuthenticationService.Instance.IsSignedIn)
{
await AuthenticationService.Instance.SignInAnonymouslyAsync();
}
}
// Create a function to set your variables to their keyed values:
void ApplyRemoteConfig (ConfigResponse configResponse) {
var env = RemoteConfigService.Instance.appConfig.GetString("test_key_env");
Debug.Log($"Environment is {RemoteConfigService.Instance.appConfig.GetString("test_key_env")}");
text.text = env;
}
async Task Awake () {
// initialize Unity's authentication and core services
await InitializeRemoteConfigAsync();
// Add a listener to apply settings when successfully retrieved:
RemoteConfigService.Instance.FetchCompleted += ApplyRemoteConfig;
// Fetch configuration settings from the remote service, they must be called with the attributes structs (empty or with custom attributes) to initiate the WebRequest.
await RemoteConfigService.Instance.FetchConfigsAsync(new userAttributes(), new appAttributes());
}
}
After this, the next step to investigate this is for you to provide the exact versions of the editor and packages you are using as Gabriel mentioned (editor, remote config package, deployment package), and also make sure you published the remote config values, because this is a common mistake we all do