• Advertisement

lougv22

Member
  • Content count

    120
  • Joined

  • Last visited

Community Reputation

392 Neutral

About lougv22

  • Rank
    Member

Personal Information

  • Interests
    Art
    Audio
    Design
    Programming
  1. An interesting article and an impressive idea about a playable menu, but I couldn't help wandering to myself, they spent a lot of time on a menu, wouldn't some of that time have been better spent on adding more gameplay and content to the game?! Generally speaking, if a game is engaging and has interesting gameplay, characters, music, overall ambiance, etc., players will go through the effort of reading a tutorial or asking somebody or even looking up online how to play it. Look at some of the more popular arcade games from the 80's and 90's, for example. There was very minimal information about the controls and how to play the game, but players learned if they liked the game enough. In games like Mortal Kombat and Street Fighter, for example, there wasn't really much of anything in the game about what buttons did what. In MK, which is notorious for its fatalities, there was nothing in the game about the button inputs to perform one, but players figured it out and shared the knowledge amongst each other. I am not criticizing, per se, more like wandering about the merits of adding playable menus and how much playable to make them. It seems to me something like in Antichamber is more optimal. You still get the playable menu feel, but really the "play" part is very minimal and it only serves to teach the player the controls of the game.
  2.   That's great advice! Plus, if an input system is well designed, it shouldn't be too hard to switch from one system to another, if necessary. Good software design principles are universal, after all. Thanks for that.   @kburkhard84 It's unlikely it'd be finished soon, i.e. it'd probably take a while longer.
  3. Thank you for the detailed and informative responses, everyone. It's clear to me now that I have to support both Keyboard/Mouse and a game controller (s), at the very least. In addition, all types of input have to be configurable with ability to save input configurations, of course, and an option to reset to defaults. The next question I have is whether to use a third party input system for Unity, such as ReWired, or Unity's new input system. I have done some research into ReWired and I agree that it is superior to what Unity offers out of the box today. However, there is a new input system in the works for Unity, which sounds promising, and they should be releasing an experimental version this summer. Here is a link to their blog: https://blogs.unity3d.com/2016/04/12/developing-the-new-input-system-together-with-you/. In general, if Unity offers a certain feature out of the box, I prefer to use it over any alternative third party solutions, provided their functionalities are fairly similar. Any opinions on ReWired vs. this new input system?
  4. So I am an indie developer, working on a third person action adventure-like game in Unity. So far, while developing the game, I've only been playing and testing it with a keyboard. However, now I want to add support for a controller (Xbox One for example) as well. My question is, should I support inputs with a keyboard and a controller both? I personally am a console gamer and I only play games with a controller, so that is my preferred inputs scheme. In addition, supporting only one control scheme would reduce my development effort. I do realize though that, since the game in question is a PC game, I would think a lot of gamers would want to use a keyboard.   What is the prevailing design philosophy on this? Do most players on Steam, for example, prefer a keyboard? Would there be any harm in only supporting a controller?
  5. XPO Retrospective

      That's a good tip. Thanks. I already started doing that while playtesting in Unity, but hadn't thought to do it while in the editor.   After learning the lesson about testing in a build the hard way, I am now testing testing every new change in a development build. It doesn't take much time and the pay off is immeasurable.
  6. XPO Retrospective

    Long time reader, first time journal poster here. This is regarding a game convention called XPO, where I showcased publicly for the first time an indie game I've been working on for the past three years. And more specifically, it's about the lessons I learned from it. The game in question can be described as a fighting game with RPG elements and it is being developed in Unity. It's something that has been on my mind for a while, but I didn't start any real development on it until early 2013. XPO, which took place in September of this year in Tulsa, OK, was the first, and so far only, convention I've showcased the game at. Up to this point, I didn't think it was good enough to be publicly exhibited. And without further adieu, here are the most important lessons I learned from the whole experience: Lesson 1. Test the game in a build as often as possible (under different resolutions and aspect ratios). Because I had never done this until the week of the convention, there were a great number of things that did not work correctly in a build and there simply wasn't enough time to fix all of them, so I ended up demoing the game in the Unity editor, which was not optimal. It is much easier to position various UIs (user interfaces), dialogs, and other game objects where they need to be as you are developing them, when all the various conditions and parameters are still fresh in your mind, as opposed to coming back later and adjusting them. For example, now that I've learned this lesson, I am re-working big portions of the game to make sure it runs in a build. One of the biggest issues I've encountered is with the positions and sizes of my UIs. Many of them I simply hard coded to get them to work when I needed them, but as you can guess, they did not work so well in a build. In order to address that issue, I am currently re-doing all of my UIs to make use of the Canvas system in Unity, as it has built-in features for adjusting the positions and sizes of UI elements as the screen resolution changes. As you can probably guess, this is a time consuming enterprise, which would have been a lot less painful had I planned for it from the beginning. Plus, making sure the game works well in a build forces you to think about important details, such as what resolution and graphics quality your game should be playable under, where should data files be located, etc., early in development. Lesson 2. Have other people test the game as often as possible. It is a well known, and oft ignored, maxim in the professional software development world that a developer cannot, and should not, test his or her own code. They are simply too close to it and subconsciously, or rather consciously at times, "test" it in such a way that it does not break. Unit testing can do some of the work for you, but really nothing is a substitute for another human being playing your game and actively trying to find ways to break it. The reality though is that indie developers, such as myself, don't really have the resources to hire testers to playtest a game on any kind of a regular basis. We are often limited to friends and relatives, or just doing it ourselves, which is pretty much what I did, other than one playthrough done by my spouse. If your game has been tested on a regular basis and you already know everything works well, that will give you confidence in your creation, which will show through to whoever you are talking about it with. And as a very nice added bonus, it will also save you from having to frantically fix bugs in your hotel room the night before the convention. Trust me, I've been there, I know, it's a stressful experience that I don't care to repeat. It is, shall we say, unpleasant to find out the night before you are supposed to be showcasing your game, that it doesn't work in a build so you have no choice but to have people play it in the Unity editor, not to mention finding out that a major feature you introduced specifically for the convention, such as being able to restart the game, has caused hard to find bugs and you have no choice but to scrap it. It sucks! Test your game early and often to prevent all that. Lesson 3. Have the game playable on a TV. Somehow I had convinced myself that as soon as I had set up my laptop and started up the game, people would line up wanting to play and asking me all sorts of questions about it. Talk about wishful thinking. Well that was not exactly the case. People were walking by, but did not seem terribly interested in approaching my booth. I am sure the location (off to one side and facing away from the entrance) did not help things a whole lot, but I am convinced the bigger reason was that my set-up was simply not appealing enough. I had no posters or marketing materials of any sort, just a laptop screen facing towards the convention floor. In contrast, the main indie games booth hub, other than being directly in front of the entrance and thus being difficult to miss, was populated by big screen TVs at elevations high-enough to be seen from pretty much anywhere on the expo floor. It was only logical then that people would congregate around them and hardly even notice my less catchy set-up. Lesson 4. Have the game playable with a controller. Being a console gamer, perhaps I am a bit biased, but watching people play my game, hunched over the laptop and struggling with the keyboard, it dawned on me it would be so much easier if they could just pick up a controller and play. Plus, with a controller there is less opportunity for errors, i.e. only the buttons that do something in the game are available to the player. Even if they wanted to, they could not press a button, or a button combination (such as Escape or Ctrl + Alt + Delete), that could cause your game to exit or transition into some other undesirable state. Lesson 5. (Almost) always develop as if you are preparing to showcase the game at a convention. When you are in the midst of development and really want to pump out a cool new feature, it can be very tempting to "leave things for later". Or when you are faced with a looming deadline. Of course, the reality is that it is impossible to never leave anything for later, but you should try to minimize that and think really hard before you do (leave something for later, that is). In my case, I had left so many things for the proverbial later that when the time came to showcase the game at an actual convention, there simply wasn't enough time to address them all, so I had to cut features and otherwise make compromises just to have the game be playable at the expo. This also goes hand in hand with some of the other lessons, particularly #7 below, but long story short, (almost) nothing during the development life cycle of a game happens in a vacuum. All aspects of a game, especially the code, go hand in hand together and many are dependent on each other. So if you leave one thing for later and that one thing depends on, or affects, five other things, the amount of time and effort it would take to finish or fix that one thing several months later would be significantly higher because the other five have most likely changed, or they would have to, as a result of the thing you change. Lesson 6. Add a main menu screen. I noticed the guy on the table next to me, who was showing off an open world MMO with western themes, had a pretty nice main menu that was constantly looping while the game was on stand by, and it made his game look polished. By contrast, my game thrust the player directly in the first level. Now granted, you are not expected to have a finished product at a game expo, but whatever you do have should look as good as possible, and a main menu is just the sort of thing that can make your game look more like a professionally done product as opposed to a hobbyist project. Lesson 7. Emphasize (code) quality over quantity. As a software developer by education and trade, I've always tangled with the million dollar question, "How to build better software?" One conclusion I've reached is that creating good software is very much like building a brick fence. You lay down a layer of bricks and then another one on top of the first one, then yet another on top of the second one, and so on and so forth. Now, if just one of the bricks in the very first layer is a tiny bit askew, that's not a big problem, plus at this point you only have one layer so really, your fence is just as stable as if that one brick fit perfectly with all the rest. However, if you now put down a second layer on top of that first, imperfect one, your fence will be a tiny bit unstable. Still probably not a big deal, right?! You are on track to meet your deadline, so things are good, ....maybe. However, think about this now. If you wanted to fix that first layer at this point, you would have to undo the second one, fix that one brick, and then redo the second layer. Of course, things are not as clear cut in neither real life brick fence building or software development, but you get the point. To continue with my analogy above, if you leave the first layer imperfect as it was and not only that, but you also introduce a faulty brick in the second layer too (because again, you had to meet a deadline or some such) and then you erect a third layer, your fence is now starting to get a bit wobbly and the cost of fixing all that would be even greater, as you would have to undo and redo two layers. I am pretty sure you see now where I am going with this, but let's continue with our example a bit longer. Now let's say in layer #3 not one, but two bricks are off and don't quite fit very well with the rest of the bricks, partially because one of the bricks is now on top of the imperfect brick from layer #2. You still march on, however, and you construct layer #4 on top of #3. At this point, the whole thing is starting to get noticeably unstable, but the cost of fixing it grows higher and higher and you now start realizing it would take so long to fix all the issues that you would be severely over budget and behind on your deadline. So you do the thing that so many other developers do, and that seems the easiest at this point, and you keep on building on top of an increasingly unstable foundation, you keep on patching and duck taping the fence, just to keep it standing and your boss happy. The time comes, however, when the fence is so unstable that it becomes impossible to patch it up anymore and when that tipping point is reached, the whole thing simply collapses under its own weight. The only way to fix it at this phase in development is to scrap the whole thing and start over. That's the very situation we want to avoid by following software development best practices, measuring twice before cutting once, and so forth. As a side note in regards to best practices, I would highly recommend the SOLID principles of software design. So after this very long example, back to my lesson. After spending a few months preparing my game for XPO, I realized my code base had gotten big enough to the point where I could not really afford to add any more poorly designed or implemented code, or I would risk my "brick fence" going over the wobbly point of no return. From this point on, I decided, it's imperative that all new code is well designed and implemented in accordance with best practices. I suppose the whole point of this lesson then would be that "this point on" should really be the beginning of your development cycle. Lesson 8. Go and find people to play your game if you have to. For whatever reason, poor location, the small laptop screen the game was showcased on, etc., people were not coming up to my "booth". So after some time, I decided that it was up to me to convince them to try out the game. And so I did. I watched the people pass by and when I spotted what I thought was a good candidate, a young guy walking by himself, I went up to him and said, "Excuse me, do you mind playing my game? It's an indie game I am working on and I need some feedback. You can get free candy if you play". And the guy said "OK". Boy was I happy. The first stranger to play "Genosaga"! Bonus lesson: 9. Bring candy. Why not? Can't hurt. People like free food. See Lesson #8 above.
  7. For those interested, here is the solution I came up with, thanks to user JoshuaMcKenzie from the Unity forums. It's based on the Adapter software design pattern. First I have an interface representing the behavior of an image component with a texture: public interface IImageComponent { void SetTexture(Texture2D texture); } Then I have an implementation of the interface above for RawImage. This is an adapter type class whose job is to provide communication between a Unity image component, such as an Image or RawImage, and a logic class that performs operations (such as show, hide, and set the texture) on the image component: public class RawImageAdapter : MonoBehaviour, IImageComponent { public RawImage Image; public void SetTexture (Texture2D texture) { if (Image == null) { return; } if (texture == null) { throw new System.ArgumentException ("Texture reference could not be created."); } Image.texture = texture; } } And finally, there is the TextureHandler class, which doesn't know about the Image Component it's affecting, not even the RawImageAdapter (just that its referencing some class that implements IImageComponent). Because of that, it's decoupled from RawImage allowing me to swap it out with, for example, an Image + ImageAdapter class: public class TextureHandler : MonoBehaviour { // An array of textures for the level images. public Texture2D[] SmallLevelImages; private int _imageIndex = 0; public IImageComponent textureComponent; private IImageComponent TextureComponent { get { if (textureComponent == null) textureComponent = GetComponent<IImageComponent>(); return textureComponent; } } /// <summary> /// Gets or sets the index of the image. /// </summary> /// <value>The index of the image.</value> public int ImageIndex { get { return _imageIndex; } set { _imageIndex = value; } } // Use this for initialization void Start () { // There is nothing to do here. } // Update is called once per frame void Update () { TextureComponent.SetTexture(SmallLevelImages[_imageIndex]); } void OnEnable() { _imageIndex = 0; if(TextureComponent== null) return; if(_imageIndex < SmallLevelImages.Length) TextureComponent.SetTexture(SmallLevelImages[_imageIndex]); this.enabled = true; } } So we now have a solution which works for any image component. The IImageComponent interface and the TextureHandler class would stay the same for any image component. Only the adapter class would change. 
  8. I see. Funny, this is the exact same video I was watching the other day as my introduction to panels.
  9.   Kind of a late response, but I am just now learning about panels. Is the standard practice to put all UI elements in panels for better positioning and resizing, etc? What would you use panels for and when?
  10.   I cannot assign the image directly because I don't know at compile time what the image is going to be. I do need to have special logic for deciding what image to assign, depending on various conditions in the game.   That's a good tip about storing references to components that are used multiple times.
  11.   So doing it in the Update function is the wrong place.   If you want to animate graphics, use their Sprite system. If you're changing text, use the Text object and change that. If you want to hide or show images, enable or disable the object or the component. Wrap these calls in functions if you like but trying to abstract away the entire engine is just going to cause more trouble than it solves.     I am not sure that creating abstractions would cause more problems. For example, currently I have 8 UI scripts for the minigame in question, which are tightly coupled with GUITexture. Now that I am switching to Canvas and planning on using RawImage components, I have to write 8 more scripts, tightly coupled with RawImage. Then what happens if I decide to add some Image components? I have to write more scripts, tightly couple with Image. While if I can somehow write generic scripts that handle all image components, that would save me a lot of extra code.   Somebody above mentioned using the Graphic class, instead of RawImage or Image, since both inherit from it. That sort of works, but Graphic doesn't have texture or sprite attributes, so I still have to write tightly coupled code.   I am currently pondering an architecture utilizing the Adapter design pattern. That might be what I am looking for.
  12.   Nope. That particular script simply sets a texture, to the GUITexture component, that shows what level the player is on in a mini-game, i.e. something like Level 1, Level 2, etc. Although one of the other scripts inheriting from InterfaceHandler does simulate a very simple two image animation.   Basically, I need a generic, re-usable way to hide or show a GUITexture, RawImage, or Image component and to also provide capability to change the texture (or sprite if it's an Image, as Image doesn't seem to have texture) attribute of said component to different images.
  13.   I am not very familiar with Canvas, so it may well be over-engineering, but I can't help but feel there is a way to design this so that it's re-usable and not tightly coupled to a GUITexture or RawImage or some other graphics class.   And I currently have 8 UI elements that have scripts inheriting from InterfaceHandler above. Most of them either call the Hide or Show method (or both) and set the texture property of the GUITexture component. Here is one more of them, this one alternates two image to create a very simply animation: public class InterfaceHandlerB : InterfaceHandler { private int _imageIndex; private float _speed; public Texture2D[] sweepingFrames; // Use this for initialization void Start () { _imageIndex = 0; _speed = 3.0f; Hide (); } // Update is called once per frame void Update () { if (CurrentState == State.Clean) { GetComponent<GUITexture> ().texture = sweepingFrames [_imageIndex]; _imageIndex -= 1; _imageIndex = Mathf.Abs (_imageIndex); CurrentState = State.None; } }
  14. So I am working on an indie game in Unity and I've recently decided to move all of my UIs (user interfaces) into Canvas game objects, which is fine and dandy, but it does require me to re-write some code. Specifically, I have the following architecture that relies on the interface game objects having a GUITexture component: public class InterfaceHandler : MonoBehaviour { /// <summary> /// Hides the GUI Texture. /// </summary> public void Hide () { GetComponent<GUITexture> ().enabled = false; } /// <summary> /// Shows the GUI Texture. /// </summary> public virtual void Show () { GetComponent<GUITexture> ().enabled = true; } void Start () { } // Update is called once per frame void Update () { } } public class InterfaceHandlerA : InterfaceHandler { public Texture2D[] Images; private int _imageIndex = 0; public int ImageIndex { get { return _imageIndex; } set { _imageIndex = value; } } // Use this for initialization void Start () { Hide (); } // Update is called once per frame void Update () { GetComponent<GUITexture>().texture = Images[_imageIndex]; } } The problem is that with Canvas, there are no GUITextures. Instead I have to use RawImage or Image. So now I have to either re-write the code above (there are many more classes that inherit from InterfaceHandler, InterfaceHandlerA is just one of them) or write all new code that does the exact same thing, except with RawImage or Image instead of GUITexture.   This seems like a good opportunity to stop, take a step back, and really think about how to properly engineer this thing. I want it to be re-usable and maintainable, so that if a year from now Unity decides to replace Canvas with something else and there are no more RawImages, my code would still work. I am thinking maybe some kind of Dependency Injection might work here, or perhaps Generics, i.e. something like this: public class InterfaceHandler<T> : MonoBehaviour I tried the approach above, but it tells me that type T doesn't have a property called 'enabled'.   Any other ideas? What would be the best way to architecture this?
  15. Thanks for the replies guys. Lots of good info here.   @Norman Barrows, in my case since I am using Unity, I think my best bet is to make use of their Canvas UI system, which takes care of scaling up the UI to whatever resolution the player is using. For example, in the image below, I've picked the Scale With Screen Size option for the UI scale mode, which should scale it up or down from whatever I pick for reference resolution.   And if the aspect ratio on the player's machine is different, then it uses the Screen Match Mode option that lets you select how to resize the UI.   The whole Canvas system is new to me, but it looks powerful from what I've seen so far. That should take care of all resolutions and aspect rations, shouldn't it?  
  • Advertisement