Showing posts with label Unity. Show all posts
Showing posts with label Unity. Show all posts

Sunday, July 22, 2018

Unity starter tips - performance.

"Uh oh. It's another one of those starter tips thing from people that thing they know game engines."
Yeah, it's one of those things. Things that I run into my self, and had to hunt them down all over the place when my projects had issues. Of course this is by no means the be-all-end-all list. But it is a start!

1) Remember to set up your project correctly in the Player Settings, set up skinning and batching depending on what you need (Leave batching on of course...), what to log...

2) Know your target platform. Not all platforms are created equal. You won't put the same effects (or the same quality effects) in PC and mobile. Mobile will just get single digit fps, if it will even work in the first place.

3) Set up your physics layers! If you have a physics layer for your player character and you know for sure that the character will never touch or interact in any way with objects belonging to a certain physics layer, disable their interaction in the physics matrix. There is no need to let the engine try to figure out if these two are touching since you know that they won't.

4) Bake stuff in maps! Even if you are targeting DirectX12/Vulkan with all the eye-candy possible, why waste cycles with having dynamic effects enabled for something that you know is going to be static? Bake those shadows and that occlusion. You'll take a tiny bit more to set them up, but you'll save on resources that you'll be able to use elsewhere and the people playing your game won't complain about fps drops.

5) Batch stuff! And Ι'm not talking only about dynamic batching because if abused, it may end up costing frames instead of saving. If you are making a detailed environment in a 3D modeling package, when it's time to export stuff, export all the stationary objects as one mesh, so when they go over in the real time engine then they will be treated as a single mesh.

6) Texture atlas. Continuing from #5, combine your textures for that scene into one big one, so when the engine goes to load the textures it won't go like "stop rendering, read from disk, load into memory" for every single texture. Sure you can't combine eeeeverything, especially the textures for character because if those characters are used in a different scene, then the whole texture will be loaded, even the pieces that aren't used.

7) When making a new script, always remove that Update function if it won't be used. If it's left there in the script, then the engine will still go in the loop every frame to see what it should do in it. It won't skip a function just because it's empty.

8) Comparing Tags. gameObject.CompareTag("thing") is faster than gameObject.tag=="thing".
So if trying to see if this is the right tag, use CompareTag. It is a native Unity function, compiles to fewer calls, it has less of an overhead... long story short, it uses less stuff and things add up.

9) Pool objects. It's really tempting to simply have a call that creates/spawns an enemy from a script. You just write it and when the game is about to use the enemy, spawn it. Well... that introduces hiccups when the entity is spawned, especially if there are alot of stuff going on with it. And if you have lots spawning; as we said already - things add up. Have a pool of enemies ready, just disabled or hidden out of sight, and when needed teleport the enemy where it's needed and have a boolean for that enemy that he is awake. When destroyed/killed, simply hide them again and set the boolean that they are free to be used again later on. This is really especially useful for example when dealing with waves of enemy ships. When they blow up, don't Destroy() the object, simply hide them.

10) Try to use Coroutines instead of Update functions in scripts. As we said in #7, Update is always checked even if it won't do anything. One of the first ways people just starting unity will use to try and control objects, is Update. At first, my self included at first, people will put a boolean in an IF check, and if true the object will do something. That hogs the main execution thread of the project. So use Coroutines instead. What are Coroutines? They are small routines that can be spun off into their own thing, running along the main thread, but unlike Update, they don't stay there looping and never letting the main thread continue. Coroutines can be called when needed, paused and delayed and when done they stop and go away. Useful for timers and controlling stuff!

Thursday, April 12, 2018

Spheres and UVs.

Balls. I'm not too fond of them when it comes to UV mapping one. Ironic, since the two games I made so far have nothing but balls. Spheres... I mean spheres.

Now those not in 3D graphics might wonder what UV mapping is. You see in 3D graphics you have the object represented in points that connect with each other in a certain hierarchy to form triangles, and those make the mesh. Think of it as a game of connecting the dots only in 3D space and that will give you a wireframe. Then you'd need a canvas to drape that wireframe and give it color. The traditional way of doing things is to make your mesh (your object) and then "unwrap" it, which is to take the mesh and open it up and flatten it into a 2D image to make it easy to paint on it. There are many ways of unwrapping a mesh and i'm sure that many have seen how a face mesh is unwrapped to its UV map. The easiest object to unwrap is a flat plane as that one is pretty much already unwrapped. But spheres... If you want to do some detail work on their surface you'll need to think of where you want to focus and unwrap accordingly. One would need to think of where the bulk of the detail is going to be and decide on the way to unwrap it, as depending on the way you unwrap a sphere, you might get different kinds of artifacts or stretch marks.

Default UV unwrap, next to its sphere mesh. If you noticed at the top and bottom of the right side, (the unwrap) you'll notice that the edges end up looking like a saw-blade. It's really easy to have details looking fine at the red zone, but if you try to add detail to the blue area, it will look as if it has stuff cut off. That's because you'll have pixels of your texture be unassigned to actual polygons. There IS a way to have the sphere look better but I have yet to see a default sphere from a modeling program look good on its poles. And now with VR and skyboxes in computer graphics, it gets more and more important to pay attention.
























If you click on the image above to open the full sized one, take a look at the center of the circles.
The image is from a game that was unfortunately shut down while still in beta and it shows artifacts in the center of the skydome. What you are looking at is me pointing the camera way up to look at the "sky", while waiting for the other players to get ready and start the match. The skydome is a sphere and while the rest looks fine, the last bit where the sphere ends up in the pointy bits looks collapsed. That happens when the pointy bits all connect to a single point and sort of pull the texture along.

Sure there is an "auto" button, but that one almost never gives you the results you might want, at least not with me... It could be a starting point for other kinds of meshes that you would then edit to bring up to snuff.

The way I ended up making my UV map was to make a custom unwrap, by actually projecting a flat plane towards the poles from the top, and then put the skirt that ends up being stretched to its own place. I thought of doing that as i wanted the poles to be easily texture-able.

I was also able to pack different looks for the ball into the same texture file, just to have everything in the same file. In hindsight it would have been nicer if i would have 4 textures in half the file size and load the one needed instead of having 1 big texture file loaded in memory and only use a quarter of it.



I really, REALLY wanted to make texture atlases for everything. Even when it wasn't needed...

The poles are both projected on a flat plane, leaving them with an area that can be easily textured. Top and bottom of the ball are reflected and placed on the same area in the UV map, with the waist being cut and projected on that yellow strip on its own.

I promise, the next time I need a sphere, I'll just either use a gradient from top to bottom, or just place a single color and skip texture making on the whole.

Tuesday, November 22, 2016

101 texturing aimed at mobile games. (Just bake'em all in there)

Yes, mobile GPUs have gotten really fast. Yes, they can make more things than consoles from some years ago. But there is still something that hasn't improved yet. Battery life.
Forcing more fps means less battery life and a hotter device. But more so does giving more stuff to the GPU/CPU to calculate. Of course they can do effects like normal mapping and real time shadows, reflections/ refractions... But when running on a device that its battery only lasts for one or two days when on standby, that isn't such a good idea.

So... what's usually done on the art department is to cheat a bit.
Consider the scene below. From certain angles the floor looks as if it has some overhang and a relief/sculpted effect. (It's used in fact in a lot of places in the project).


The most common way to do so in a 3D project would be to use a normal map in order to give the lighting information to the rendering engine and have it react correctly with the lighting.

But in a mobile environment you'd want to have the device have the least amount of work to do possible. Think of PCs and consoles good at marathons, with mobile devices good for sprints. Even though a Nintendo 3DS or a PlayStation Vita are mobile consoles running on batteries, they have chips with relatively slow speeds running as fast as they can, while mobiles are given fast, multi-core chips; and we are trying to give them as few things as possible to do, because the more you give those chips, the faster they'll go, and the more battery they'll eat up.

So back to the scene; see that chiseled effect that gives some highlights on the sides? Or that shadow effect? Well those are all baked into the texture, meaning basically that they were pre-drawn in the picture that gets wrapped around the 3D object. Lighting is faked as well, with only a couple objects actually using lighting calculations done in real time. (The ball is one of them since you will be moving it, faking it on the ball won't do as the highlights won't move. It has a small normal map to give it bumpiness. It's ok to do stuff like that if they aren't covering much of the screen.)



Above you can see the actual model of the platform blocks with no textures and in the lower right corner part of the texture atlas that has the texture info for all the platforms in this scene.
Which is another way to save on resources; placing as much stuff as you can on a single file so that the engine will only need to read one file once - but do that for things that won't be needed in a different scene. If you take a single object that uses this texture and put it into another one, then the engine will have to load the textures for that scene, plus the whole texture for that single object even if only a small part will be shown on screen.

All the shadows and highlights in the texture detail shown in the corner above were made in Photoshop, while the ambient light and shadows visible in the scene were precalculated by the engine and saved in their own image file as well. So that information is not being calculated while playing the game. That has its own limitations, but it helps in lowering the work needed. Since the light source and/or the platforms don't move, painting the highlights and shadows before hand saves on resources.



  




Wednesday, October 12, 2016

Quality settings on mobile VS battery life

(Repost from the dev blog)

It's always important to try and balance image quality vs performance in every project because when you get up to a certain point with a certain tech, then it'll stop giving out better perceptible image quality, while still eating up CPU and GPU resources. This is even more important on mobile platforms since they are powered by a battery and more strain on those components means less battery time.

When i was making my game i thought of adding an option to select the texture quality in the game in order to save RAM on devices that don't have a lot of that precious resource. All it does is if you set it "High", it will render the textures in their full resolution and have anisotropic filtering on, and if you select the "Low" setting it will render the textures in half their resolution and disable anisotropic filtering.

You can see the difference that the option actually makes. Left is High quality, right is Low quality. It may not look like much of a difference on a small screen, but it halves the amount of RAM used by the textures.


However: One my friends testing the game decided to do a small benchmark on battery life VS textures. Granted, the way it was done needs more refining and better controlled environment variables, but for what he wanted to check it's good enough. He just wanted an indicative value.

He took his iPhone 6s, went into flight mode and then only enabled the phone's WiFi. He then had just the game running and played the actual stages while timing himself.
The first run was done with the quality setting on High, and the second run on Low. He said that his times were very close with give or take just a couple of seconds. (And i trust him on that. He found exploits or "shortcuts" in the stages that i couldn't.)

And the battery life?
On High the battery went from 100% down to 70%.
On Low it went from 100% down to 89%

Granted, it does need a more controlled test with an automatic timer and standardized routes and video evidence, but this does show a bit how just changing the texture quality will affect battery life instead of just RAM usage. Personally i wasn't expecting such a difference on a device that is more than enough to play the game fine while the only thing that changes is the Texture memory use. No Level of Detail thing going on here or polygon reduction on Low setting.





On the left, Level selector for World 2 stages.
The texture on the "Low" resolution setting gets blurry as it is half the resolution of "High" mode.














On the right we have World 2 Stage 7. Same thing on this one as well. In some elements the texture resolution reduction is more evident than others, but it happens to all textures regardless.













   

Monday, June 8, 2015

Nooby Unity tip - why you need prefabs.

Some people will tell you to use prefabs for safety and some will tell you for convenience when assembling scenes. Both reasons are true and more than enough, but I like prefabs for one more reason.

It makes it really easy to select complex elements in your scene that are made out of multiple gameObjects. Even if you have a label on your complex element, it will only select the whole thing if you click on that label. But if it's a prefab, it will select the whole thing anyway instead of the individual gameObject that is right under the mouse pointer. If your complex element doesn't have a prefab connection, it will select the individual gameObject that is directly under the mouse pointer. Want to select a single object in your prefabbed element? Just click again. (Or just directly double click on that object in the first place.) Handy for moving things around the scene.


Left object has a prefab connection, right one doesn't. I'm only clicking once on them, both have labels. Click on the GIF for a better look.
Adventures of a Rubber Ball thread.

Friday, September 12, 2014

Design/graphics cheat #2 - Mobile gaming

Mobile gaming is all the rage now, and companies are showing their latest phones, tablets, phones the size of slippers and chipsets for 3D graphics on-the-go.
Everybody are now showing off some awesome looking shaders, effects and high polygon (for mobile) models making sure you realize that it's rendering in real time. There's something that they don't show a lot though and that's real time - level wide shadowing. And there's a good reason for it as well; it's probably one of the more resource intensive stuff to pull off well enough, so people making games are resorting to all sorts of trickery like "baking" lighting, drawing the details in the textures instead, using shadow "blobs" for stuff that's moving... in general cut using realtime shadows in mobile gaming as much as possible.
(It can be done of course, but most of the time you'd be better off faking it and pushing your savings on making the game run at more fps or implementing some more resources into your enemies.)

So where am i going with it? 
Be smart in hiding things and using simple geometry to make shadows. Like the image on the right; those two things are just some of the obstacles in a game i'm trying to make that spew snow balls. 
I really wanted to have some slight shadowing/ darkening effect in those barrels. Light mapping wouldn't work of course because ... that's not how it works... and real time shadowing would be no-no. 


On a game you are trying to include as many devices as possible after-all to potentially have a larger install base. So it's back to old-school tricks, back to basics if you like. The barrels simply have 3 simple planes, with just 2 polygons each, and a simple black texture. Then the texture's alpha channel is set as semitransparent. Each plane will progressively make it look as if it's darker and darker the deeper you look. Of course this will only work for stuff that aren't out in the open.

For things that are out in the open, what someone could do is mark areas with simple trigger boxes that are placed in shadowy areas. Then have a simple script that would smoothly make the texture of the object that enters the box's volume darker, and lighter as the object exits. A poor man's light probe if you like. These things do require tweaking though, but the plus is that your game's speed won't suffer and you'll get some nice looking stuff.

Monday, September 1, 2014

Man I feel dumb - Unity animations and scaling.

Don't, just don't change the scaling of an object inside Unity. Even if your object has 50 polygons.
It'll f@(k your fps. Pardon the language but it'll just ruin your day if you are doing for mobile. Just take the extra time to make your scaling animation in your 3D package of choice and save the animation as blendshapes or whatever it's called in there.
I just wanted to squish 2 bellows. But nooooo. I have to do the whole blendshapes thing. Can't just change the z value.
Sorry, I know it messes up with batching, but I just didnt' expect to lose close to 25fps.
(And I blamed my rigidbodies. Sorry bodies....)

Wednesday, June 25, 2014

Free tileable stone sidewalk/road texture package for Unity

As the title says. I was taking a stroll around the city and found a stone-paved pedestrians path so i snapped a picture of it and treated it to be tileable. Also made an alpha channel and normal map in the PSD so that Unity's specular shaders will only apply specular to the stone and not everywhere. The asset is free; over at Unity's asset store.

Link: Cobblestone in Asset store

Tuesday, March 25, 2014

Unity3D mobile quicky noobie note.

So you are making something in Unity for mobile (lets say Android). You went ahead and selected your resolution in the preview window ("Game" window) And set your GUITextures with pixel inset values in the inspector. You might have even made a script that calculates things according to the screen resolution in X and Y to find ratios and what not. Then you deploy and you notice that something is off by a couple of pixels. You double check and things are ok but still get shifted in the screen.

So what gives? Well, Unity may have 1280*800 or other standard resolutions built in, but what the OS gives to the player once you actually have it running on the device is not exactly that. Remember it has the home bar. So that takes some pixels away from the real-estate, 28 pixels as far as I could tell in the case of 1280*800 screen resolution.

Just make a custom preview resolution of 1280*752 so you won't have to keep that in the back of your mind. I'm sure there are other a lot more elegant ways of solving this, this is the easiest thing I thought about.

Tuesday, January 21, 2014

Noobie trap in Unity. (Or "How time flies". Or "Time.deltaTime")

So i wanted to make a small timer in the upper left corner of my small game.
Extremely easy; you just have a variable storing float values and add Time.deltaTime on every frame to it (deltaTime is the time it takes to render a frame.)
Thing is, if you are using something other than "1" in time scale or playing with timeScale to do some slow motion effects, your timer will get out of sync with the real time that has passed. If the timer is to trigger an event in game to happen, no biggie.
If it's for stage scoring or leaderboards though, then the timer needs to be in sync.
So just take into account timeScale. Just divide Time.deltaTime by timeScale to always keep the timer counting in the same speed. (i.e. real speed, the same speed that a wall clock does).

timer+=(Time.deltaTime/Time.timeScale);