What I'm trying to do:
When I press the play button appears the panel with +. I made a simple script for the + button
public void addSave()
{
if (i != 0)
{
File.Delete("Assets/Game1.unity");//If there is already a save then delete it
i = 0;
}
if (i == 0)
{
File.Copy("Assets/Game.unity", "Assets/Game1.unity");//And copy the scene to make the new one.
OpenSave.SetActive(true);
i++;
}
}
When I press on it has to load the Game1.unity but it says: "Scene 'Game1' couldn't be loaded because it has not been added to the build settings or the AssetBundle has not been loaded." So how do I add it to the build settings in the script?
I've found this but how do I make a new scene before the gameplay?
Edit: I've added the Game1.unity to build settings manually so the + button just resets the game. But maybe there is a better way to do this?
Or maybe there is a better way to do this?
You shouldn't be using scenes to save and load your game. Actually it is better to use just a master scene for everything (Unity scene system is ugly and slow).
You can use any serialization method depending on your needs such as xml, json,protocol buffers or the ones in the Asset Store. Serialization is much more flexible and manageable for these kind of things.
Related
I'm working on a Cities: Skylines mod and I want to access the sharedassets.assets file(s) the game has in the Data folder programmatically to get a mesh/prefab.
I've found a tool called Unity Assets Bundle Extractor (UABE) and it is able to open up these files and extract the mesh.
Is there a way to extract a mesh from the sharedassets programmatically with C# code like UABE does?
I've looked in the Unity documentation but so far only have seen this page (not sure if relevant): https://docs.unity3d.com/ScriptReference/AssetBundle.LoadFromFile.html
I tried adapting the code from there but I haven't had any success so far, only have had not found error messages
var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, "sharedassets11"));
Is there a way to achieve this? Thanks
Look at the API for AssetBundle.LoadFromFile.
There is a second method AssetBundle.LoadAsset (or alternatively also maybe AssetBundle.LoadAllAssets) you will need:
var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.dataPath, "sharedassets11"));
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
return;
}
var prefab = myLoadedAssetBundle.LoadAsset<GameObject>("NameOfTheAccordingObject");
Instantiate(prefab);
myLoadedAssetBundle.Unload(false);
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 currently using GameObject.Find() to retrieve an object generated by the Mapbox Unity SDK. The code works fine in the editor, but when I build the project it returns null. The offending code is the following:
GameObject go = GameObject.Find ("16/32699/21126");
if(go != null) {
//do the thing
} else {
Debug.Log("the tile doesn't exist");
}
I've tried building in both WebGL and Native OSX, both with the same result.
in the editor, the exact name of the object I'm looking for in the scene hierarchy is 16/32699/21126. I appreciate that using the forward slash is how you search for sub-children in unity, but it seemed to work fine in the editor.
below is a screenshot of the scene hierarchy.
The behaviour script is attached to the Map object.
Do you know what could be causing this, or if there is another way of searching for the object I'm after?
You can directly access the tile through the map visualises..
example code.
UnwrappedTileId unwrappedTileId = Conversions.LatitudeLongitudeToTileId(latLon.x, latLon.y, (int)_mapManager.Zoom); //either use lat,lon or other way to get unwraptileid
var tile = _mapManager.MapVisualizer.ActiveTiles[unwrappedTileId];//_mapManager is your abstract map
//active tiles is the dictionary created by mapbox sdk to track which tiles are active
if(null!= tile)
{
myModel.transform.SetParent(tile.transform, true);
}
else
{
Debug.Log("Map tile is null");
}
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.
I have a method that gets called when a button is pressed,
private List<Page> _pages = new List<Page>();
public void LoadKern(int requestedKern)
{
TextAsset pages = Resources.Load("kern" + requestedKern) as TextAsset;
JSONArray jsonPages = JSON.Parse(pages.text)["pages"].AsArray;
foreach (JSONNode page in jsonPages)
{
_pages.Add(new Page(page["image"], page["text"]));
}
ImageSpriteRenderer.sprite = Resources.Load<Sprite>(_pages[currentPage].image);
TextSpriteRenderer.sprite = Resources.Load<Sprite>(_pages[currentPage].text);
}
The code works perfect when running it in the simulator but whenever I deploy it to an android device or use the Untiy Remote 4 it no longer updates the sprites.
Whenever I remove this line and set the resource manually, it does update when the button is pressed.
_pages.Add(new Page(page["image"], page["text"]));
It seems very odd that it does work on a desktop but not on Android, is there something I am missing?
I think it difficult to put it in the comment, so I write it as an answer here.
The simplest approach to verify this a problem due to the Resource.Load<>, is to add below code:
TextAsset pages = Resources.Load("kern" + requestedKern) as TextAsset;
Debug.Load(pages + "are Loading"); // to see if it is really loaded successfully
Connect your device and open the adb log, filter the message with "are loading".
If you see pages are null, then it is clear that Resource.Load<> is the culprit.
If it is Resource.Load<> problem, you can consider using StreamingAssets:
Any files placed in a folder called StreamingAssets in a Unity project will be copied verbatim to a particular folder on the target machine. You can retrieve the folder using the Application.streamingAssetsPath property. It’s always best to use Application.streamingAssetsPath to get the location of the StreamingAssets folder, it will always point to the correct location on the platform where the application is running.
On Android, you should use:
path = "jar:file://" + Application.dataPath + "!/assets/";
I suspect that your loading the text assets is carried out at runtime, when you package the app, the text assets are not read, and it might be excluded from the project, as Unity considers this "not used". When you run the app on Android, it is natural that it fails.
Using StreamingAssets approach, you force Unity to copy the text assets "verbatim" which assures it is accessible at runtime!