benArcen

Unity Questions Thread

Recommended Posts

I thought it would be a good idea to have a thread where those who are getting started with Unity can go to ask questions about working in the engine. I write my script in C# so I suppose someone else will have to answer questions about Java/Unity Script.  After I get out of class, studying, and homework I'm usually working in Unity and don't mind helping out.

 

Unity does have an official Answers website where you can ask questions and get answers from the community but it does not lend itself to discussion and I remember not wanting to post questions there when I first began.

 

 

I only ask the following of those asking questions because I really don't have a lot of experience with other development solutions other than Python and Pygame which basically requires you to code your own game loop and "engine". I've heard that Boo is similar to python so I may be able help you out there as well but I honestly don't see anyone choosing to use Boo over JS or C#...

  • Questions should be concerned with Unity or:
    • C#/JavaScript/Boo scripting
    • Asset Store Development Tools
    • Development tools not found in the Asset Store but used in conjunction with Unity (Importing assets, using pixel editor program to implement pixel-perfect camera setup...)

 

 

Share this post


Link to post
Share on other sites

I should say that the one question I asked on the Unity website actually turned out pretty well. The folks there can come off a bit curt, but they know their stuff and they want to help.

 

That being said, I'm decent at C# so I'd be happy to help with that at least.

Share this post


Link to post
Share on other sites

I haven't asked anything on Unity Answers but I've been getting helpful stuff from there just by googling.

 

    • Asset Store Development Tools
    • Development tools not found in the Asset Store but used in conjunction with Unity (Importing assets, using pixel editor program to implement pixel-perfect camera setup...)

 

1. Are there any asset store things you recommend?

2. what do you mean by "using pixel editor to implement pixel-perfect camera setup"? and any recommendations here too?

 

I know a bunch of these tools are probably specific to the kind of game one is making, but I also keep finding Unity features/abilities I wasn't aware existed

Share this post


Link to post
Share on other sites

One thing you may find essential is a UI plugin from the Asset Store.  But if I were you, i'd hold off on UI for a while, because they've been working on implementing a new GUI system based off of NGUI.

 

As for C# vs javascript, just use C#.  Almost all the examples are going to be written for C# anyways.

Share this post


Link to post
Share on other sites

This may sound a bit... dumb. But, concerning C# vs Javascript... since everything is in a bunch of seperate scripts anyways, is there any serious downfall to having say one script being C# and another completely different script being in Javascript? Or should I go and convert one to the other so everything's the same? (Actually I should do that anyways just for tidiness and cleanness sake...)

Share this post


Link to post
Share on other sites

They can interoperate with each other, but your code will be a lot cleaner if it's all one language.  I wouldn't let that hold you back from using good javascript libraries or example code from other games.  I also wouldn't rewrite significant pieces of code just to make them match the rest of your code base.  But I'd definitely recommend just sticking with one language so you don't have to context shift constantly.

Share this post


Link to post
Share on other sites

So, in my space trading sim, I have multiple planets (5 now, up from 3 last week) with multiple commodities for sale (7 at this point, up from a single one last week.) Each commodity has several relevant stats, so I created a 7x6 array inside the PlanetEcon script to hold all the pricing, stock, and production information. Back when I was working with just one commodity, it was easy to create several public variables that I could set in the inspector different for each planet. Now that I'm working with a 2D array, it doesn't show up in the inspector anymore, so I've had to make seven 1d arrays, set the values in the inspector, then push those values into the 2D array that I'm actually working with.

 

All this has shown me that I really shouldn't be using the inspector to set initial values for these variables anyway, but I'm not sure how to go about doing so. Since the same script is used for each planet, I can't set the variables inside the script. Should I be setting up an initialization script floating out in the scene somewhere, or maybe a different initialization script attached to each planet? How to I handle this without making the entire array public?

Share this post


Link to post
Share on other sites

All this has shown me that I really shouldn't be using the inspector to set initial values for these variables anyway, but I'm not sure how to go about doing so. Since the same script is used for each planet, I can't set the variables inside the script. Should I be setting up an initialization script floating out in the scene somewhere, or maybe a different initialization script attached to each planet? How to I handle this without making the entire array public?

 

In the scene you could have something called PlanetInfoModel that you reference to get the info for each planet. You can then set up an enumerated type (enum) to identify individual planets, and pass that ID to the PlanetInfoModel to get the planet's info. If you want me to elaborate with some code snippets I can.

Share this post


Link to post
Share on other sites

So you're saying to set up an enum with all the planet names in it as members, then make a 3d array (one 2d array for each planet, the third dimension being the enum) and then have each planet individually call PlanetInfoModel and provide its name, which then spits back out the 2d array for that particular planet?

Share this post


Link to post
Share on other sites

So you're saying to set up an enum with all the planet names in it as members, then make a 3d array (one 2d array for each planet, the third dimension being the enum) and then have each planet individually call PlanetInfoModel and provide its name, which then spits back out the 2d array for that particular planet?

 

Yeah, this will work. To maybe give you a few more ideas I'll drop some code snippets based around how i might do it maybe to give you some ideas.

 

We'll start with out enum:

public enum PlanetID
{
  Zorgulon = 1,
  Xanzibar = 2,
}

Then we'll create our planet model and have an easy way to access it:

 

public class PlanetModel : GameObject
{
  public static PlanetModel instance;
  void Awake()
  {
    instance = this;
  }
}

Now from other classes we can easily access PlaentModel by calling PlanetModel.instance (make sure you have a PlanetModel in the scene though).

 

We might then instead of using a series of arrays create an object to store planet's data:

 

public class PlanetData : object
{
  PlanetID planetID;
  int [] resourceOne;

  //this constructor allows us to initialize the data when we create it
  public PlanetData(PlanetID planetID, int resourceOne)
  {
    this.planetID = planetID;
    this.resourceOne = resourceOne;
  }
}

Then at the top of our planet model we will import System.Collections.Generic

 

using System.Collections.Generic

public class PlanetModel : GameObject
{
  public static PlanetModel instance;
  void Awake()
  {
    instance = this;
  }
}

so that we can have a dictionary of all our planet data

 

using System.Collections.Generic

public class PlanetModel : GameObject
{
  public static PlanetModel instance;
  void Awake()
  {
    instance = this;
  }

  public Dictionary<PlanetID,PlanetData> allPlanetData {get; private set;} //allow others to easily read this dictionary
  void Start()
  {
    allPlanetData = new Dictionary<PlanetID,PlanetData>();//initialize the dictionary

    //add the data for two planets
    allPlanetData.Add(PlanetID.Zorgulon, new PlanetData(PlanetID.Zorgulon, new int [] {1,2,3}));
    allPlanetData.Add(PlanetID.Xanzibar, new PlanetData(PlanetID.Xanzibar, new int [] {1,2,3}));
  }
}

 

so now when a planet is initialized you can call the planet model

 


class Planet : GameObject
{
  PlanetID myPlanetID //set in inspector
  int [] resourceOne;

  void Start()
  {
    this.resourceOne = PlanetModel.instance.allPlanetData[myPlanetID].resourceOne;
  }
}

 

I realize there is a lot of information there, but hopefully you see a few tools that might help you. Again if you want me to explain anything further I'm happy to do so.

Share this post


Link to post
Share on other sites

I think a singleton pattern isn't really the best solution.  I'd go with your first instinct which is to set these values through the inspector, but simplify your data structure.

 

There's no reason to optimize it down to a 2d array, you're already eating a huge amount of object bloat since they're game objects, you might as well make them something that's easy to operate with. By putting it as a 2d array, you're making it harder to add both new planets and stats.

 

One way you could play nice with the inspector is by creating a class for planet attributes eg:

 

public class PlanetModelAttr {
  public string key;
  public string value; //or float/int, whatever

  public PlanetModelAttr(string k, string v) {
    key = k;
    value = v;
  }
}

public class PlanetModel : Monobehaviour {

   public PlanetModelAttr[] attrs;

   //... etc ...
}

Share this post


Link to post
Share on other sites

You can then make prefabs of your planets if you want to load them via script.

Share this post


Link to post
Share on other sites

Also, it's not a bad idea to create some sort of scene director that spawns in your planets, and initializes values that aren't set in objects already in the scene.

Share this post


Link to post
Share on other sites

Interesting. I'll have to read it all again while I'm sitting in front of Unity. It's been a while since I worked with Enums and Classes in that way. I'm a bit rusty.

 

The point (in my mind at least) of putting all the different commodities in an array was the ability to iterate through them with a for loop for the planet to planet trading. Each planet has an individual 2d array that contains six variables (Current Price, Base Price, Stock, Production, Storage, Shipping Capacity) for seven different commodities. In order to do what you're talking about Forbin, I'd have to have one class for each commodity, and then each planet with 7 different classes, right? Or a class of classes I guess.

 

Edit: Rather than using an Enum, I fell back on my old QBasic habit of having a bunch of Static Variables so I could access the array by using something like "items[food, price]" so it's not horribly clunky to work with, just doing the initial setup is a pain.

Share this post


Link to post
Share on other sites

What to put in a prefab, what to put in scene, what to put in a script through the editor and what to do in code is IMO the hardest thing to figure out in Unity. I'm not sure there's any shortcut to getting comfortable with that other than using it for a while.

 

If you are going to have a pretty small number of planets I would probably make prefabs for each. If you want it do be more dynamic or support a larger number I would do it in code.

Share this post


Link to post
Share on other sites

I think a singleton pattern isn't really the best solution.  I'd go with your first instinct which is to set these values through the inspector, but simplify your data structure.

 

I really like using singletons, but what you suggest does look like a better solution for the problem.

Share this post


Link to post
Share on other sites

What to put in a prefab, what to put in scene, what to put in a script through the editor and what to do in code is IMO the hardest thing to figure out in Unity. I'm not sure there's any shortcut to getting comfortable with that other than using it for a while.

 

If you are going to have a pretty small number of planets I would probably make prefabs for each. If you want it do be more dynamic or support a larger number I would do it in code.

 

 

I'm not looking at creating and destroying them during the course of the game, they will be static for each play through, and I'm planning on having a lot of them, so I think I'm going to avoid the prefab way of doing things. I think I can play around with Enums and Classes and build this in a way that makes a little more sense.

 

Thanks for that article ATSP. I'll finish reading it when I get home from work.

Share this post


Link to post
Share on other sites

I'm not looking at creating and destroying them during the course of the game, they will be static for each play through, and I'm planning on having a lot of them, so I think I'm going to avoid the prefab way of doing things. I think I can play around with Enums and Classes and build this in a way that makes a little more sense.

 

Thanks for that article ATSP. I'll finish reading it when I get home from work.

 

Wait, you can create a 2D Array of a struct (a single commodity class that extends from System.ValueType and that has an enum variable that indicates commodity type and float variable that holds the relevant information. you need to make it serializable for an array of those to be editable in the inspector). That way you will be able to resize and add to this array in the editor (which I think it's the right solution for your problem). It also allows planets to have more or less commodities (since the array is of no fixed size) which adds to the flexibility of the design...

Share this post


Link to post
Share on other sites

I ended up just creating a bunch of initialization functions and just calling the proper one based on planet name. I'm not sure it's the best solution, but it'll work for now while I study up on C# some more.

 

Now to add an actual trading ship that you can move around and it will be come an actual "game." It'll be easy and boring, but at least it'll be something.

 

Edit: Which actually brings me to another question. I want to basically have an idle animation that has your little space ship orbitting the planet. The easy way to do this from a visual perspective would be to have a version of the ship as child object under each planet, that way I can just rotate the planet + ship combo or plot a circular path for the ship with the parent object as the port of origin. The problem with that is I'd effectively have five (or hundreds later on when I add more planets) of child ship objects so a seperate container will be needed to hold the various ship stats (cargo held, damage, etc.) I guess there's nothing stopping me from creating an invisible object out there somehwere to hold all that, but I don't know if that's the best way or not.

Share this post


Link to post
Share on other sites

I'm pretty sure that this is the piece of foundational knowledge that I am missing. I'm excited that I found a lesson on it, but after repeated viewings, it is not sinking in. Can someone please explain this to me in clyde-speak.

http://unity3d.com/http%3A//unity3d.com/learn/tutorials/modules/beginner/scripting/datatypes

 

Why does the first one not work, but the second one does?

And how can I tell the difference in the future?

using UnityEngine;
using System.Collections;

public class DatatypeScript : MonoBehaviour 
{
    void Start () 
    {
        //Value type variable
        Vector3 pos = transform.position;
        pos = new Vector3(0, 2, 0);
        
        //Reference type variable
        Transform tran = transform;
        tran.position = new Vector3(0, 2, 0);
    }
}

 

Why am I not getting this? It's so weird to have info right there and just not be able to understand it even though it looks understandable. It reminds me of my struggle to understand the Monty Hall Problem

Share this post


Link to post
Share on other sites

In the first case, "Vector3 pos = transform.position;" copies the x,y,z values of the transform's position into a new place in memory.

 

So when you then update pos, you're just fiddling with the x,y,z values of the Vector3 variable somewhere in memory and NOT the Vector3 variable tied to the transform. When the engine then tries to read your transform's position, it still has the old values. If you wanted this to work, you would have to add "transform.position = pos;" to the end.

 

On the other hand, "Transform tran = transform;" copies the address of your transform, so when you edit the position this time, you travel to the location in memory stored by your tran variable and directly change the values tied to the transform. This is what is meant by a reference variable - it isn't its own instance of the type specified, it refers to a variable of that type and can be used to access it. It's also sometimes called an alias.

 

I hope that helps.

Share this post


Link to post
Share on other sites

Am I correct in saying that with Unity types which are components are passed as reference and others are passed by value?

Share this post


Link to post
Share on other sites

Am I correct in saying that with Unity types which are components are passed as reference and others are passed by value?

 

 

Yes I believe so.

Share this post


Link to post
Share on other sites

Does anyone know of a way to have multiple people simultaneously editing a scene over the internet?

 

I've started on a project with 5 people and have been using git, which is great for all our scripts and assets, but having multiple people work on the same scene has been pretty difficult and a frustrating bottleneck at times.

 

I tried (somewhat feebly) finding a solution online and wasn't successful.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now