Build an AssetBundle runtime - c#

I'm using Unity and I need a button that calls a function that allows me to build an AssetBundle, so I can make a software external from unity that allows me to build AssetBundle; is it possible?
Thank you all.

Build an AssetBundle runtime
This can not be done. bulding assetbundles requires the buildPipeline which is in the UnityEditor namespace which can not be accessed at runtime as it is editor only.
Making an external application for this that you call from within Unity would most likely also not work unless you know how to replicate their pipeline in your own application, and i doubt you will be able to call it form outside Unity (And even if you could it would still not work at runtime as assets will become read only)
I'm not sure why you would want to build assetbundles at runtime, but the only method i can think of that may work for this would use JSON/XML.
This would need two Instances of unity running to do it in "real time". The first instance of unity would be running your game with the object you want to make into anassetbundle. After clicking your button a function would be called that gets all the information on your GameObject (components, values, ID's, literally everything) and parse it into a XML/JSON file. This file will then be uploaded/saved somewhere where your second Unity instance can access it. The second instance of unity will then read this JSON/XML file in editor time, reconstruct the original GameObject from the data within (This can be done in editor time from script) and then put this reconstructed object through the assetbundle pipeline.
Do take note though that i've never done this myself, and am not 100% it will work. Though i am fairly confident if done correctly it should work.

Related

Unity make ScriptableObject on a build

I'm new to scriptable objects, but I've seen a lot of tutorials using them for an inventory system and recipes. My question is if it is possible for a future player of my game to create new "recipes" in the final build that will be saved as scriptable objects. Similar in Minecraft where you can use data packs to create new recipes.
ScriptableObjects aren't really intended to be used that way. They are assets in your build, just like objects saved in your scenes during edit time.
One option could be to try to save them as Addressables or AssetBundles so the game could load them dynamically. I don't think any of those facilities are available at runtime, so you would have to jump through a lot of hoops to get the storage format correct. I'd recommend against that and just use regular object serialization to save stuff.
It's worth noting, when you run your game in the editor and directly update your ScriptableObjects at runtime, it will update the asset and will save with the project. Although it might seem like its working, that only works in the editor. In a real build of your game it will not be saved, and will have it's original values every time you start your game (just like the scene objects all return to their original states).

How do I make copies of a Node in Godot

I'm new to Godot coming fresh from unity and I cant figure out how to duplicate an object/node. I've tried the duplicate function to no effect. My most recent attempts try to create child nodes with the same property as the parent. I cant seem to get anywhere, help would be appreciated. Here is my code that tries to create a child node:
Node copynode = new Node();
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
copynode = this;
for (int i = 0; i < 5; i++)
{
AddChild(copynode);
}
}
Also could someone tell me what the object/node/item in the scene is actually called and how to reference it? Is it a Node or a Gamedot.Object or something else? And how do I get and set its properties? I'm just really used to unity and cant figure this stuff out. The only tutorials I find are in the Godot language, and I kind of know c# already so I would prefer to program in that.
Nodes are references
I believe you expected Node to behave as a value type, but actually it is a reference. Let us over what happens:
Here you declare a variable of type Node, and initialize it to a new Node:
Node copynode = new Node();
And then here you overwrite it with the Node on which this script is being executed:
copynode = this;
And then you try to add the Node as child of itself five times:
AddChild(copynode);
Which, of course, does not work. And you do that five times.
Let us be glad this does not work. Because if it did, you have a Node that makes five copies of itself, which each also make five copies of themselves, and you can imagine how that goes. Which is why I will not give you some code to do it.
As you are aware there is a duplicate method. I suspect you expected it to add the duplicate to the scene tree. However it does not do that. Instead it returns the duplicate, and you have to add it (or do something else with it).
Your questions
Also could someone tell me what the object/node/item in the scene is actually called and how to reference it?
I'm not sure what you mean. However, if it helps, this will refer to the object on which the script is executing.
Is it a Node or a Gamedot.Object or something else?
The class Godot.Node inherits from Godot.Object. If you attached a script to a Node the class of your script must inherit form the type of the Node, which could be Godot.Node or a class that inherits from Godot.Node. I hope that helps.
And how do I get and set its properties?
You get and set them like any C# property. Although you should be able to use the Get and Set methods too, but that is intended for dynamic code.
If what you are looking for is how to make the properties available in the inspector panel, you do that by adding the [Export] attribute. For example:
[Export]
public float Speed;
And it should appear in the inspector panel when the object that has the script is selected.
The only tutorials I find are in the Godot language, and I kind of know c# already so I would prefer to program in that.
Most of the tutorials are in GDScript because:
There are two Godot builds. One with C# and one without it. But both can use GDScript. Thus GDScript is useful regardless of which build you are using.
Translating from GDScript to C# is not difficult. It is mostly the naming convention (and some edge cases, which you are probably not encounter when you are beginning). See C# API differences to GDScript.
The way C# is used with Godot follows C# conventions. I'd argue that it follows them closer than Unity. Although there are some rough edges when it comes to signals and async methods.
See the video Intro to C# in Godot 3.1: Your First Script (tutorial) by GDQuest.
I'll also recommend the underrated video Godot C# Delegate Tutorial.
And hare some YouTube channels have some C# Godot content that I've found: FinePointCGI, BurgZerg Arcade, Abdullah, BeIndie - Alan Thorn, Godot Academy.
Some advice for Unity developers arriving to Godot
Since you are familiar with C#, go ahead and use C#.
By the way my personal recommendation is to use an external editor (such as Visual Studio or Visual Studio Code, for which there are some good plugins for Godot) instead of using the integrated one. Because - even thought C# is fully supported - C# is poorly integrated with the editor.
Also be aware it is OK to use both C# and GDScript on the same project, or Godot visual scripting, or other languages that can be added to Godot (or even C++ if you really want to). How much C# you use is up to you.
Thus, you can use each language to their strength. For example you can use C# to get some extra performance compared to GDScript, and have access to all the .NET libraries and some modern language features. And use GDScript as glue with the rest of Godot (e.g. exporting variables and connecting singals, and calling into C#).
If you decide to combine GDScript and C# be aware the GDScript cannot properly consume C# async methods. My advice for that is to design around signals when they need to interact asynchronously.
Before you ask how to use components. There are multiple ways to build a component system on top of Godot, but it does not include one. And you probably don't need them. Most of what Unity does with components is done in Godot with Nodes instead.
Furthermore, coming from Unity, you might be expecting some distinction between "prefab", "scene" and "node". There isn't. An scene can have other scenes inside, and the scenes are nodes. And as I said, you will use nodes instead of components.
That does not mean that everything is nodes. You absolutely can make classes that are not nodes. It can be in particular useful to make resource classes, but that is its own topic.
Although, scenes are nodes, there is an slight distinction: a scene is a node that is serialized. Thus if you want to create a whole thing that can be instantiated multiple times, then you want to create a scene. And then you can add that scene as a node - which it is - inside of another scene. Similarly when you import model that you can place in a scene… the models are scenes.
There is an example of loading and instantiating a scene:
var scene = (PackedScene)ResourceLoader.Load("res://scenes/Scene.tscn");
Node scene_instance = ground.Instance();
AddChild(scene_instance);
I don't know if that is what you are trying to do with your code, but I figured I'd mention it, just in case.
Are you looking for an asset store. Godot does not have an asset store, because it sells you nothing. Instead it has an asset library, that you can access from the "AssetLib" button at the top of the editor. To reiterate, everything there is free, it sells you nothing. If you want some comercial assets, you will have to find them elsewhere.
Which reminds me, the preferred format for 3D models in Godot is GLTF (which is an open standard - not a proprietary format like some others).
Godot has a way
Some times when people go from one tool to another they try to stick to how they used the old tool. For an easy example, you don't need to make complex math to position an object relative to another, you just make it a child… But if you can't make it a child? There is RemoteTransform node that can do that. No code involved.
Godot is full of features hiding just below the surface, and there is value in discovering them. And if you are struggling with something, perhaps there is a Godot way. And if there isn't, it can be added.
I'll tell you one that is particularly powerful: the AnimationPlayer node can animate any exported property. In fact, it can call methods. It can also start animations in other AnimationPlayers.
By the way, it goes without saying, but: for whatever code you find online, try to understand the reasoning behind it. It will save you trouble when it does not work and you have to figure out how to fix it.
The base node class is invisible (gray) so you cannot see if they were added or not. You can switch from the local to the remote tab in the scene tree while running to see only one invisible node added.
If you change the code to AddChild(copynode).Duplicate(); you can see it adds all 5 invisible nodes.

Recovering inspector values from Unity build

I made the stupid mistake of moving a C# script out of the project and back in. This, of course, cleared all of the important inspector values back to their default values from the script.
All I need is to see those values again and re-enter them. I attempted decompiling the assembly-csharp.dll from my last build using dotPeak. While this did recover the correct classes and their fields, all of the fields are not defined. Where in a Unity build are these values stored, and is it possible to decompile them there?
Thanks in advance!
As far as I know there are stored in the scene file (.unity) or, if it's a prefab, in the prefab file (.prefab) (and if it's a prefab in the scene, it's stored in the prefab file with a list of modifications in the scene file). You might have success finding some values in there, but those are serialized and you can only really read them with Asset Serialization Mode "Force Text". It might also be that they lose their value when you open Unity between moving the script out and moving it back in.
Edit:
I missed the part that you wanted to read them from the build. I don't think that's possible, as they are normally serialized (if they are not in Streaming Assets). As scene files (which I think would contain the data) are also just files and not scripts that get compiled, I think the values are in one of the serialized files.
Also: You don't happen to have any kind of version control? Because then you could rollback to an old commit that contains that data, or if that's not possible look at the specific file in question.

Can't load Mono.CSharp.dll in either Unity3D or a C# project

I'm working on an online video game project using Unity3D for the clients, and C# servers.
I'm trying to use some code eval for a specific feature, but I can't get it to work.
I went with Mono, because it seemed to be one of the lightest and one of the simplest. I installed Mono and got the "Mono.CSharp.dll" for .Net 4.6 from "Mono\lib\mono\4.6-api". (Both Unity and my servers are configured to use this version of .Net). I dropped it in the Unity assets, and referenced it on my servers.
But I have errors on both Unity and the servers. In Unity there is :
Loading script assembly "Assets/Scripts/Common/References/Mono.CSharp.dll" failed!
And there is an exception on the servers (my IDE is in French so I can't really copy/paste it), but it basically tells me it can't use Reference Assemblies for build, but only for reflection.
To describe the feature I want to create (because you'll maybe have a better solution), I want to be able to create spells from an external tool. Spells are made of SpellEffects. Let's say there is a SpellEffect called DealDamage, constructor takes an int (for the damage amount). I want to be able to write "DealDamage(50)" on my external tool, then take the string, and build a new DealDamage(50) from it.
I know I could find a way to interpret some code by myself, but it would be a lot more work for a far less flexible system.
It was really hard to find any help online for this problem, so as a last hope I'm turning to you.
I'm not exactly sure why you're trying to import Mono into Unity. It's already included in the installation package. If you want to make a modular spell builder, just create a regular application with your preferred language, in your preferred IDE, and save all of your spells as a JSON or XML file, and then import those into Unity. On the Unity side, just build a class to parse the files.
To get you started, take a look at the JSON.Net library. You can serialize your files into C# classes with it.

Unity Asset Bundles backward compatibility

I am working in a project, and we use Unity3D ... we are loading our Asset Bundles Dynamically. But we want to add the backward compatibility between the versions of our app.
Let's say that I release version 1.05.0 and the user loaded a certain Asset Bundle, After that the user downloaded version 1.06.0 which contains some changes in some scripts that were used in version 1.05.0
Could I make version 1.06.0 work with the same Asset Bundle of version 1.05.0 ?!
or that is not doable ?!
Thanks in advance
"Some changes in some scripts" is quite vague.
Generally speaking, asset bundles do not include scripts directly, but they do include references to scripts (which may be corrupted if you move your scripts) and to properties (which may get complicated if you refactor). Unity Answers does have some more detailed information.
If all you did was some minor tweak to the Update() function of some script, you should be fine.
If you renamed your scripts or moved scripts between assemblies, you will likely have a problem.
If you create new serialized fields, an older asset bundle will not contain those fields, and they will receive their default value upon instantiation.
If you remove existing serialized fields, they will be ignored upon instantiation.
If you rename or change the type of existing serialized fields, Unity will "try" to reconcile that, but I wouldn't count on it working.
If you're looking for a more robust system, you might be better off attaching "plain old data" components just to serialize your data, then using that data to reconstruct your assets at runtime.

Categories

Resources