Trying to Understand Unity's "Way" (Implementation of tip from Unity Best Practices)

Since it has nothing to do with Unity, it was easy for me to successfully craft a procedurally generated universe.
What is NOT easy, and is giving me a lot of trouble, is understanding how UNITY wants me to do this. Anytime I try to do it “My Way” I usually contradict whatever framework/engine I am trying to use. My way, My thoughts, always get me in trouble. I need help understanding how Unity prefers developers to work.

I really want to use Unity to make my life easier, but my thoughts keep beckoning me to just make my own engine. However, I figured it is easier to learn Unity’s “Way” than it is to learn a ton of low level API like OpenGL +/- ES.

I have a string which is used to create a procedural galaxy or “SpaceExpanse” which is composed of a 10x10 grid of 256x256 squares or “SpaceAreas”, which are composed of a collection of stars/planets or SpaceSystems, which hold the individual stars/planets, and the planets holding PlanetAreas, and so forth, etc.

Something like this:

It is composed of the following primary classes:

SpaceExpanse
SpaceArea
[TypeOf]System

None of them are Monobehavior. They’re just plain C# scripts that would work 100% without Unity.

Now, one of the ‘best practices’ tips is to make everything a Prefab, and Unity loves Gameobjects.
This coincides well with the fact I have to render this, allow for interface usability, etc.
I am FINALLY getting a feel for Unity’s favoring of component-based design. I also am FINALLY beginning to understand component-based design (coming from OOP practices).

For now, it would be simplest and most efficient for me to have the following gameobjects and object parenting.

SpaceExpanse
---SpaceArea
------System
---SpaceArea
------System
---SpaceArea
------System
---SpaceArea
------System

This would allow me to take a component-based approach to the primary gameplay which revolves around the System.

Add a few scripts like: Pickable (Clickable Interface), TooltipGUI (OnMouseHover), give the gameobject its own Sprite (while rendering everything else in a different way), etc.

Question: How should I go about creating a prefab or components from my game data, from my non-monobehavior Classes?

Right now I just have an empty prefab of a gameobject named “SpaceExpanse”, and I assume I would create “SpaceArea” prefabs inside the ‘SpaceArea’ script, and then parent all of them to the ‘SpaceExpanse’ Prefab which instantiated in the Scene first.

Is that it? It is as simple as adjusting the position of SpaceAreas (transform.translate) to form the grid?

Should I create a new class, or just implement it inside of SpaceExpanse.cs, SpaceArea.cs, etc.
Even more, should I attach these scripts TO the game objects themselves? Right now there doesn’t seem to be a need for attaching them because once the objects are instantiated, they are never altered.

This is a bit confusing, because I am already working backwards. Having already created the galaxy without Unity, and now wanting to switch to a Unity-style approach. (Other approaches give me too many problems, like inaccurate translation of world coordinates, iffy translation points, and more annoying problems. I want to give Prefab/GameObject Component-Based design a try.)

You are looking to create a voxel style map. Your approach is normal though. You know the elements you want and the way that you want to present it, you are looking for a simple solution that will give you what you need.

OK, presentation of what you are trying to do is fairly simple. You have a galaxy, that is comprised of 10x10 blocks of 256x256 each. This says that:

  1. you need a single unit that depicts what each block is. (what type of star, color or whatever) That is just a star.
    2), you need a Monobehaviour that controls a grid of 256x256 of these blocks. This monobehaviour draws all the blocks within it’s domain. How you want to draw it then depends on what type of interface you want.
  2. you need a galaxy controller that builds each grid block. It is a monobehaviour which creates each grid block in the spacial orientation of what you want.

So 1 and 2 are not created in the editor, only 3. And 3 builds everything else.

Voxel tech states that each grid space is to be built if that grid space contains a value that can be drawn. You can easily create the geometry. This would be a voxel in each of the 256x256 areas. Now, for Unity’s sake, it cannot handle more than 65536 vertices in a single object. And each block will contain 4 vertices… that is 256x256x4 that is 262144 vertices, well over Unity’s limits. So a better calculation is to take Sqrt(65536/4) which is 128. So I would make these blocks 128x128. Now, to compensate, just increase the grid blocks from 10x10 to 20x20 and you reach the same coverage.

All of this is based on the math that each grid block will have 1 star per area. which should never be the case, but its good to think ahead.

Now, All you need is a system that says… GridPoint at Vector2(10, 20) is Star index # 1 in the Galaxy script. math says that point 10,20 is in grid block 0,0 (because 10 nor 20 are greater than 128), then puts #1 in the grid at 10,20.

Next, put GridPoint at Vector2(200,300) to index #1. So the Galaxy then picks the grid at 128, 256 and makes point 72, 44 # 1.

Math is simple…

pointx = point.x % 128;
pointy = point.y % 128;
basex = point.x - pointx;
basey = point.y - pointy;

Thank you for the help! :slight_smile:

This confirms what I have come up with so far and helps steer me in the right direction.

After considering it all, here is what I have so far:

In my scene, I have a prefab SpaceExpanse (#3) which just builds everything (#2, the 256x256 SpaceArea, which builds #1 the StarSystems).
All that the prefab has is the correct size and a 2D rect collider (I was hoping to use it for camera bounds, as it encompasses the entire 2560x2560 map).

Each “SpaceArea” will be made with a simple 256 * X, 256 * Y. With X/Y being what tile it is from 0,0 to 9,9 (the 10x10 grid).
Within each SpaceArea, the StarSystems will be placed depending on where they want to go in the 256x256 Area.

I’m going to try to use Vectrosity to render everything except the black empty space. I might run into a problem making background stars, but I can easily resolve that by just making the background 10x10 tilemap of textures which are edited at runtime. Hopefully I can avoid this, as I think editing the textures is 99% of the load time. At worst though, I can use texture2D to render the pointless background (the empty space is scattered with faded stars which are irrelevant to gameplay, but are just for looks) and/or Vectrosity to render each SpaceArea. Finally, the prefabs SpaceSystem (which are 10x10 pixels) will render with a 10x10 sprite of its own.

The Prefabs themselves are as follow:

SpaceExpanse (The huge map container, size 2560x2560)
–2D Rect Collider
–GO_SpaceExpanse.cs (Script which creates all the other gameobjects which fill the expanse.)

SpaceArea (A single 256x256 square area)
-GO_SpaceArea.cs (Script which renders the SpaceAreas using Vectrosity or Texture2D’s and game data from my non-monobehavior scripts. Creates SpaceSystem gameobjects which are the 10x10 big stars. If texture is required to render background stars, then that too.)

SpaceSystem (A small, 10x10 pixel system, but crucial to gameplay and the entire point of the map.)
-GO_SpaceSystem.cs (If required, the main script.)
-ClickableObject.cs (Component to allow the GameObject to know it has been clicked by the Player’s Mouse; OnMouseDown. Allows Game Actions for Player by clicking it.)
-ToolTipGUI.cs (Component to allow the GameObject to have a small GUI box appear if the player hovers their mouse over it. Gives Game Data to Player to read before deciding to click it.)
-A Sprite (a 10x10 pixel star), maybe change color as well. Maybe effects/shader added later like sparkling.

I hope it sounds good so far.

So far this approach seems very promising. Much more than the 6+ hours wasted yesterday and hair-pulling frustration when trying to use SpriteTile ScreenToWorldCoordinates (which SpriteTile is horrendously bad at if you move the layer or do ANYTHING to the tilemap, as functions fail to update with the tilemap’s alterations) Vectrosity which led me only to discover I can’t use it to render small 256x256 points because of Unity’s limitation as you described.

This should be a better approach anyway. I can see why everyone uses GameObjects and Prefabs. And it also lets me use Vectrosity to draw everything (hopefully, anyway.) Meanwhile I can reserve SpriteTile for when the player lands on a planet, as opposed to when they are traveling on a huge procedurally generated worldmap.

It might have helped a tiny bit that I went through the entire Documentation earlier today, the basics (especially GameObject-Component relationships and Scripting/Prefab basics).

[OFF-TOPIC] Also to note, I have tightened the area where Systems were created AND tightened the area where planets/stars are placed around each System on the map. This allows me to keep my 256x256 size and get rid of the 290x290 awkward size I had to go with when dealing with the fact a System (10x10) could be placed at location 0,0 on a SpaceArea…and if that happened then any planet that was placed NorthWest of the System would go out of bounds (same for SouthEast of a System at 256x256).

I am hoping this won’t tighten everything so much that it becomes ugly, as the maps looked great before the change. I have yet to render the new world though.

Here goes!

edit: Why are pictures not loading? It says it is uploaded attached.
edit2: ah, I had to ctrl-F5

Lookin good so far!

edit3: Using Vectrosity, and everything seems to be working well enough so far

It worked!

It worked WELL! :slight_smile:

All that is in the Scene is MainCamera, !Scene, and SpaceExpanse.
All the rest are procedurally generated GameObjects from Prefabs with Components!