• entries
24
53
• views
34236

# Lessons learned while switching to Unity

4295 views

[font=inherit][/font]

Daily routine
Coroutines can be achieved in pure C# but Unity made their use very easy and intuitive. It is akin to starting a new thread without the problems associated with thread safety issues like concurrency, race condition & deadlock. The coroutine also behaves like any other member function. It has access to other functions and member variables.
I will leave the implementation details aside (see links below) but know that it can easily be used to provide easing to an object over time or calculate the next score increment. Another, more advanced, use-case is a very elegant way to implement a state machine. More information here and there and state chartshere

Eventful delegation
Event firing and registering is built into the language. Events & delegates are two sides of the same coin. The delegate provides an equivalent to an array of function pointers and the event is the message being sent. This makes for painless event driven programming and we all know how much a game can be event heavy.
This could make a post topic by itself so I leave you with the documentation and an in depth tutorial/study

Epilogue
There you have it. A non-exhaustive list of tips, tricks and gotcha. Thank you for reading and feel free to ask any question in the comments.

So basically C# is one of the best programming languages out there (along with C++, Java, Ruby, Phyton). And Unity does not break it. The switch statement in C# is great. You can fall through in this case:  case A: case B: // do stuff for A or B. Goto statement available where it shines. I think, it is the same in Java. Yeah C# has delegates. Never done any GUI in windows.forms? I hoped to see delegates nowhere else. Sometimes I just want a simple pointer to a single function or maybe a single object. Why do they force a collection on me?

What is off puttig about LINQ syntax? It is sooo close to SQL and JQuery as possible and better. This one I would miss in C++. Java has it. The dynamic languages probably can do similar things.

Probably there are other well written frameworks which play well with C++ language idioms.

While Unity ain't bad, and C# is great.  One of the things you should be really careful about is Unity's implementation of C#.  A lot of extra garbage collection happens on some fairly innocuous things.  For example, I wouldn't use IEnumerable for arrays.  In fact, avoid ForEach in general, as it causes garbage collection.

Now, that said, maybe they've finally fixed it in Unity5.

While Unity ain't bad, and C# is great.  One of the things you should be really careful about is Unity's implementation of C#.  A lot of extra garbage collection happens on some fairly innocuous things.  For example, I wouldn't use IEnumerable for arrays.  In fact, avoid ForEach in general, as it causes garbage collection.

Now, that said, maybe they've finally fixed it in Unity5.

If you read that thread in it's entirety, it's not really so cut and dry. While the bug does exist, depending on the platforms you are targeting, you might not even notice the bug. In reality, mobile platforms are likely the only place you would notice anything due to their CPU and memory constraints.

While Unity ain't bad, and C# is great.  One of the things you should be really careful about is Unity's implementation of C#.  A lot of extra garbage collection happens on some fairly innocuous things.  For example, I wouldn't use IEnumerable for arrays.  In fact, avoid ForEach in general, as it causes garbage collection.

Now, that said, maybe they've finally fixed it in Unity5.

If you read that thread in it's entirety, it's not really so cut and dry. While the bug does exist, depending on the platforms you are targeting, you might not even notice the bug. In reality, mobile platforms are likely the only place you would notice anything due to their CPU and memory constraints.

Eh, even in the thread, the consensus is mostly, "avoid linq and foreach in upate/fixedupdate", except for one guy, and he even predicates his LINQ love depending on the data and because of it's Lazy evaluation.  I think it's worth pointing out the bug, and noting that for a lot of foreach calls, a simple for() replacement is very simple to do, comes at little cost of readability, and if done upfront, gives a nice small speedup, and will be less of a headache later if one ports to mobile, or suddenly has to deal with a shitty PC.

While Unity ain't bad, and C# is great.  One of the things you should be really careful about is Unity's implementation of C#.  A lot of extra garbage collection happens on some fairly innocuous things.  For example, I wouldn't use IEnumerable for arrays.  In fact, avoid ForEach in general, as it causes garbage collection.

Now, that said, maybe they've finally fixed it in Unity5.

If you read that thread in it's entirety, it's not really so cut and dry. While the bug does exist, depending on the platforms you are targeting, you might not even notice the bug. In reality, mobile platforms are likely the only place you would notice anything due to their CPU and memory constraints.

Eh, even in the thread, the consensus is mostly, "avoid linq and foreach in upate/fixedupdate", except for one guy, and he even predicates his LINQ love depending on the data and because of it's Lazy evaluation.  I think it's worth pointing out the bug, and noting that for a lot of foreach calls, a simple for() replacement is very simple to do, comes at little cost of readability, and if done upfront, gives a nice small speedup, and will be less of a headache later if one ports to mobile, or suddenly has to deal with a shitty PC.

Yeah, I agree with you for the most part. A bug is a bug, and that is hard to argue, but I am personally not going to worry about it until I see some real world benchmarks illustrating the performance hit.

Also, IIRC, LINQ is only partially implemented in the version of Mono that Unity is using and that is one of the biggest reasons to steer clear of it in my opinion.

I am sure that you have seen this, but it is the latest official thing that I have seen talking about a Mono upgrade.

http://blogs.unity3d.com/2014/05/20/the-future-of-scripting-in-unity/

In any case, lets hope that IL2CPP lives up to the hype when it is fully implemented.

Linq was one of the game changers that was added to C#, it transforms how you think in the language. I have a whole set of monadic comprehensions implemented that integrate with linq. Maybe, IO, State, Validation and Exception. Linq is not tied to IEnumerable<T> it is just the only monad they supplied out of the box for use with it.

This for example if my validator to test a spawn location

        public static IValidation<Level> CanSpawnActor(
this Level level, long actorId, Vector location)
{
return
from isNew in level.IsNewActor(actorId)
from targetTile in level.IsValidLocation(location)
from validMove in targetTile.IsValidMove()
select level;
}


This will return the level object if valid or the reason the spawn is invalid when not

Select = M<A> => A -> B => M<B>

SelectMany = M<A> => A -> M<B> => M<B>

etc

And the comprehension engine is a monadic parser

"False friend
The switch statement is a good way to keep the code readable. But in this case its behavior is slightly different in C#. You cannot fall through to the next case section. You have to place a break/return/goto… However, there is a walkaround. You can use something like “goto case 1;” to jump to another case. More details here"

I really don't like how the switch operates in C# / Unity. It always feels like it is unclean code for some reason but sometimes, it's really the way to go (especially in Unity).

I would've preferred they had some sort of fallthrough keyword, or perhaps use the 'continue' keyword that already exists for loops -- though that might be problematic.  I do like that not having any break or anything bubbles up to the compiler, as it's nice to catch those kind of sneaky errors at compile time, but it is uglier when you have to bust out gotos in a switch.

You can fall through in C# but not cases with code in them. This is valid

switch (someValue)

{

case 1:

case 2:

// do some work

break;

case 3:

// Some more work

break;

}

if you have common code for a few switches then extract it to a function :)

Needing a goto in a switch shows bad code structure imho,

The C style fall through is also a common source of bugs where a forgotten break can cause real issues.

## Create an account

Register a new account

×

## Important Information

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!