Learning a programming language to use Unity

It highly depends what your goal is. Is your goal to learn technology, specific techniques, or just make a game?

I wanted to see if I could make an asynchronous engine. Yeah, I want to make a game, but for me a large part of it was exploring the technology, and Unity wouldn’t really let me do that. I know how component based game programming works, I’ve done it before, but with Unity I can’t explore the stuff I want to explore (at least without the $1k+ pro version). I have less control over the renderer and update loop tools so I can’t try out certain algorithms I want to try out, and so on.

If your goal is just to learn specific techniques, it really depends which techniques. New graphics algorithms are going to be harder to implement because Unity is your renderer, pathfinding or AI is going to be easier because you can just choose to not use their API.

I’m going through largely the same progression that those Unity tutorials go through. Right now I’m working on the GUI system, so I’m implementing certain techniques (e.g. spatial hashing) to make the point-and-click stuff easier. As I develop the mock components, I learn about my API and what works and what doesn’t and refactor it. So I just decided to write a game that’s almost entirely keyboard and GUI. This lets me deal with stuff like text rendering, on-click events, and the like without having to deal with that and 3D geometry bugs and cascaded shadowmaps, and physics systems at the same time. It also lets me torture test my engine to make sure it’s flexible and can handle a wide variety of things with little fuss. However, if I just wanted to make my 3D game, yeah, I am immensely slowed down by “reinventing the wheel” and not just using Unity (well, except for the fact that I need control over the renderer for my game idea, but that’s besides the point).

So, as I said, it depends on what your goal as a “single dev” is.

So, I’ve checked out a few programming tutorials from various sources and so far, what they have in common is that they teach like this:
“We’ll make Project.
Now, do This1 and This2 and This3 like you see here.
And then that gives us That1 and then we do This4 and the code looks like this. We have now completed Project.”
In other words, it tends to mainly consist of a set of instructions on how particular *parts *of it work. It rarely says much about why the system works. It seems like explaining it from principles, from a systematic point of view first would be more efficient.

Is this false, is the most efficient way to learn to go through a series of applied “Do this and then this and then that”? Are there resources which go for a more sysmetic approach?

Are you talking about general programming tutorials, or Unity tutorials?

You have to realize that programming has a level of abstraction, asking “how does this work?” is a great question, but a lot of times the answer is not something you need or want to know, at least not until you’re at an intermediate to advanced level. You can’t write a basic “Hello, world!” program in C without invoking the preprocessor or writing a function, or even calling a variadic function. That doesn’t change the fact that explaining how the preprocessor works, what functions do (and worse: how they work), or what variadic arguments are would be way out of the scope of a beginning class. Java is similar, how does import work? I’m sure C# is similar as well. With Python there’s a bit less obvious magic, but it’s still ultimately present.

If it’s Unity, I think it’s the curse of an engine. In large part you don’t need to know what the engine does, and the fact of the matter is most people don’t actually know how the engine works since it’s a black box without the pro version. It’s mostly irrelevant to the programmer until you’re optimizing your game to work with the engine. I do agree that a lot of bad tutorials just go “create this, write that” without explaining it well, but looking at it from a systematic perspective is hard when a lot of that system is a black box.

Besides, in component-based game programming you really want to conceptualize things as independent parts. Something that listens for Collision Events and Takes Damage when it hears them doesn’t care about what system forwards the collision events, or even what triggered the event to happen (beyond maybe doing some identify-friend-or-foe logic to determine whether it gets hurt). All it cares about is that when it happens, it can do its own thing.

Systems are good, but looking at a component-based black-box game engine from a systematic perspective is unfortunately not going to get you very far.

I think what you might be after is a more complete, holistic approach to unity development, and you’re not going to get that on the internet. The web is great for quick tutorials, specialized information, but you’re going to need to pick up a book on Unity to really get closer to what you want Michael.

I think you’re too hung up on understanding stuff. Work on understandin when you need to, and not before, otherwise you end up never getting anything done. Are you an INTP, by any chance? :wink:

Overthinking it is the number 1 killer of projects. "Overcomplicating Everything"

It also turns out that the more complexity you introduce to non-critical game mechanics, the shittier your game tends to become. Seamus Young (look him up) calls this “oversimulation”. If traffic doesn’t matter in your game, then just having cars moving in straight lines and turning at predictable junctures is fine. Introducing swerving, slamming on breaks, turn signals, tailgating, and all the other crap that comes with traffic is just going to 1. distract you from your real goals, 2. make your traffic look terrible because it’s probably a full project in and of itself to model traffic in a satisfying way, and 3. make people notice how bad your traffic is because it’s doing a bunch of stuff that will make people want to look at it.

C++ should not be your first programming language. It would be a bit tough to learn on your own. It could be done if you had to, but you would be better off with C# or JavaScript.

Strongly INTJ. That systemic approach has served me well when it comes to learning English as a second language, how to dress, philosophy and law but I admit that programming might be different.

Note that I am not thinking of making games complicated. The reason I want to understand a systemic way is because I think it’ll eventually be simpler. It’s a bit like knowing the laws of a jurisdictions; sure, I could try to memorize all of them or the ad hoc rules on any particular topic or I could understand how a legal system works and how to get the information within it. Once I do that, pretty much everything is easy.

I understand what you’re saying and I’m much the same way. A bit of the crux is what I consider the number one rule of programming: everything is arbitrary. Programs are complicated and there is no “system” that is universal to all programs (unless you want to learn physics and electrical engineering, naturally).

The reason you learn pieces is because programs are built from pieces. Even if your design process starts with “I need a system that does <x>” the design ultimately must boil down to “in order to make a system that does <x>, I must build it from x, y, and z”. You’re effectively asking “what’s the system behind playing with Legos?” That largely depends on what playsets you own and what you’re trying to build.

Now, a cool thing about programming is that these pieces are frequently interchangeable. If you need a piece that sorts a list of numbers, then you can exchange mergesort, quicksort, bogosort, insertion sort, or bubble sort (with some of these being better or worse than others depending on the case). That’s where your “systematic understanding” comes in. But you design your problems as interacting systems; first you need to know the pieces you can use to build them. You can’t build a lego castle without some legos, and you can’t build a program without knowing what components you can break it down into.

Now that’s not to say there isn’t a theoretical system underpinning computing in general, but… well, let’s just say that you don’t want to start with an Automata course that discusses the finer points of Turing Machines when you want to make a video game. You’ll find conceptual similarities underpinning computing eventually, but that’s when you learn your second or third programming language and begin to get a feel for what sort of logic, functions, and concepts are common between programming languages.

Ah, J. Figures. :smiley:

Let me share my experience coding snake in Unity with you.

I started with a flat 2D array, because that’s how I did it in Pascal. I soon learnt that it wasn’t the best way to operate in an object oriented world (I ended up with a 2D array of a self-declared mutant class that included integers and GameObjects out the wazoo).

I used a plain square sprite GameObject to represent a snake segment, and simulated movement by instantiating and destroying the snake segment. This is of course horribly inefficient, but at least I learned how to instantiate and destroy game objects. I also had the satisfaction of seeing something happen.

Along the way, I figured out that arrays needed to be declared and then initialised in the start() function. I have no idea why ints and such are automatically initialised, but arrays and GameObjects are not, but I found out that that needed to be done, so I do it, and it works. Maybe not the most satisfying thing for you, but when I need to know in the future (maybe I need to optimise something) I’ll find out.

I also experimented with setting the fixed update frequency to adjust the snake speed, and in the process learned about deltafixedupdate and its cousin deltaupdate, and when to use which.

I then switched to having an array of GameObjects to contain the snake segments, and having the snake head move smoothly, but realised that I had to deal with the snake head being positioned in Vector3 (which are really just 3 floats) and ensuring that the snake only turns on integer values for xpos and ypos.

Then, I discovered lists. Those are amazing.
So, very much learning by trial and error, but the result of which is that I know exactly what I need to know to get the game that I want to make right now, and I can work on this base for my next game. If I’d studied the documentation for GameObject (really, you can ignore most of the methods and things), I probably wouldn’t even have started coding yet.

So, as always, YMMV, but I’m finding that “measure twice cut once” doesn’t work as well as “flail madly and JIT everything”, at least at this stage.

As a side note, people reading this thread, if you have a strong desire to make games, I’d like to know your Meyer Briggs type, if you would. I have a hunch that quite a few game designers are INTP.

MBTI and games:
Kinthalis prediction: INTP.

How about you Tabby, INTP too?

Coding:
So, every time I want to do something new, I have to search the forums/tutorials or curse my way into semi-randomly kludging my way into finding the right code?
I made a clock in Unity from here (http://catlikecoding.com/unity/tutorials/clock/), it worked and the coded ended up looking like this:
"using UnityEngine;
using System;

public class ClockAnimator : MonoBehaviour {

private const float
	hoursToDegrees = 360f / 12f,
	minutesToDegrees = 360f / 60f,
	secondsToDegrees = 360f / 60f;

public Transform hours, minutes, seconds;
public bool analog;

void Update () {
	if (analog) {
		TimeSpan timespan = DateTime.Now.TimeOfDay;
		hours.localRotation =
			Quaternion.Euler(0f,0f,(float)timespan.TotalHours * -hoursToDegrees);
		minutes.localRotation =
			Quaternion.Euler(0f,0f,(float)timespan.TotalMinutes * -minutesToDegrees);
		seconds.localRotation =
			Quaternion.Euler(0f,0f,(float)timespan.TotalSeconds * -secondsToDegrees);
	}
	else {
		DateTime time = DateTime.Now;
		hours.localRotation = Quaternion.Euler(0f, 0f, time.Hour * -hoursToDegrees);
		minutes.localRotation = Quaternion.Euler(0f, 0f, time.Minute * -minutesToDegrees);
		seconds.localRotation = Quaternion.Euler(0f, 0f, time.Second * -secondsToDegrees);
	}"

While some of it I understand and could reproduce, for most of the code all I can do is say “Well, if I ever run into a very close problem to that one, I’ll be able to slightly modify that.”

They actually are initialized, just not in the way you think. C# and Java are tricky and essentially use pointers without telling you. What’s a pointer? Consider it the address of where a value lives. GameObjects and Arrays are really big values with a lot of smaller things living in them, a GameObject has a bunch of integers, and maybe even other GameObjects in it! Same with an Array. In fact, this is true of any Object.

So instead of trying to figure out exactly how big every Object is, C# does something for you. When you make a new Object, C# gives it a nice home somewhere in the program and tells you where it lives. The actual variable in your program isn’t that object, but rather its address. Now, C# is very nice, it doesn’t want to bother you about this, so it doesn’t make you worry about the fact that you have the Object’s address, so it pretends that you have the Object itself. You hand it an instruction to some data and it discreetly writes the address on a letter and sends it for you, and if the method has something it wants to say back to you, C# will forward the message, all the while convincing you that no, dude, Object is totally right there in the next room with us. Now, this sometimes causes tricky problems for newbies. For instance, using the “=” operator on two Object variables assigns the address of the right hand side to the left hand side, it doesn’t actually change the variables in the left-hand object to match those of the right-hand Object, but for the most part it works pretty well.

But what does this have to do with initialization? Well, the address is just an int. A magical int that tells you where something lives, but an int nonetheless. So when C# initializes your program, it sets it to the same value it does for the int: 0. Consider 0 (aka “null”) to be a fancy way of saying “nobody lives here”. It’s like the 555 area code.

And yes, this does mean that if you have an Array of Objects that hold other Objects you do indeed have an address to a list of a bunch of addresses that in turn hold a bunch of addresses. :stuck_out_tongue:

Keep in mind that this, like many things, is arbitrary. There’s no reason why C# can’t initialize the object for you and then initialize your variable to its address. There’s no reason why ints don’t use addresses. Heck, for some Objects, there’s actually no reason you need it living somewhere else at all (though for many, like arrays, you really do need to do the address thing). Or rather, there are reasons – they intentionally made the decision when writing the language, but it’s not the only way it can work. Indeed, you can almost certainly find languages that do or don’t do all of these things.

Also keep in mind that I’m handwaving a few things. In reality, the “address” isn’t always the exact address of where it’s living. To keep beating this analogy, sometimes it’s a PO box or a forwarding address or its place of business, but C# makes sure that everything you’re doing gets to the right place, so you can generally think of it as such.

Yep, INTP. :slight_smile:

See, that’s your problem. You don’t have a problem.

Find a problem. Make pong. What do you want to do? Go do that.
You’ll then be forced to find out how to make pong, and learn what needs to be learned to make pong. It probably won’t have anything to do with clocks, but then you knew that. Why’d you make a clock in the first place? :stuck_out_tongue: Did you want a clock?

Let’s say you wanted to make missile command, and your turret has to rotate. You can probably figure out how to rotate the turret from your clock example, using the quartered onions. Maybe you need the clock script then. Or maybe you’ll find something else that’s more suited to rotating turrets, and learn from that script instead.