I've searched through the web and seen a lot of talk about a WWW method of retrieving content from a web server or a database and using values but I would like a method where I don't have to continuously update my code in monodevelop and then build the projects as big projects sometimes take up to an hour to build so basically patching over a server.
So can the WWW method be used to do this? Like for instance lets say I have a code like this
int level;
int currentLevel;
if(level != currentLevel){
level = currentLevel;
}
Now this code is having complications because the level is not always up to date and I have to change methods into something like this so tht the level stays updated
int level;
int currentLevel;
private void Update(){
if(level != currentLevel){
level = currentLevel;
}
}
Now instead of rebuilding my entire project I would like to put this in maybe a database or some sort and then when the game launches it checks the database to make sure the code matches the code on the database if the code matches then it starts the game if not it updates
FYI I am building for WebGL HTML5
You can't do that. What you can do is to make make a decision based on what you receive from WWW but the action to do must exist already before it can used. You can't create a new action during run-time.
For example, make decision if ad should be displayed in your app.
WWW www = new WWW("url");
yield return www;
if(www.text=="AdEnabled"){
displayAd();
}
You can also run JavaScript code from Unity but that's not helpful to your question. You can't do more than that.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I was wondering... What's the best way to save data in Unity games. JSONs? If so, how? Thanks
Here are some of the different Ways and Methods to Save data for Unity Projects:
Platform-Independent: One way of saving data in Unity3D in a Platform-independent way is to use the PlayerPrefs class. PlayerPrefs is a static class and it is very easy to use but not reliable.
PERSISTENCE - SAVING AND LOADING DATA using DontDestroyOnLoad, PlayerPrefs, and data serialization Video Tutorial by unity.
Server Side: You can also use a Server for saving data (like a combination of PHP and MySQL Database). You can use it to save Score Data, user profiles, inventory, etc., Learn More From Unity Wiki. You can also use third-party solutions like firebase etc.
For saving the in-game data to a Hard drive in a format that can be understood and loaded later on, use a .NET/Mono feature known as Serialization. Learn More
Simple JSON guide about Unity is available at Unity Wiki or officially you can see JSON serialization
SQLite (an embedded database for your app) is another great option for you to get the Free Package, it is simple and easy (and my favorite) if you know SQL.
Scriptable Object: it's a data container. Useful for unchanging data. Suitable for large unchanging data and amazingly reduce your project's memory.
The above is taken from my blog post on Data Saving Techniques for Unity3d Applications.
You can use many assets that are available for free and paid in asset store.
Save Game Free - XML and JSON saving and loading.
Syntax:
Saver.Save<T> (T data, string fileName);
Example:
Saver.Save<MyData> (myData, "myData"); // The .json extension will be added automatically
Save Game Pro - Binary saving and loading. fast and secure. Easy to use.
Syntax:
SaveGame.Save<T> (T data, string identifier);
Example:
SaveGame.Save<int> (score, "score");
If you want to store your data in server there is a simple way with PHP and MySQL. What you have to do is:
STEP 1:
Get what ever data you want from your server just in single string (code is below):
<?php
//SERVER CONNECTION
$server_name = "localhost";
$server_user = "Er.Ellison";
$server_pass = "supersecretPassword";
$server_db = "game_test_db";
$connection = new mysqli($server_name , $server_user , $server_pass , $server_db);
if(!$connection) {
die("Connection failed !" . mysqli_connect_error());
}
// QUERY
$query = "SELECT * FROM items";
$result = mysqli_query($connection , $query);
if(mysqli_num_rows($result) > 0){
while($row = mysqli_fetch_array($result)){
echo "id:" . $row['id'] . "|username:" . $row['username'] . "|type:" . $row['type'] . "|score:" . $row['score'] . ";";
}
}
?>
And note that you MUST SEPARATE ANY string you want with a ; or any thing that you are comfortable with that and remember that we going to use it in C# in Unity.
STEP 2:
Now you should get the data from your web like this (it will be a long string):
STEP 3:
Now go to the Unity and create a C# script and attached that to what ever object in your scene and open the script up, then use this kind of code to manipulate the data that you retrieved from your database:
public class DataLoader : MonoBehaviour {
public string[] items;
// Use this for initialization
IEnumerator Start () {
WWW itemsData = new WWW ("http://localhost/_game/test/itemsdata.php");
yield return itemsData;
string itemsDataStrign = itemsData.text;
print (itemsDataStrign);
items = itemsDataStrign.Split (';');
print (GetDataValue(items[0] , "cost:"));
}
string GetDataValue(string data, string index) {
string value = data.Substring (data.IndexOf(index) + index.Length);
if (value.Contains ("|")) {
value = value.Remove (value.IndexOf("|"));
}
return value;
}
}
STEP 4:
You just NOW retrieved data from database, check the image from unity console:
I made this for who that may be, like me, stuck in database problems!
I'm using addressable assets to remote download a new scene from server, What I'm trying to do is to activate a play button if the addressable scene is already downloaded and in cache, and a download button if it is not in cache so that the player won't download the addressable from server every time he wants to play the scene.
I tried using Caching. IsVersionCached to check the bundle is in the cache using the bundle name but the problem here is that the name is not a good reference since in the addressable system I load the scene using Addressable. loadscene which loads the scene directly without giving any reference to the asset bundle. so the question is how to check if the scene is cached?
Here is what I tried with but it is not working since I already know that the asset bundle name won't be the good reference at least in this example.
private IEnumerator LoadRoutine()
{
var lastHash = PlayerPrefs.GetString(LAST_HASH);
if (Caching.IsVersionCached(AssetBundleHavingTheScene.name, Hash128.Parse(lastHash)))
{
Debug.Log("The Bundle is Cached i'll launch it");
Addressables.LoadScene(AddressableScene);
}
else
{
Debug.Log("Not Cached I'm going to download it");
var async = Addressables.LoadScene(AddressableScene);
while (!async.IsDone)
{
ProgressNumber.text = (async.PercentComplete * 100f).ToString("F0") + ("%");
ProgressSlider.value = async.PercentComplete;
Debug.Log(async.PercentComplete);
yield return null;
}
// At this point the scene is loaded and referenced in async.Result
Debug.Log("LOADED!");
Scene myScene = async.Result;
}
}
As far as I know, Addressable assets are automatically cached by unity and will not be downloaded twice. But you have to make sure that when you build the addressables in the unity editor, you select 'update existing build' (or similar) rather than a clean build.
But if you still want to check manually, you could use the method "Addressables.GetDownloadSizeAsync()". (Please read more about it in unity docs).
I hope it helps you a little bit.
I'm attempting to import a model created in Keras/Tensorflow and use it for inference in a Unity project.
I have successfully imported the model and validated by printing names of input and output nodes in the graph. Though, when I try to get the output value from the runner, I get this exception.
TFException: Attempting to use uninitialized value action_W
[[Node: action_W/read = IdentityT=DT_FLOAT, _class=["loc:#action_W"], _device="/job:localhost/replica:0/task:0/cpu:0"]]
TensorFlow.TFStatus.CheckMaybeRaise (TensorFlow.TFStatus incomingStatus, System.Boolean last) (at <6ed6db22f8874deba74ffe3e566039be>:0)
TensorFlow.TFSession.Run (TensorFlow.TFOutput[] inputs, TensorFlow.TFTensor[] inputValues, TensorFlow.TFOutput[] outputs, TensorFlow.TFOperation[] targetOpers, TensorFlow.TFBuffer runMetadata, TensorFlow.TFBuffer runOptions, TensorFlow.TFStatus status) (at <6ed6db22f8874deba74ffe3e566039be>:0)
TensorFlow.TFSession+Runner.Run (TensorFlow.TFStatus status) (at <6ed6db22f8874deba74ffe3e566039be>:0)
RecordArbitraryData.ModelPredict (System.Single[,] input) (at Assets/Scripts/Spells/RecordArbitraryData.cs:230)
RecordArbitraryData.FixedUpdate () (at Assets/Scripts/Spells/RecordArbitraryData.cs:95)
Here are the two functions I use. InstantiateModel is called OnStart() in my unity script. And ModelPredict is called when the user passes an input to the script.
void InstantiateModel(){
string model_name = "simple_as_binary";
//Instantiate Graph
graphModel = Resources.Load (model_name) as TextAsset;
graph = new TFGraph ();
graph.Import (graphModel.bytes);
session = new TFSession (graph);
}
void ModelPredict(float[,] input){
using (graph) {
using (session) {
//Assign input tensors
var runner = session.GetRunner ();
runner.AddInput (graph [input_node_name] [0], input);
//Calculate and access output of graph
runner.Fetch (graph[output_node_name][0]);
Debug.Log ("Output node name: " + graph [output_node_name].Name);
float[,] recurrent_tensor = runner.Run () [0].GetValue () as float[,];
//var results = runner.Run();
//Debug.Log("Prediciton: " + results);
}
}
}
Any help appreciated - TensorflowSharp is very new to me.
I was able to figure out most of my problems. I'm currently at a point where my model is predicting in unity, but only predicting the first of four classes. My guess is it has something to do with the weights not getting initialized correctly from the checkpoint files? Edit: My values weren't being normalized before being passed to neural network.
Preface: Mozilla Firefox works best for displaying tensorboard; it took me a long time to realize that google chrome was causing my graph to be invisible (tensorboard is how I was able to figure out the nodes that needed to be used for input and output).
First Issue: I was renaming a .pb file into a .bytes file. This is incorrect because the model’s weights come from the checkpoint file, and are given to the nodes held in the .pb file. This was causing the uninitialized variables. These variables were used for training, which were removed after using the freeze_graph function.
Second Issue: I was using the file created called ‘checkpoint’, which was throwing an error. I then changed the name of the checkpoint to ‘test’ and used this in the freeze_graph function. When calling the checkpoints file, I was required to use ‘test.ckpt’. I assume this function knows to grab the three files automatically based on the .ckpt? ‘Test’ without ‘.ckpt’ did not work.
Third Issue: when using the freeze_graph function, I needed to export the .pb file in keras/tf with text=False. I tested True and False; True threw an error about “bad wiring”.
Fourth Issue: Tensorboard was very difficult to use without any organization. Using tf.name_scope helped a lot with not only visualization, but making sure I was using/referencing the correct nodes in TensorFlowSharp. In keras I found it helpful to separate the final Dense layer and Activation into their own scopes so I could find the correct output node. The rest of my network was put into a ‘body’ scope, and the sole input layer in ‘input’ scope. The name_scope function prepends ‘scopename/’ to the node name. I don't think it’s necessary, but it helped me.
Fifth Issue: The version of tensorflowsharp released as a unity package is not up to date. This caused an issue with a keras placeholder for ‘keras_training_phase’. In keras, you pass this along with an input like [0] + input. I tried to do the same by creating a new TFTensor(bool), but I was getting an error ‘inaccessible due to its protection level. This was an error with the implicit conversion between bool and TFTensor in my unity TensorFlowSharp version. To fix this I had to use a function found in this stackoverflow solution where the .bytes file is read in, the placeholder for keras_training_phase is found, and is swapped out for a bool constant set to false. This worked for me because my model was pretrained in python, so it may not be a great fix for someone that’s trying to train and test the model. A condition for removing this node with the freeze_graph function would really be useful.
Hope someone finds this useful!
I've done a bit of research and i'm kind of strugguling right now.
I want to use Firebase Database functions to write datas in an editor script on Unity.
I managed to read/write in the database during the run time pretty easly (the doc online is great !), but when i try to do it on edit time, it's not working.
I've got a pretty explicit error : "Notice that DontDestroyOnLoad can only be used in play mode and, as such, cannot be part of an editor script."
Considering this error, it seems impossible to use Firebase functions here. But did someone manage to use it ?
The only solution I could think of right now is writing a python script and launching it from the unity editor, but that's not really conviniant having to deal with plenty of languages in an industrial project (unless you have no choice).
Thanks for reading and sorry for all the grammatical mistakes !
Louis
At first you should initialize firebase with new instance of FirebaseApp with unique name. I do it like this:
FirebaseApp firebaseApp = FirebaseApp.Create(
FirebaseApp.DefaultInstance.Options,
"FIREBASE_EDITOR");
The second is setup references (DatabaseReference, StorageReference etc.) with this firebaseApp instance and use it only after FirebaseApp.CheckAndFixDependenciesAsync()
Overall code will look like this:
public static void Initialize(bool isEditor = false)
{
if (isEditor)
{
FirebaseApp firebaseApp = FirebaseApp.Create(
FirebaseApp.DefaultInstance.Options,
"FIREBASE_EDITOR");
firebaseApp.SetEditorDatabaseUrl("https://project.firebaseio.com/");
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
if (task.Result == DependencyStatus.Available)
{
database = FirebaseDatabase.GetInstance(firebaseApp).RootReference;
storage = FirebaseStorage.GetInstance(firebaseApp).RootReference;
auth = FirebaseAuth.GetAuth(firebaseApp);
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + task.Result);
}
});
}
else
{
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://project.firebaseio.com/");
database = FirebaseDatabase.DefaultInstance.RootReference;
storage = FirebaseStorage.DefaultInstance.RootReference;
auth = FirebaseAuth.DefaultInstance;
}
IsInitialized = true;
}
Initialize SDK for editor before get/set data:
FirebaseManager.Initialize(true);
Then after CheckAndFixDependenciesAsync callback you can use Firebase in editor scripts.
I dont know if it is even possible, but is there some way how to "end" page in Windows Phone 8 app?
My problem is that i am using one delegate (to know when is my xml downloaded) on multiple pages. It works fine, but when i open one page, she initialize herself, i go on other page (trough back button) and new page initialize herself too. Everything is fine, but the previous page is still listening to the delegate and it is really big problem. So i need to get the previous page (that closed) into a same state like she was not ever opened.
I will be thankful for any advice (maybe i am thinking in wrong way now, i dont know, maybe the page just have to be de-initialize).
PS: If its necessary i will post the code, but i think it is not. :)
Okey here is some code:
In class whis is downloading XML i have delegate like this:
public delegate void delDownloadCompleted();
public static event delDownloadCompleted eventDownloadCompleted;
This class is downloading few different xml files depends of constructor in run(int number) method.
After is download complete and all information from xml are saved in my local list i call delegateCompled. if (eventDownloadCompleted != null)
{
eventDownloadCompleted();
}
Then i have few different pages. All pages are used for display specific data from downloaded xml. So on this specific page I have method that is fired when "downloadClass" says it is complet.
XML_DynamicDataChat.delDownloadCompleted delegMetoda = new XML_DynamicDataChat.delDownloadCompleted(inicialiyaceListu);
XML_DynamicDataChat.eventDownloadCompleted += delegMetoda;
This is that "inicializaceListu" method:
private void inicialiyaceListu()
{
Dispatcher.BeginInvoke(() =>
{
model = new datka();
// object model is just model where i am saving all specific list of informations that i got from xml files.
chatList9 = model.getChat(1);
gui_listNovinky.ItemsSource = chatList9;
gui_loadingGrid.Visibility = Visibility.Collapsed;
});
}
All of these works fine, but when i go back (with back button) and open other specific page with other specific information from other downloaded xml, previous page is still listening for the delegate and inicialiyaceListu() method is still fired everytime i complete download of xml.
So i need to say previous page something like: "hey page, you are now closed! Can you shut the **** up and stop work?!?"
I think that specific delegate for each pages could solve this, but it is not correct programing way.
I solved it nice and easy. It is really simple solution. I just created bool variable and set it false when i go back. In inicializaceListu() i have condition if it is true. If it is true do that stuffs when false do nothing.