I am using factories to generate Objects, however I am having trouble figuring out how to add these created object instances to the unity scene.
If I add a component of the type, it's a new instance and doesn't have the created data.
If I try and instantiate, It won't work because it's a custom class and has no gameObject.
Is there a common way to do this? or do I have to redesign how this is working?
So far the only thing I can think of is creating an Initialize method in the objects that sets all the properties, and then after the object is created and generated, I create a new Component, and call the initialize method on the GetComponent that I just added, setting the values to the values from the generated object.
Seems like a headache and bad way to do it though.
Basically I'm generating Items, using some Randomization functions to get their rarity/itemType etc, and then creating said Item using factories as I won't know what type they are until the game is already running.
I'm, in theory, trying to generate everything without any need for a database, except a sprite > object connection. But, the more and more I get into this the more I think i'm going to have to have some sort of database.
Long story short, I need the instances in the Unity scene so that when a player clicks on them he can "equip them, disenchant them, etc"
Related
I hear people talking about serializing variables among things in their unity projects and quite don't understand it. I see them using
[SerializeField]
and don't know why or what it does.
I looked up the definition of data serialization: Serialization is the process of converting the state information of an object into a form that can be stored or transmitted.
During serialization, objects write their current state to temporary or persistent storage. Later, the object can be recreated by reading or deserializing the state of the object from the store.
Objects are created as the program runs, and then reclaimed when unreachable, with a short lifespan. But what if we want to store the contents of the object permanently?
Convert it into a sequence of bytes and save it on a storage medium. Then serialization is required. [SerializeField] is to force Unity to serialize a private field. This is an internal Unity serialization function. Sometimes we need to Serialize a private or protected attribute. In this case, the [SerializeField] attribute can be used.
The above is some information I found, I hope it is correct and can bring you some help
Say, you have a field _speed and you want to set it using inspector. It means we want it to be serialized - stored somewhere in a human-readable and flexible format(e.g. xml), not directly in code. So when you edit fields in inspector, you edit the serialized data. During compilation, it's being deserialized and assigned to a field. This is how serialization/desearialization works. It is used to store non-static or just big amounts of data. In case of Unity it is used to show you everything in inspector. Transform has position and scale variables serialized and you can edit them.
In Unity there are two common ways to make fields assignable in inspector: using public fields or using [SerializedField] attribute for private ones.
Making fields public just to edit them with inspector is bad practice. If you can edit field in inspector, it means every other component can too, which is insecure. There is no good architecture that allows such things. If you want other components to edit the field, make it a property or make a set method. If you just need to assign fields by hand, don't use public fields. Avoid them.
When you use the [SerializeField] attribute, you create a private field that is accessible to this component only and you can assign it in inspector at the same time. If you need other components to read it, you can make a public property without set (public float Speed => _speed;).
This all is not an obligatory usage. Just good practice.
Any values set in the Unity inspector for any public fields or private/protected fields that use the attribute [SerializeField] are saved with the current scene file.
If you open up a Unity.scene file you will find a hierarchy of data that matches the scene hierarchy along with lists of what script or component classes are attached to that game object and what the field values of those classes/components should be.
When loading a level in Unity, the scene file is deserialized meaning that a program walks the data structure creating game objects. It then creates component and script class instances attached to those components and initializes them with the serialized data in the scene file. After that you end up with a level more or less the same as it was when saved in the unity editor.
In addition to your own Monobehaviour scripts having this ability, all the default unity components work this way. Transform uses serialized Vector3s for position, rotation and scale. MeshFilter components serialize a reference to a mesh asset and the MeshRenderer component references Materials that are used by the GPU to draw the mesh etc etc.
In short, serialisation is a process by which computers transform data so that it can be written to a file (or sent across a network via a protocol stream) and then later transformed back into the original set of objects it was to begin with (or as close as matters).
I'm working a game in Unity and I've got a Script where I save a lot of values in multiple variables, which I then use in other scripts. You could say its my GameState. The Script itself is not a GameObject, it purely exists to save values. When I start my game the "GameState" has some basic values like Name, TeamName, Money and tons of more variables which are static and filled with pre-set values.
Now comes my problem. If the player plays through the game and picks some options, functions get triggered which change the values in the GameState, like for example he'll receive more money, so the value for money in the GameState changes. But the player also has the option to completely "restart" the game by going back to the main menu (where I use a LoadScene Function). Problem is that the values in the GameState remain changed when he goes back, so when he starts a new game, he doesn't got the pre-set values, but the ones from his last game.
So my question would be, is there an easy way to reset my GameState completely to its original values? I know I could save the default values somewhere and then make a check to see if the game is reloaded to then use them, but I've already got like 60-70 variables in there and don't really want to create another 60-70 just for the default values (unless there is no other option). So does anyone have an idea how I could do that?
I don't think showing the code of the GameState does much, since its really just looking like:
public class GameState
{
//Team
public int TeamID;
public string TeamName;
public string TeamColor;
etc...
}
GameState is a class to contain data. An easy way to create default is to serialize it : add [System.Serializable] on top of the class declaration.
Now you can have say an object in your main scene called default values which has a public/serialized field of type GameState. You can set those in the editor save the scene and bam. Now to reset all the values to default you just copy the default to the current/active set of data.
If you want to expand a bit on that you can also turn the class into a scriptableObject but I don't think you need that.
public abstract class Unit
{
public abstract List<Move> allowedMoves{get;}
}
public class Javelineer : Unit
{
public List<Move> allowedMoves =>
new List<Move> {Move.Impale, Move.JavelinThrow, Move.ShieldBlock};
}
public class Dragon : Unit
{
public List<Move> allowedMoves =>
new List<Move> {Move.BreatheFire, Move.Swipe, Move.Bite, Move.Devour, Move.TailBash};
}
The X:
Given the above code, if and how can I retrieve the allowed moves of a given unit without necessarily instantiating a new object?
I know I can retrieve the property with this code:
typeof(Javelineer).GetProperty("allowedMoves")
But if and how can I retrieve the definition of this property?
The Y:
The client (web browser) must send the game server the player's unit. This includes the unit's type and moves this unit is able to perform (4 out of all available; similarily to Pokemon).
While the validation (of course) is performed on the server, the browser still needs to get a list of available unit types and allowed moves.
In order not to duplicate code, I would like to avoid hard-coding this data in Javascript.
Having read some excellent SO questions & answers I think I can retrieve all available units with code similar to this:
Assembly.GetExecutingAssembly().GetTypes().Where(
type => type.BaseType == typeof(Unit)
).Select(type => type.Name).ToList()
I'd call this code on server startup, cache the result and send the cached result to every connecting client, because I have feeling this code is likely expensive to call.
But how can I retrieve the list of allowed moves?
You have a couple of options, but TL;DR: Construct the object instance and read the property.
In any case, here are some options, creative minds might be able to find a couple more even.
Construct the instance, read the property.
This is your best option code-wise because it will be easy to understand, maintain, bugfix.
Rewrite the code to allow for easy detection of the values using reflection
One way to do this would be to use attributes, tagging the property or object with the legal moves. However, to avoid having the bug that the attributes does one thing, the code another, you might have to change the code to use the attributes as well, which would be a performance hit.
Additionally, reading those attributes would likely construct many more objects than your original object.
Use mono.cecil or some other IL-inspection library to decode the code of the property getter and finding the construction of that list, extracting the values being added to the list. You would essentially either have to dumb down the code of that property to be on par with what you have right now (and never allow it to become more complex) or basically simulate execution of code.
This is like constructing a flotilla of space warships with enough firepower to demolish a local starsystem, just to kill an ant.
Bottom line, construct the object instance, read the property.
I am building web service in C# for a particular application, I have a XML definition of module. I have created a class called Field that holds the properties of all fields on a module. What I would like to do is create the field objects but name them dynamically then add them to a list of some sort. So when I reference them from the client it would be like this:
Module.Fields.MyDynamicName.FieldProperty
Is this possible to do? and could anyone point me in the right direction on how to do this.
Hope my question makes sense.
Basically you need to design for "deferred design", which means you do not know at compile time what the design is, but you still need to accommodate it.
There are probably a few ways but what I have done in the past is use a dictionary list of Key/Value pairs to store fields. Using serialization (I prefer Json) you can shove just about anything into a string and store it as the Value, then deserialize it when you need it.
I am working to generate terrain for our project, something that will be contained in the Model class that I can draw, but I new class would be alright since I may need to look inside for specific data often, and then I would just need the basic function to work with the Game class.
Anyway, I have a fair amount of knowledge of the XNA framework, but because of how convoluted it handles anything. So my problem is I can't just make a Model, I can't instantiate that class or anything. I have what I believe the proper data to form a model's geometry, which is all I need right now, and later possibly have it textured.
I don't know where to go from here.
XNA you usually use Content.Load, to have their content pipeline read in a file and parse it specifically, but I want to avoid that because I want my terrain generated. I can compute an array of Vertex data and indices for the triangles I want to make-up a mesh, but so far my efforts have tried to instantiate any object like Model or those it contains, have failed.
If there is some factory class I can use to build it, I have no idea what that is, so if someone else can point me in the right direction there and give me a rough outline on how to build a model, that would help.
If that's not the answer, maybe I need to do something completely different, either centered on using Content.Load or not, but basically I don't want my terrain sitting in a file, consistent between executions, I want to control the mesh data on load and randomize it, etc.
So how can I get a model generated completely programmatically, to show up on the screen, and still have its data exposed?
Model and its associated classes (eg: ModelMesh), are convenience classes. They are not the only way to draw models. It is expected that sometimes, particularly when doing something "special", you will have to re-implement them entirely, using the same low-level methods that Model uses.
Here's the quick version of what you should do:
First of all, at load time, create a VertexBuffer and an IndexBuffer and use SetData on each to fill each with the appropriate data.
Then, at draw time, do this:
GraphicsDevice.SetVertexBuffer(myVertexBuffer);
GraphicsDevice.Indices = myIndexBuffer;
// Set up your effect. Use a BasicEffect here, if you don't have something else.
myEffect.CurrentTechnique.Passes[0].Apply();
GraphicsDevice.Textures[0] = myTexture; // From Content.Load<Texture2D>("...")
GraphicsDevice.DrawIndexedPrimitives(...);