Hi guys,
Im stuck for 3 hours for this now. i dont know whats wrong. whatever i do, i always get null for every getstring i requested from the remote config dashboard.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Unity.RemoteConfig;
using UnityEngine.SceneManagement;
namespace TanksMP
{
public class VersionControl : MonoBehaviour
{
public Text message;
public GameObject okButton;
public FeatureRandomizer feature;
void Start()
{
ConfigManager.FetchCompleted += ApplyRemoteSettings;
okButton.SetActive(false);
}
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
void ApplyRemoteSettings(ConfigResponse configResponse)
{
switch (configResponse.requestOrigin)
{
case ConfigOrigin.Default:
Debug.Log("No settings loaded this session; using default values.");
string[] defaultStoreItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
feature.readList(defaultStoreItems);
gameObject.SetActive(false);
break;
case ConfigOrigin.Cached:
Debug.Log("No settings loaded this session; using cached values from a previous session.");
break;
case ConfigOrigin.Remote:
Debug.Log("New settings loaded this session; update values accordingly.");
bool outdated = true;
string[] str = ConfigManager.appConfig.GetString("live_version").Split(';');
for (int a = 0; a < str.Length; a++)
{
if (str[a] == Application.version.ToString()) outdated = false;
}
if (outdated)
{
message.text = "<size=22>Version Outdated</size>\nUpdate to the latest version to play the game.";
okButton.SetActive(false);
}
string[] storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
feature.readList(storeItems);
message.text = ConfigManager.appConfig.GetString("message");
if (message.text == "") gameObject.SetActive(false);
okButton.SetActive(true);
break;
}
}
}
}
but i sometimes i get “incomplete” strings. for example, i use the remote config for item rotation. i would store all the items in a string and split them into array. when i get the array, it sometimes only get the first string. for example
storeItem[0] = itemA
storeItem[1]-[13] = null
at first i thought theres error in my script. but when i test it again, it worked. it only happen sometime.
Can you share the full script that you are using, and the corresponding dashboard settings? Are you receiving the full string, but the parsing fails? I doubt that we would return only the first x number of characters from a string, but we can check.
Can you show a screenshot of your value for store_item in the Dashboard? Also, please Debug.Log the full value of the local store_item variable, prior to the Split. And your default value for storeItems is not a single string, it’s an array of strings, and may be why you are only seeing the first value.
how can the parsing sometimes fail and sometimes it succeed? the parsing works fine IF it gets the full string from the appconfig. it only returns error if it fetches incomplete appconfig.
here is the new version of the script
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using Unity.RemoteConfig;
using UnityEngine.SceneManagement;
public class VersionControl : MonoBehaviour
{
public Text title;
public Text message;
public GameObject okButton;
public GameObject restartButton;
public FeatureRandomizer feature;
public Text version;
public struct userAttributes
{
// Optionally declare variables for any custom user attributes; if none keep an empty struct:
}
public struct appAttributes
{
// Optionally declare variables for any custom app attributes; if none keep an empty struct:
}
void Start()
{
version.text = Application.version.ToString();
restartButton.SetActive(false);
okButton.SetActive(false);
StartCoroutine(queuedVersionCheck());
}
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
ConfigManager.FetchCompleted -= ApplyRemoteSettings;
}
IEnumerator queuedVersionCheck()
{
yield return new WaitForSeconds(1);
ConfigManager.FetchCompleted += ApplyRemoteSettings;
ConfigManager.FetchConfigs<userAttributes, appAttributes>(new userAttributes(), new appAttributes());
yield return new WaitForSeconds(10);
restartButton.SetActive(true);
}
void ApplyRemoteSettings(ConfigResponse configResponse)
{
string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
string[] str= {""};
switch (configResponse.requestOrigin)
{
case ConfigOrigin.Default:
Debug.Log("No settings loaded this session; using default values.");
gameObject.SetActive(false);
break;
case ConfigOrigin.Cached:
Debug.Log("No settings loaded this session; using cached values from a previous session.");
storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
str = ConfigManager.appConfig.GetString("live_version").Split(';');
break;
case ConfigOrigin.Remote:
Debug.Log("New settings loaded this session; update values accordingly.");
storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
str = ConfigManager.appConfig.GetString("live_version").Split(';');
break;
}
bool outdated = true;
for (int a = 0; a < str.Length; a++)
{
if (str[a] == Application.version.ToString()) outdated = false;
}
if (outdated)
{
title.text = "Version Outdated";
message.text = "Update to the latest version to play the game.";
restartButton.SetActive(true);
}
else
{
StopAllCoroutines();
okButton.SetActive(true);
title.text = ConfigManager.appConfig.GetString("title");
message.text = ConfigManager.appConfig.GetString("message");
if (message.text == "") gameObject.SetActive(false);
}
ConfigManager.FetchCompleted -= ApplyRemoteSettings;
if (storeItems.Length < 13) RestartGame();
else StartCoroutine(feature.readList(storeItems));
}
}
then the storeItem is sent to featurerandomizer below. as you can see, the game restarts when storeitem.length is less than 13.
when i run it, yes, the game restarts. that means it fetches incomplete strings.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class FeatureRandomizer : MonoBehaviour
{
public IAPProduct[] FeatureCards;
public IAPProduct[] InventoryCards;
public IEnumerator readList(string[] storeList)
{
for (int a = 0; a < FeatureCards.Length; a++)
{
populate(System.Convert.ToInt32(storeList[a]), a);
yield return null;
}
}
void populate(int rand, int index)
{
FeatureCards[index].id = InventoryCards[rand].id;
FeatureCards[index].partCategory = InventoryCards[rand].partCategory;
FeatureCards[index].value = InventoryCards[rand].value;
FeatureCards[index].transform.GetChild(0).GetComponent<Image>().color = InventoryCards[rand].transform.GetChild(0).GetComponent<Image>().color;
FeatureCards[index].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite = InventoryCards[rand].transform.GetChild(0).GetChild(0).GetComponent<Image>().sprite;
FeatureCards[index].transform.GetChild(0).GetChild(1).GetComponent<Text>().text = InventoryCards[rand].transform.GetChild(0).GetChild(1).GetComponent<Text>().text;
FeatureCards[index].transform.GetChild(0).GetChild(2).GetChild(0).GetComponent<Text>().text = "BUY FOR " +UnityIAPManager.productHandler.products.WithID(InventoryCards[rand].id).metadata.localizedPriceString;
InventoryCards[rand].pairFeatureSoldButton = FeatureCards[index].transform.GetChild(0).GetChild(3).gameObject;
InventoryCards[rand].pairFeatureBuyButton = FeatureCards[index].transform.GetChild(0).GetChild(2).gameObject;
if (PlayerPrefs.HasKey(Encryptor.Encrypt(FeatureCards[index].id)))
FeatureCards[index].Purchased();
}
}
Because you are using the default string if you execute the ConfigOrigin.Default switch condition, which is an array of strings and Split only finds the first one. If you receive data from the server, it looks like you may be using a single string with a semicolon separator, and Split works as expected. Please share the value of the variables as set on your Dashboard and the Debug.Log values at runtime, as requested. Debug.Log statements will show in the logs, you can also use breakpoint debugging from Visual Studio. Let’s see what the full string is, prior to your split attempt. Correct, we would not be sending only the first N characters of a variable.
Sorry no, because in one case, you are using the local array, and in the other switch condition, you are not and using the remote value. So it would behave differently in each case. As requested, please provide the output of your Debug.Log statement as mentioned. You are Splitting on a semicolon, and there are none in your local string array. I suspect there are, in your remote variable value. Debug.Log statements will show in the device logs, or you can use breakpoint debugging in Visual Studio to confirm https://discussions.unity.com/t/699654 This post may help also https://discussions.unity.com/t/748729/14
As I suspected, a single string separated by semicolons. Your local/default array of strings does not. A Switch statement is the same as a series of IF statements, and the behavior of the app in your case will be different depending on which path through your Switch statement is taken, and is why you see different behavior. I would encourage you to use Debug.Log as I mentioned, I believe it will be become clear.
no the switch is not the case. the switch always debugged “New settings loaded this session; update values accordingly.”
also there is nothing wrong with my local string as
void ApplyRemoteSettings(ConfigResponse configResponse)
{
////here is my local string. as you can see it doenst have semicolon because its an array. see next comment
string[] storeItems = { "6", "4", "7", "12", "16", "18", "3", "5", "2", "13", "5", "9", "20" };
string[] str= {""};
switch (configResponse.requestOrigin)
{
///doesnt need to do anything, just load the local string
case ConfigOrigin.Default:
Debug.Log("No settings loaded this session; using default values.");
gameObject.SetActive(false);
break;
case ConfigOrigin.Cached:
////load the cached appconfig string
Debug.Log("No settings loaded this session; using cached values from a previous session.");
///then we convert the appconfig string into an array and store it in storeitems
storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
str = ConfigManager.appConfig.GetString("live_version").Split(';');
break;
case ConfigOrigin.Remote:
///load the new value from the appconfig
Debug.Log("New settings loaded this session; update values accordingly.");
///and then we convert the appconfig string into an array and store it in storeitems
storeItems = ConfigManager.appConfig.GetString("store_item").Split(';');
str = ConfigManager.appConfig.GetString("live_version").Split(';');
break;
}
the parse only happen inside the switch and at the end of the switch, the string is converted into array and stored in storeitems.
Please be aware of Release vs Development. The Editor’s Play mode always uses the Development environment settings. Your screenshot was Release. Are you testing on an Android device or in the Editor?
Hi, I have just updated my Unity RemoteConfig because Unity RemoteSettings will be depriciated next year May.
And guess what, its not working again as-usual as this Unity keeps buggier and buggier.
I just followed this tutorial from your youtube channel:
I tried to get int and doesn’t get my original values.
Any idea? you guys have no idea how buggy Unity is. or your aware, I installed unity 10 times all failed just for installation on this new unity 2019 i took me 3 days. then building ilc2pp using your ndk too is buggy. it does not download the required ndk as it promises.
Hope this new remote config has a solution cause like the struggles I have before. at default IT DOES NOT WORK.