Search Unity

Software developer 30 years wants to learn Unity not more C#

Discussion in 'General Discussion' started by Evil_Genius, Jun 17, 2021.

  1. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    I am have been a professional developer since 1992, and I want to learn the nuts and bolts of Game Development, not programming. Unfortunately, most courses for learning Game Programming teach while learning basic code, or even worst Visual Scripting! (<Evil grin>).

    I have been using the https://docs.unity3d.com/ScriptReference/ to learn functionality. Still, I am looking for a course/book that will help me glue the concepts together into a whole that does not expect that I already know general concepts of Vectors. I hope many of my questions come from a "Code" background and have expectations from that history. Here are some of the questions I keep coming asking myself.

    I understand that each object can have one or more scripts associated with it; What order do the scripts execute? For example, is there a way to have a single script file for the scene that is the "controller" for all game objects and then by type inherit behaviour? What is the correct layout of a code project to promote this?

    Another example would be should objects be stored as collections or stacks for iteration? Which is faster? Why would I choose one over the other? On that note, should I create a class to store all information about an object and attach the script to each object or store a collection/stack of the objects with an identifier to associate the game object and the stack items? Finally, is it better to enumerate a given object type in a scene and act on them or store the list upfront and manipulate it from there? For example, bullets in a shooter could be a stand-alone object that deals with its lifetime, give it a vector and let it go, or keep a collection of bullet objects, iterating them to manage vector, velocity, etc. collisions as a single callback.

    I give these examples to illustrate the types of information I need. Does anybody have any resources that would help?

    I am already just "Writing" games and figuring it out as I go. I want to know best practices to avoid pitfalls and the reasoning behind them. Maybe I should go and look at the Unity source code, figure it out and write a damn book.

    Thanks, everyone.

    EG
     
  2. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    5,181
    I think the best thing to do is learn how to use the profile tools.

    Just like in writing or painting, get something on the canvas to work with first. Don't worry about how. Profile tools will let you figure out where problems are.

    People want to help but so many different opinions and persuasions. Even somebody who really knows their stuff and has a heart of gold won't be able to understand the scope and situation of your problem. They might give a technically correct answer but if you follow it you might still have problems because how can they know all the details?



    My general strategy:

    Get a playable game first. Do it as fast as possible.

    Once game is proofed, then proof individual production pipelines (models, animations, scripting architecture, etc).

    This is all throw away work - the return is having a checklist written down for how the actual production is going to happen.

    Both in art and code, I am trying to keep elements separate and non-dependent on each other. I want to be able to experiment non-destructively. If I hit a snag point, I don't hunker down and fight to the death. I try to find a simpler solution.

    The scope of work solo developer has to do is too big, so too much energy in any one spot introduces risk. At end of every day I need to see visible progress that is moving game closer to publication. If that hasn't happened then I reconsider how I am working. Don't want to fall into trap of noodling too long and this becomes a cover for fear of failure.

    Number one problem I think people are facing is perfectionism. With tools like Unity we all have means to make a fantastic bicycle, but insist on making a Ferrari. The key skill is decision making: knowing where to put focus and where not to. Everybody is a genius in some way or another - solving technical problems proves you can do a grunts job but the general will win the war by knowing where to focus all this power at the right place and time.

    I don't think indie developer needs to be solving complex problems. If there isn't already a tried and true solution to your problem, you might be taking wrong approach.

    I think games have already hit an apex. We have the technology to do pretty much anything, and its all already been done before. The thing even huge AAA games still struggle with is make it fun, maintain retention, earn praise, etc. This is a human question, nothing to do with technology.


    TLDR : Don't trust other people, learn how the tools work at low level and test for yourself. Keep game design simple and build in a way you can control and understand easily. Keep primary focus not on technicals but on the human experience of playing your game.
     
    Last edited: Jun 17, 2021
    stain2319 and NotaNaN like this.
  3. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    All you said is solid advice; I have many prototype games written from scratch and starter kits. I am at the point now where I am improving my craft. Using the profiler is a great idea to examine performance and make determinations about code effectiveness.

    Code organization-wise, I hoped that the industry had a "standard" that most professional studios use. I did the obligatory searches for the information, but as you said, there are many answers to the problem, and everybody has an opinion on why their way is best but little evidence.

    I am coming from a well-structured and known environment into the Unity ecosystem that is pretty much "by the seat of its pants," which is disturbing to me. Even the code on Github for Unity is structured differently in many places.
    Your point about "Perfectionism" is taken to heart, and I struggle with this myself. I am always looking for the "best" way to do something with evidence for why it is the "best."

    I will follow the "LEAN" methodology and keep the code as straightforward as possible while emphasizing fast deliveries/iterations and keeping code waste to a minimum. Organizational wise I am used to a more centralized approach to projects and will maintain this. Meaning spawn objects and track them in a stack instead of form layout via prefabs.

    I will be the lead programmer in a team of 3 developers and set the studio's game structure going forth. I wanted to be as industry standard as possible.

    Thanks for your insights.

    EG
     
    BIGTIMEMASTER likes this.
  4. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    5,181
    Yeah I don't know if its a case of game developers are less serious people, or maybe its just a space where each project is too different so standards cant cover very much.

    My experience with entertainment industry in general is that it's largely highly-unprofessional, though I haven't worked at any game studios.

    Just spit balling but in your position I'd think about setting the team a task to make like 3-5 simple games. Like tic tac toe, pong, roll a ball, etc.

    Each is an exercise in team development. Find and define a methodology for communication. Figure out which approaches - like object oriented versus data oriented, or a mix of both - suit which situations best.

    I think you just have to build the team and define your own methodologies. Each game is a little different. And each developer is different. For instance I am learning the basics of Unreal right now. I do two tutorials from two different authors, covering similar topics. One sets up communication between actors one way, the other does things another way. Both ways work, but for me, one way is confusing and hard for me to work with. The other is direct and intuitive.

    I run the profiler tools and can't find a difference, even though the complicated (to me) version is claimed to be made that way for performance considerations. Well, maybe when things scale it is the case, but no use trying to solve a problem that only might exist. I'll go with the way I can iterate on.
     
  5. stain2319

    stain2319

    Joined:
    Mar 2, 2020
    Posts:
    417
    In a way, it feels like game programming is like the "I want to be an astronaut" of programming - it's exploratory in nature and pushing the envelope is the normal state of affairs. In the Enterprise software world I think there are more "standards and best practices" whereas in game programming it's more "we gotta get this thing to the moon, and anything goes" mentality.

    The "best way" is first and foremost the way that works for you and your game. Optimization is like making the space shuttle, first you gotta work your way through a dozen Apollo rockets.
     
    ADNCG, EternalAmbiguity and NotaNaN like this.
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    They're executed in this order:
    https://docs.unity3d.com/Manual/ExecutionOrder.html

    However, if you're asking if ComponentA.Update() will be excetued before ComponentB.Update() when they're both attached to the same object, then for practical purposes, assume that the order is undefined.

    However, you can override it via this setting:
    https://docs.unity3d.com/Manual/class-MonoManager.html

    That doesn't really make sense to me.
    A GameObject is a thing that has components attached. The engine does not concern itself with what meaning you attach to this particular collection of nodes. It could be a car, it oculd be a player, or it could be an empty object that has data stored on it. It doesn't matter.

    You'll find an answer to most of those questions if you try to actually make something and tinker with the engine.

    If you're using component system and are not using thousands of objects, then the general idea is to program obejcts as if you're programming a drone swarm. I.e. everybody is independent from each other and interact with physics only.

    If you're dealing with tens of thousands of objects, this is no longer going to fly, as you'll hit overhead.
    https://blog.unity.com/technology/1k-update-calls

    In this case you'll end up one MonoBehavior acting as a "Manager" to multiple objects. Which will be closer to traditional.

    If you want even more, then there's "Dots" framework which unity swears is the next big thing. Which may or may not be true.

    Generally, if you want to comfortably program the engine, I recommend "Drone Swarm" approach.
     
  7. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,203
    Yeah I started to type up a post but I kept glancing back up at this line and ultimately decided to just emphasize it.

    Just making games ultimately answers a ton of questions and even if you think you've found all of the answers it's often the case they're not as correct as you had thought they were. A ton of information on the Internet, on these forums, and even in official reference material is incorrect and/or just plain out of date.

    Concerning advanced topics like DOTS I recommend steering clear of them until you have a basic understanding of Unity. Once you're no longer confused by simple topics like vectors then you can worry about which framework is faster but until then it's a moot point if you lack the knowledge to even use them.
     
    Last edited: Jun 17, 2021
    Socrates and stain2319 like this.
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I strongly recommend picking up the latest edition of Game Engine Architecture by Jason Gregory. It does have code examples, but it's really not a programming book - it's about the systems, algorithms, and how to design real-time interactive systems for games. It introduces many concepts related to game programming and engine development, which will introduce you to a bunch of stuff so you can think through the types of questions you've asked here.

    I also recommend the latest edition of Real Time Rendering by Akenine-Moller et. al. because this will give you a solid overview of how graphics work. That's about half of game development's programming, but it also has a major impact on how things look, feel and perform even if you're using stuff someone else wrote. Plus, at some point you're almost certainly going to want to modify someone's graphics code, write a shader, or solve some rendering edge case which you run into.

    Being disturbed is 100% ok. However, two things to keep in mind. First of all, what you see online is often not indicative of professionals in the game development industry. Secondly, games are often quite different to develop than other types of software for a variety of reasons, so different is not necessarily worse.

    That said, I do believe that both game developers and non-game software developers could learn a bunch from each other. I've worked in both and learned stuff in each that I could apply valuably to the other. Unfortunately, my experience with many people moving from one to the other is to just repeatedly insist that whichever one they started in does things "right" and that the other must therefore be "wrong".
     
    Martin_H, JoNax97, stain2319 and 2 others like this.
  9. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    I am a bit like you here, I like well organized projects, and the video games industry do not seem to be really like that.
    I also have been coding from a bit longer than you as I wrote my first full-assembly games a bit earlier than 1990, so I understand your problem with Unity tutorials mostly explaining how to write a if-then-else condition or a simple loop.

    That said, coding video games is not like coding an industry software.
    You'll have to re-learn how to code (well, mostly you'll have to change some of your habits).


    In the industry, you have a specification document telling you what the software will do in details, and you have a design document telling you roughly how it will be implemented.

    For a game, the specification cannot be precise, because you'll see when your project is taking form that it's not as fun as you supposed at first, so you'll have to do some tiny (or not that tiny...) modification to your initial specification.
    On the coding side it means that your design must be open enough so that modification in the specification will not force you to break and rework too large parts of your code.
    For example, it's better to make most things configurable, depending on the size of your project it may mean having hundreds, if not thousands, of configuration files.
    If you go for a moddable game, then you'll have to make it even more configurable.

    As for the design, it's harder to make it because the performances of the game are important, whereas in industry performance is not often important (you need to be reasonably fast, but you won't fight for a 20% reduction of execution time).
    It means that your initial design may not be working because of some performance problem, requiring you to deeply modify it.

    Also linked to performance, there is the garbage collection which is the nightmare of Unity game devs (and players...).
    In standard industry, you love using high level functions, especially LinQ.
    In video game industry, you fear those high-level functions and you ban LinQ.

    It's all a balance between configurability - performance - cost (in man hours).
    Each project is different, so there cannot be any standard.


    I do not know about your background, but if you're coding for 30 years now, I suspect that you're quite used to Objects Programming.
    In video games you may want to think differently, instead of putting together data and code which are working together, you may want to separate completely data and code, which is about the opposite of the Objects Programming way of thinking.
    Separating the data from the code will give you 2 advantages:
    - it will be easy to make things configurable
    - it will be easier to optimize

    Things will be more configurable because data can be exported/imported in configuration files, and it will also make it a lot easier to add more data (more monsters, ships, characters, etc.).
    Things will be easier to optimize because it will be easier to use multi-threading and cache memory (that's what DOTS does).


    And here I have introduced DOTS.
    It's still in a prototype state, and I do not have tried it myself, but I have read tons of things about ECS (Entity Component System) programming, and it looks like it may be some sort of semi-'standard' thing for you.
    I won't lie to you, programming using an ECS when you've worked more than 20 years with Object Programming will require you to wipe your mind and re-program it completely. It's like thinking like an Alien.
    But in the end, it may be the thing you're waiting for.
     
    vfn4i83 likes this.
  10. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
  11. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    6,025
    I used to be like you (much less programming experience though!) but wanting to do things the 'right way'. There is no such thing.

    The basic structure of Unity is the component/gameobject concept. There's not a lot to say about this, it's the point in the architecture where abstract code and physical objects meet. A script on a gameobject does not have to do anything with that object at all, but it's generally good practice, in my opinion anyway, to have the code for controlling an object on the object.

    I think this is where a lot of people coming from a programming background get stuck. In the typical programming world, the code exists as an abstract entity and you have all these principles for how to design it inside that abstract space.

    In game programming though, the physical world (usually) rules. In the sense that designing things is typically done as of the components on a gameobject are mechanical parts that make it up physically. Of course, there is no need to do it this way, but generally since Unity is aimed at newbies and people not used to thinking very much in the abstract, OOP and this physically-based approach is more intuitive than anything else. Which is good and fine since we aren't programming firewalls for nuclear launch systems, and half the time we don't know what an object will do exactly so it's better to operate on the object and its code as if it is completely self-contained.

    I think that's the crux of it. I wrote a kit for people to make space games, and the first iteration was according to theoretical best practices (including lots of interfaces and similar types of abstractions). In the end I threw all that out and rewrote it completely focused on this 'physically-based' approach. You want an object to do X? Add the component for X to the object you want to do it.

    In the end this proved far better because of how little I knew about what people wanted to do with the kit. And in game development, being a way more creative field, the rule is that you don't know what you are doing until you happen to see it on the screen.

    So I would suggest coding things as if the gameobject is the physical object, and components are the physical mechanisms associated with it. Is a crate damageable? Add a Health component. Can it hold something? Add a ResourceContainer script or whatever. Can it be kicked around? Add a rigidbody and collider. etc.
     
    Jingle-Fett likes this.
  12. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    I have, and I wouldn't say that at all. Every studio have I have worked in has been highly professional. Even the small ones. But industry is a bit messy because everything changes all the time.

    ---

    Developing games is a moving target. Many, many things can change in the time it takes to complete a game. Some things you have control over some things not so much. At Disney/LucasFilm, mid-core games typically took 3-5 years from greenlight to release. That is enough time for consoles to refresh, mobile devices to replace, hardware to change, software, middleware and operating changes to change. Sometimes significantly. And then there is tools like Unity, Unreal and internal engines and 3rd party tools and libraries. (Heck back in the day we had two huge games in production when the Flash/Air started to sunset). There was a point when 4 consecutive games I worked on were on different engines, at the same studio with the same team. Platforms can come and go, trends can come and go. (for a brief while social games were more successful than console, then mobile came along and they virtually disappeared).

    On top of all that, trends and patterns in architecture can change based on needs of the hardware. We always tried to build frameworks and scaffolds that could be used in the next game... but that often is completely impractical. We build a full custom UI framework, it becomes more practical to use Scaleform... scaleform discontinues... nGUI.. uGUI... ect. Stuff like that happens all the time. Screen resolutions double, better GPUs, more memory, on and on.

    Eventually you figure out that longevity of architecture is less important than being able to release a game faster. It becomes losing game if you take to long. You start accumulating tech-debt outside your scope as the timeline grows. We had a marvel combat game wayyyy long ago that, part way through the dev cycle retina on iOS devices became a thing. Due to other issues our date got pushed back past the Apple cut off for non-retina devices. it was 2d with hand painted characters and the images were really big several years back with project started, but not retina big. I and my team spent several months hand-painting new, larger versions of several hundred animated characters. This stuff happens all the time.

    So you evaluate what is possible, what you can reasonably see coming, if you are big enough company you can early versions of hardware and such, then you plan and make a schedule that you can deliver on before the future bites you in the ass. Then you start again, hopefully carrying some tools/pipelines etc.

    So yes, there are absolutely industry standards for how to build a game. Though, next week it will be different. ;)
     
    Wattosan, Zarconis, NavidK0 and 8 others like this.
  13. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    Yes good architecture is still important on a longer bigger project. Realising your outdated UI system is tightly coupled to so much of your code is not good!
    I'm not sure of the overall pattern of separation with Unity but it helps to separate wherever possible with loose coupling - logic, input, UI, graphics - then you can always swap out an outdated system.
    However it's not like Unity itself subscribes to such a thing due to requiring legacy support - TextMeshPro, new render pipelines, they are all awkward add-ons, patched on top of current architecture and with no common interface
     
  14. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    UI is never a 'swap out' as large games have lots of it, and good games have may have lots of unique controls that far beyond simple buttons, not to mention pipeline (big and little 'p'). Coupling a key system like UI is critical for performance and maintainability and stability. 99.99% of the time you aren't going to change core systems on a game ever, to risky. You may change tools on a next game, but not on existing game, the cost isn't justified. One of our bigger games, we went as far getting a custom agreement with ngui to maintain it in-house long after they stopped supporting it.
     
    Zarconis, NotaNaN, hippocoder and 2 others like this.
  15. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    Yeah true I guess
    Also stuck with ngui on a project, but what do you mean stopped supporting it? Still on the store so it must be supported.
     
  16. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    Stopped as of february
     
  17. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    10,160
    ?

    The asset store is loaded with stuff that isn't supported anymore.
     
    angrypenguin likes this.
  18. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    ?
    "2.1.h Publishers must provide and maintain an active customer support email."

    If you know of any unsupported assets, report them and they should be removed from sale.
    Or do you mean not supported on new Unity?
     
    Last edited: Jun 18, 2021
  19. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,203
    She means what she said. There are assets on the store that you can no longer contact the developers of.
     
  20. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    Well I reported an asset that was not being supported any longer (as stated by author) and it was removed from sale, so be sure to report them. They have to be supported, one of the pains of selling assets...
    NGUI is supported by its author on Discord still
     
  21. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It's pretty far off topic.
     
  22. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    This is useful. Thanks

    Edit: After going through it, this is what I am talking about when I talk about object management as lists. and Lists in Mono/C# are slow as S***. I have created a custom stack manager that we will be using. Increased performance significantly.
     
    Last edited: Jun 18, 2021
    tmonestudio likes this.
  23. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    I appreciate all of the thoughts here, and I have worked them into our Software Design principles for the development we will be doing.

    I was specifically brought in to lead the development effort to make reproducible abstracted code that is portable with many outcomes that are not projected. Meaning solid code that is fully abstracted that can be easily subclassed and refused without major modification of the original codebase while being flexible enough to meet many different needs per platform and design. This allows separate developers to work on their specific goals and refactor sections as new methods and ideas emerge while not impacting the performance and deliverables of existing code bases.
     
  24. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    Well, it doesn't work this way.

    For example, there's BioIK asset that still works, but the developer hasn't responded to anything in 2 years. This is common.

    You're getting sidetracked instead of learning unity.

    Give the engine two months, tinker with it and suppress the thoughts of implementing custom stack managers. Then it will eventually click.
     
    Noisecrime, bobisgod234 and Billy4184 like this.
  25. ippdev

    ippdev

    Joined:
    Feb 7, 2010
    Posts:
    3,853
    I wrote the below to management after they hired a bunch of C#-ers with little or no Unity experience to work. I thought it a bad idea..I left..they bankrupted the company. It is cobbled from bits and pieces espoused by some of the long time devs on here and some of my own opinions on the subject.

    Unity, C#, Mono and .NET

    C# engineers are _initially_ going to be the wrong people for be programming games in general. They're trained in practices that work actively against how Unity uses C#.

    So they need to understand that game development is about making up new rules (breaking them) because the rules aren't designed for games.

    In the world of game development, it's all about optimizations because it has to run within a specific time limit in order to be interactive and enjoyable.

    This means breaking the rules.

    The earliest game developers (since the birth of the very first game) up to today, had to be about breaking rules because the hardware wasn't (and still isn't really) designed for games. So to make games you need to play outside the established set of rules. That means using things that aren't designed for something, and not using things that are designed for something (in a language and hardware context).

    This typically means that most optimizations are breaking the "rules".

    Of course to any game dev using Unity, we're not really aware we're breaking rules, we're just flexible enough to think well outside the box, because that's a normal every day mode of thinking for the humble game developer.

    At its core, Unity uses Mono. Mono is an implementation of the .NET framework. That by definition means it's not the same framework .NET developers may be used to. Even though it's supposed to behave the same as the framework they're used to, not all things are implemented the same way (if even at all).

    Unity took this a step further and changed a few rules about what to expect from C# via operator overloading -- using bool to check vs null, and overloading equals to check against a fake null being just two examples. This also broke newer C# features such as null propagating and coalescing operators. With constructors being forbidden, readonly fields become harder to set. And so on.

    Hell, Unity doesn't even use polymorphism to call Update() in MonoBehaviour derived classes. It feels a bit alien to not include "override" when creating an Update() function. But that's just how Unity works.

    So if anyone argues "But it works this way in .NET..." it's already irrelevant. There is a definitive distinction between "C# vs Unity C#”.Some random thoughts:

    1) If they want to stick with their .NET code, then fine. Just keep it in DLLs. And create an API to let their .NET code talk to Unity and vice versa. If they want to work within the Unity namespace, they must adhere to Unity's rules. No ifs, ands, or buts about that.

    2) You use an API in the way it's meant to be used. You don't try to bend the rules or work around it, then complain that the API doesn't work the way it should. Thinking you can write your own buttons for example instead of a Unity Button component hogties any system that uses the UI eventData looking for interactable bools, loses for free animation and colorBlock transitions from your toolkit. Using the OnClick event delegate is the exact same but faster as intercepting it in script. Real world testing has proven this even though it looks like they are the same. Unity does something under the hood with pooling and reassigning delegates on the fly.

    3) If upgrading Unity versions break your code or objects and force you to re- engineer it, then see point #1 about adhering to Unity's rules. Note, I am not talking about Unity bugs -- these are very valid reasons on skipping certain versions while upgrading. I am talking about how if you try to access internals via reflection, then your reflected code breaks because the internals changed, well guess what, that's on you for depending on internals to never change. (Note: This should be extremely unlikely now that Unity open sourced their C# code, but the point still stands). Setting up objects to be normalized with a uniform scale and Quaternion.Identity rotation and it’s coordinate system position at 0, 0, 0 will avoid serious headaches when Instantiating objects.

    4) Similar to #1 above, if they've ever worked with WPF, they should be familiar with MVVM. Or MVC. Keep the logic and UI code separate. Apply this line of thinking to Unity -- if you're going to get all fancy with your .NET code, keep it out of Unity code. Changing your code should not break Unity. Changing Unity UI should not break your code.

    5) As has already been said, game dev is very different from business dev. Unfortunately it's very hard to convey this point to folks, especially if they have little technical knowledge of the underlying issues. You have people with specialized skills and you don't try to put them on jobs they're not suited for. Even though architects and electricians work together to build a house, you don't expect an electrician to draw up blueprints for the house and expect the house to not collapse. Or architects to not die from electrocution. And so on.

    The irony in saying that games development "breaks all the rules" is that it can be tempting for a non-technical person to say, "Well isn't the opposite also true? Can't you break game dev rules then?"

    This isn't even a C# issue. There are similar arguments way back in the C++ days when avoiding the STL was a way to optimize your game. Avoiding the STL was a positively alien concept to business devs. Some things never change, I guess

    1. unity uses C# as a scripting language, not as C#, not as .NET
    2. as a scripting language, C# has some benefits, none of which come from .NET
    3. unity is a constantly evolving game engine, getting better all the time
    4. unity is a game engine, not a corporate platform, like .NET
    5. using the latest releases of Unity has LOTS of advantages, few negatives
    6. moving up through Unity versions doesn't entail a lot of scripting changes
    7. moving up through Unity versions often bring benefits worth the effort
    8. Unity is better than it ever was, for most platforms, in 2018.1 onwards
    9. capable .NET programmers are perfectly equipped to move up versions

    I think the really important distinction to be made is that while you're writing code in C#, the majority of what the computer is doing isn't in the scripting runtime. I would point out that the scripting runtime sits on top of a game engine, and understanding what's going on in the game engine part of the system is really important. A dev might know C# really well, but that's only part of the picture.

    "to a man with a hammer everything looks like a nail".

    Whether you use IL2CPP or Mono or not, data must be marshalled to C++ since that is what the actual engine runs in. The engine will always run as C++

    Another thing of interest is how to allocate variables in a class. In most
    business .NET software, variables get declared inside functions and cleaned up automatically as they go out of scope. With a game, there is often some performance to be gained by declaring some variables at class level and re-using them throughout functions. It goes against modern scoping concerns, but it addresses memory and performance issues that are usually more important in games. If you need a reference then store it at Start. Do not ever get a reference in an Update loop.

    On Unity nulls
    if(gameObject!=null)
    A faster solution to a .NET dev is to use the following: if(!System.Object.ReferenceEquals(gameObject, null ))

    Keep in mind that those two lines of code do not actually do the same thing. If you destroy the GO, the top line will work as you expect, but the bottom line will not since it still references the container object. Unless you actively assign null to the variable, that won't work in a lot of cases. Unity uses a fake null object and overloads ==, which means that using reference equals does not return the same thing as a regular null check. A GameObject can pass a reference equals check, and still throw a null reference error on the very next line.

    Instantiate/AddComponent creates a C# object and the corresponding C++ object together. It registers the newly created GameObject/Component with the various systems Unity uses. (Incidentally calling new on a GameObject does the same thing too, don't be afraid to use new GameObject("SomeName") when the situation calls for it).

    New is used for creating regular vanilla C# objects. It goes ahead and calls the constructor.

    The thing is you can't use new to create a MonoBehaviour or to add Components to a GameObject. Unity will throw an error. Even if you do create your entire structure without GameObjects, you still need to use GameObjects and Components to interact with Unity's rendering system (and physics ect too). Which means in most cases, you are better off just using components in the first place, rather then putting an extra layer in between you and the engine.

    Under the hood Unity reserves the MonoBehaviour constructor for its own purposes, and does stuff that isn't fully publicly documented hooking up internal engine stuff. There are other ways that probably could have been handled, but that's what Unity picked, so constructors are just out of bounds to us. Because of that they instead give us Awake() and Start(), but they really aren't the same thing for two notable reasons:

    1. You can't give them parameters.About the closest we can get is a static CreateBlah(...) method which calls Instantiate or AddComponent and then does whatever else we would want to do.

    2. Awake and Start are called at different times to a constructor. I believe that Awake is immediately after construction, so that one's pretty similar, but Start is called as a part of the next iteration of the engine loop. Understanding that engine loop and what it means for your objects and their lifecycles and when you can reliably access what things is pretty important, and fairly specific to a game engine (or similar real-time systems).
    This is of course only relevant for MonoBehaviour and friends. You can make plain C# classes and use their constructors and that's all groovy. You can use those classes from your MonoBehaviours, and you can have those classes reference MonoBehaviours to interact with the scene.

    I despise going though code and seeing myVal = 7f or myText = "hello world" and then looking in the hierarchy to find what this generic thing is referencing and everything has the default name. It smells to me like copying sample code and shows no regard for other team members working with your stuff.
     
  26. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    It was version based several years ago.
     
  27. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    That would certainly be awesome. People have been trying to just that for decades.

    The challenge is that when you are writing a game, you are coding against a whole stack of things that are constantly changing. You may be able to write some domain specific libraries that may last for while (like path finding or certain types of AI or game logic). But even then where it meets the engine code you will have to likely constantly update, and there is alway the chance that what you wrote gets implemented at engine level (or hardware level) or just more optimized than yours. Performance rules all (especially over sunk cost) and the one single feature that no game can do without is shipping. Will the additional time and resources required to build and test this code significantly reduce implementation time? If you are still you maintaining this code 5 years, can you reliably say that you wouldn't update or rework based on accumulated knowledge since then? (most engineers struggle resisting tweaking their code down the road). If not you maintaining, most likely another engineer or coder may just rework it or swap it out. Every coder is way better than every other coder. It always happens. It's a great plan/ideal, it just doesn't play out in reality in the games industry. If you step back in time 5, 10, 15, 20, 25 years, at each step the state of the industry, its tools, platforms and markets are radically different. That is what I love about this industry... it also the part that some people hate.

    A friend of mine works on transactional database software in the banking industry. Their stuff is hardened and abstract and nearly never changes. By contrast I have written several games in ide/engines that haven't been updated in decades and literally won't run on modern hardware. Heck, I have the source for some of those games that is on media that I have no way reading. (syquest drives). At disney we had archives of old games source that was written to run on compilers written for hardware that no longer exists (sgi/next/etc). We could tease the logic out of by reading it, but was rewritten, much cleaner and quicker using recent tools. (like Unity). In 5 years from now, things will have likely changed again.
     
    vfn4i83, Zarconis, adamgolden and 9 others like this.
  28. stain2319

    stain2319

    Joined:
    Mar 2, 2020
    Posts:
    417
    Very much this ^^^

    I work for an Enterprise software company. Big big corporation. One of the products we sell, the code hasn't changed other than minor bug fixes in over a decade...
     
    zombiegorilla likes this.
  29. stain2319

    stain2319

    Joined:
    Mar 2, 2020
    Posts:
    417
    Imagine a game that hasn't been updated in a decade. It might not even run on your hardware anymore.
     
  30. JohnnyA

    JohnnyA

    Joined:
    Apr 9, 2010
    Posts:
    5,041
    Just like in any other broad area of software engineering there is no right way to do something (there are some wrong ways). Within a specific context there might be generally accepted ways, and within a specific project there might be a specific choice made, but certainly there is no one true way to create anything.

    I can't imagine this is news to you with 30 years of experience.

    The way you have phrased this sends up a little bit of a red flag for me, one area where games development can be quite different to a lot of other software development is that different systems can quite often benefit from vastly different implementations. Technically that might be the case for enterprise software as well, but generally such optimisations are a net negative when you consider the performance benefit vs the implementation and maintenance cost.

    To use your bullet example:

    You might implement bullets as their own objects with colliders and the like, or you might implement them as a collection with custom physics, you also might implement them as a particle system, or you might even do it all on the GPU.​

    These implementations can be vastly different and setting the guard rails too high might lead to a conformity that is not in the best interests of the project.

    I would suggest keeping your guidelines a bit looser, focusing more on higher-level principles, rather than specific implementations, particularly in the early days of the project where things are likely to be changing pretty rapidly.

    ---
    Disclaimer: Of course this is made without any knowledge of the context of your game, so needs to be taken with a grain of salt :)
     
    Last edited: Jun 19, 2021
    NotaNaN, ippdev, Ryiah and 1 other person like this.
  31. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    5,181
    Knowing that all these solutions exist is power. Now you can test things out and make the best choice based on your overall project.

    I'd start with the simplest solution - whichever your team can implement fastest. Then only add or change onto that if absolutely necessary. It's a "work before play" principle. Later on you might have some breathing room from the project deadline and then you can noodle with different approaches to see if you get performance gains or sleeker workflow or whatever benefit. But get the important things taken care of first, which is to have a working product.
     
  32. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    You what is funny…. Last month I was going through some of archives looking for something and I found some really old prototypes I had made in flash/as3. The .fla files are completely broken and nothing really supports building a as3 project anymore. But the .swfs opened and played just fine. (There was no backend connectivity or anything). Didn’t expect that.
     
    adamgolden and MadeFromPolygons like this.
  33. lmbarns

    lmbarns

    Joined:
    Jul 14, 2011
    Posts:
    1,628
    I worked at a company that mainly did dotnet and cpp and the company grew to expand into Unity work where the hired me and some other folks. There was a big rift between us and the people who'd been there 10+ years, they felt like why are we hiring these guys, we should get that work. Many of those guys were amazing developers, very organized, particular about structure and couldn't wrap their heads around having to inherit from monobehavior and working with the Unity API. It just didn't fit in the way they approached software. We would sometimes split off work for them where they'd provide a dll we consumed as a plugin in Unity, mainly for networking, leaderboards, etc self contained stuff they could do.

    If you try to fight against the "unity way" or trying to justify why it's not right rather than learn it you'll have a bad time.

    -Pooling is almost always a good thing to do when you have many objects or objects that can be re-used
    -Avoiding allocations is more important here than most other types of software dev
    -Raycasts are often better than colliders on fast moving objects.
    -Arrays might have a slight improvement over lists in some cases but generally you're not noticing a difference if you use a List, Dictionary has a place over List in some situations but not all.
    -You absolutely do not want to iterate by type over the whole scene, and only during initialization to populate a list if you do
    -Linq and reflection can be god awful, moreso on constrained devices.
    -You rarely want to be concerned with script execution order, you want to use awake() and start() for initialization and only when you have a problem get into the weeds over script execution order, not start there.

    I'd study the mobile optimization tips because they're good tips in general:
    https://docs.unity3d.com/Manual/MobileOptimizationPracticalScriptingOptimizations.html and https://docs.unity3d.com/Manual/MobileOptimizationPracticalGuide.html
     
  34. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    I was in about the same situation as you years ago and have two things on a site. One is a short "Unity for programmers": taxesforcatses-dot-com/codeNotes/UforP.shtml. Next to it (one link up) is a "game design for beginners" which also might be interesting (it's suddenly in large text, which I haven't investigated yet).The other is a very large intro to vectors and rotations/quaternions (it starts pretty basic but goes somewhat fast): taxesforcatses-dot-com/vectorW/TOC.shtml where I assume basic coding/C#.
     
  35. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    Now, this is great advice. Exactly what I was looking for somebody from the trenches who has sene the pitfalls. I have taken to heart what you have said about mono and .net being different animals and treating them individually.

    I also understand "corporate code" vs "game code". One is more of a problem-solving approach and the other being a "patterns" methodology. I think we need to find a happy medium between the cowboy attitude of game developers and the corporate methods of development. The company was burned by a cowboy in the past and it has caused the pendulum to swing the other way, towards a more "concrete" code methodology.

    I have brought in a lot of things that should be in use in every studio as a base. Things like code repositories (we are using git, I dislike plastic SCM.) Standard libraries, and evening documentation. Shocking I know who would have thought documentation... :)

    The code will evolve over time, but when I finally put down the keyboard it will be with the understanding that what I pass on is complete, understandable, documented, and working.
     
    angrypenguin likes this.
  36. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    This is why all my original source, is in text. I even have the text for the original VB3 applications written in the earlier 90's and that is stored as a binary as well. I never used flash because my intro to code was from a keyboard, not an Adobe interface. Timelines scared me :)

    We have to think of conservation of knowledge as well. At least all of Unity is text files for scripts even if a lot of DLL's are getting compiled...
     
  37. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9
    I scanned through the document and found a few things of note. In specific the Synching, timing brought a few things together in my head. The other was the Destroy method for object removal. I had not run into that before. I really should sit down and read the Documentation from stem to stern but it is more fun to hack and figure stuff out.

    Thanks
     
    Last edited: Jun 23, 2021
  38. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,930
  39. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    But that's the opposite -- it's basic software engineering for game designers, not basic game design for software engineers. Programmers wanting to learn Unity already know that stuff. But it's neat to see a successful game can be made using sloptastic code.
     
  40. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,930
    Suppose that's a fair point. Just figured it was an interesting article, but I suppose I'm weighing in on matters probably a bit senior to my experience.
     
  41. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,052
    Code on timelines is bad! ;). AS3/AIR apps are built entirely from code, flash is just an asset wrapper for graphics and animations. (though programmatic animation is more practical if it's not frame by frame). You do, however, need the flash ide to make the connections, sadly. You can (sorta) still build old AS3/AIR apps... they just may not have graphics. ;). (for fun: https://www.richardlord.net/ash/)
     
  42. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,203
    Uncle Bob is fun to watch but some of his advice can be controversial because as a game developer you may need code that is fast moreso than code that is clean since once a game is shipped and has received patches for a time the code will often be set aside and never touched again.

    An example of one thing he touches on that has performance penalties is exceptions. He mentions you should avoid returning error codes and just throw the error but the following article discusses and benchmarks them showing they have a steep performance penalty.

    https://mattwarren.org/2016/12/20/Why-Exceptions-should-be-Exceptional/

    I do believe people who go into his talks with the intention of learning from him will come out better programmers but you will want to verify what you're introducing won't cause more problems as game development can be very different from more general purpose development and especially enterprise development.
     
    Last edited: Jun 24, 2021
  43. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Source for your program, yes. A game is a lot more than just the program though. Losing the source for your art, or software to use it, is just as crippling as losing the code.

    I am still semi-regularly shocked by hearing of "professional" studios not using version control.

    By now I shouldn't be, but I am.


    With the exception of Update vs. FixedUpdate. Know what goes in which, how they relate to each other, and strategies for working between the two.
     
    Deleted User and zombiegorilla like this.
  44. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    That's by-the-book advice from 1995. Old programs returned error codes and blew-up in size dealing with them. Every useful line of code had 3 lines after it checking for problems. The idea of throwing exceptions and being able to say "this function doesn't check for out-of-memory. You can if you want" was really something, esp. when we got automatic garbage collection (which meant when a function failed 1/2-way through allocating it didn't need special code to clean it up). Java's rule about listing all exceptions a function can throw makes a lot of sense as "you can be a slob writing it, as long as you tell me".

    That Matt Warren article appears to be criticizing throw/catch, but it's actually the same stuff we were saying when we invented it. Exceptions are things that aren't suppose to happen. It doesn't matter how slow they are, since your program already just broke. We used to joke about using them in normal code, like "if(i>=A.length) throw loopdone()". As a joke. We knew throwing non-errors was confusing and slow 20 years ago. That article mentions how C# uses try/catch for Convert.ToInt32(string) and how TryParse is better. Well, yeah, TryParse is a copy of how everyone else before C# did it. Microsoft is like Unity that way -- they give you an easy way to do it which you'll need to unlearn to do it the right way (but at least Unity is for game designers, who will be do fine never learning the "right" way).
     
    Deleted User and JoNax97 like this.
  45. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    Watching others come from coding I think you’ll find some of the challenges you are going to find are:

    -Design conventions, like the different ways to design character controllers or patterns specific to game design. Google “game design patterns”. There’s a great book out there that is 100% free on it.

    -Understanding performance and identifying bottle necks.

    -Principles of game design. Game design lenses is the absolute best book on the matter.

    -Cheats to free up the cpu and ram like cycling AI scripts, pooling everything, using a random number list rather than creating one when you need lots of them, and using raycast over physics whenever possible.

    -cheats to free up the GPU like using imposters or generating skyboxes rather than rendering distant objects.

    I’m totally a novice, but from my time in the forums these are the hang ups I see from people who know code but not game dev.
     
  46. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Oh! Further to this, game design != software design, functional design or code design. It's another thing.
     
  47. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,203
    zombiegorilla likes this.
  48. undevable

    undevable

    Joined:
    Dec 25, 2020
    Posts:
    140
    angrypenguin, zombiegorilla and Ryiah like this.
  49. Evil_Genius

    Evil_Genius

    Joined:
    Jul 14, 2019
    Posts:
    9

    Thank you. Specific advice is very useful, I already had a copy of "Game design lenses" ( The Art of Game Design: A Book of Lenses, Second Edition by Jesse Schell) on my shelf, and I googled for the game design patterns on your advice (and others) except I received a billion hits as usual :). Our main scene engine already has implemented an imposters system using the "Amplify Impostors" plugin from Amplify Creations. The environment artists have told me it improved things a lot.

    I am lucky that within my team we hired a pro optimizer who knows a lot of Unity "tricks" that have proven his worth over and over.

    Thanks again
     
    Not_Sure likes this.
  50. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    3,546
    Amplify makes some great stuff.