I'm using multi resolution technique number three as written in this article
and to determine the scale factor and stage size, I'm using this piece of code originally written by Jeff :
if (Capabilities.screenDPI >= 200) {
if (Capabilities.screenDPI >= 280) {
AssetFactory.contentScaleFactor = 2;
}
else {
AssetFactory.contentScaleFactor = 1.5;
}
}
else {
AssetFactory.contentScaleFactor = 1;
}
var mViewPort:Rectangle = new Rectangle(0, 0, stage.fullScreenWidth, stage.fullScreenHeight);
mStarling = new Starling(Startup, stage,mViewPort);
mStarling.stage.stageWidth = stage.fullScreenWidth / AssetFactory.contentScaleFactor;
mStarling.stage.stageHeight = stage.fullScreenHeight / AssetFactory.contentScaleFactor;
Then I use this scale factor to determine which sized assets I need to pick.
So now, I have a background which I strech to stage width and size. This technique works great when I'm testing with most devices but then we have devices like the Barnes and Noble Nook Color.
The device has a resolution of 600x1024 with 170 dpi. This means that it's going to pick the smallest assets (320x480) and strech it to 600x1024. Which ofcourse is pixalated. Any ideas on how to get over this issue?
I'm also attaching a test application which shows the issue in detail https://dl.dropbox.com/u/2192209/scaling%20test.zip
What worked for me best so far is not scaling Starling's viewport at all. It should always remain the base size (320x480).
Then you have a scale factor about how big the texture should be. It's a built feature of Starling when creating a texture - passing a scale factor.
What this means is that if your stage is 640x960, your scale factor will be 2. Your image (Bitmap object), will have ACTUAL SCREEN size of 320x480 (fullscreen, 1:1 with stage size), BUT it's texture (loaded asset BitmapData) will be twice as big (640x960, 1:1 with phone size).
For easier understanding - the stage of Starling (320x480) will be scaled up to fit your phone's resolution (320 -> 640). But your images will be scaled down to fit in the stage (640 -> 320). So you get perfectly normal images.
This helps you maintain fixed size of stage. It's really helpful, because otherwise it would be hard to position objects - if you want the object to be in the middle, it's sometimes 160, sometimes 320, etc. This means you always have to set position/size with calculations, which is an overload.
Hope that helps!
edit: Just remembered of a site I've used to determine my main size and assets ratios: http://screensiz.es/phone
How about setting max scale size? If the conclusion of the calculations above takes you to scale that is grater than 2, use bigger assets to reduce the scale ratio.
Your calculation only takes screenDPI in count, try combining them with screen resolution as well.
Related
This question must have been asked here before, but I can't find a proper explaining answer.
So I'm a new unity3d programmer who knows about C#. Now, I selected my canvas size to 854x480 and tested the scene on moto g, samsung tabs etc. They all look same and I wonder why. Because if I design for 854x480, shouldn't I get blue bars on high-res phones?
Another question is, how do I design it so that it looks all the same on different devices. In my case, 854x480 does look zoomed a little on a kindle fire.
Please provide a conceptual answer.
The concept behind this is the aspect ratio and scale factor.
Aspect ratio = width / height
If you run your game in any device with the same aspect ratio then your game will look exactly same because the scale factor for height and width is same.
In your case,Aspect ratio = 480/854 = 0.562
If you run your game on Moto G(1st Gen) which has a resolution of 1280 x 720(In portrait),
Aspect ratio = 720/1280 = 0.562 which is same as your canvas's aspect ratio so the scale factor for width and height will be same.
Now if you run your game on kindle fire, which has a resolution of 1280 x 800,
Aspect ratio = 800/1280 = 0.625 which is not same as your canvas's aspect ratio. So the scale factor(which unity will automatically calculate) will be different for width and height(In your case, scale factor of height will be more) and hence your assets will look a little zoomed in height.
Hope it explains the concept.
The thing is that the camera rendering frame changes based on resolution, so instead of "blue bars" you get extra rendered image that is displayed instead of it, as for the UI goes, since it can't render extra UI (there is no extra UI, everything has to be shown) it changes position and scale of elements by using anchors. You can change these setting when selecting Canvas and changing values in the inspector.
I want to create a 2d games on Unity (like Doodle jump) but I don't how I can resize the screen (camera and sprite) for all resolution.
Thanks you in advance.
You need to stretch sprites dynamically depending on the resolution (width and height)
This information you can get from Screen
Imagine you have resolution 1024x768, for these resolution you created sprite 256x128 which looks good, however if you would run it on device with higher resolution - your sprite would looks to small so you need to stretch it proportionally to the new resolution
Here is how I would solve this problem:
imagine resolution 1024x768 = 100% and 256x128 = 100%
If resolution jump to 1280x800 we need to find on how many % it did increase
lets take width for a start:
1024 = 100%
1% = 1024 / 100 = 10.24
1280 / 10.24 (or 1%) = 125%
125% - 100% = 25%
So we need to re-size our sprite width on 25%
in the same way you find % for sprite:
256 = 100%
1% = 256 / 100 = 2.56
2.56 (or 1%) * 25 = 64
125% = 256 + 64 = 280 - this is new width
Repeat the same for the height, or you can find proportion for height depending on sprite size.
Note: Sprite quality might be reduced if you stretch it or shrink it too much, use vector graphic for your sprites.
There are awesome suggestions and links in this thread.
Also, if you are developing 2D games on unity, I'd recommend you buying this asset called 2dtoolkit.
This costs money, but it does save a lot of time and effort. Hope this helps :)
I am trying to make my 1st game in unity. I need to support different resolutions of android and iOS. The problem is when i place the background image for any one res ex. 1536x2048,It doesn't displays properly for 640x960. The screen size is varying, but sprites and bg sprite is not scaling as per res.
I am not clear how to acheive it. But, it must be a basic thing as there are so many games on android and all phones have different res. and dpi.
There should be some formula or we just need to set orthographic.size for this. I am using this :
// to calc size
Camera.main.orthographicSize = Screen.currentResolution.height / (2*70); //
Camera.main.orthographicSize = Screen.currentResolution.height / 2;
Debug.Log("Camera size :" + Camera.main.orthographicSize);
Debug.Log("Width : " + Screen.currentResolution.width + " height : " + Screen.currentResolution.height);
// this doesnt give me width and height as per resolution of screen for ex. for 1536x2048 -> i get, Width : 1366 height : 768
i found this as similar question
http://forum.unity3d.com/threads/orthographic-screen-size.113641/ but it didnt help, whereas problem is nearly same.
If somebody can share how to get correct screen resolution by code and how to set width of bg sprite and other sprite, it can solve the problem OR
if there is some setting which takes the default scene and scales automatically for various resolution. it will help.
Unity does not scale like that. Instead, we design assets to suit our needs. You are using a formula but i don't know what you expect from it.
here's some info: Orthographic size is height of view port. Taking your example, for height of 2048, camera size is : 2048/2/100=10.24. This will be maintained irrespective of device screen size. Only difference being it will be less detailed on smaller devices, kind of like a zoom out effect. Now for width,i'm not sure for portrait, but let's say 9:16 is the widest. So if you design the bg for this aspect ratio, the bg will be cropped on smaller devices, shown full on 9:16 devices. To design for this aspect ratio, your bg needs to be 9/16*10.24*100=576 px. (Again i'm not sure which aspect ratio is widest in portrait mode). Hope that helps
I am working on a game and i am moving the background images by 4px. For this i had used a normal mdpi screen of 480X800. i have designed the game using this resolution.
To support different resolution i have used for Horizontal speed width/480. so, for 240X400 resolution the background image will move with 2px speed half of the 480X800. Same done for the the vertical speeds. But for some reason in 240X400 it moves faster then it is expected. I want to design it in such a way that no other player gets advantage due to its resolution.
Note: I am designing this using only processing & android. Screen-orientation - LANDSCAPE
You should fix your scrolling speed in DP (e.g 10dp per second). Then you can read device DP using
DisplayMetrics metrics = getResources().getDisplayMetrics();
Log.d(LOG_TAG, "density: " + metrics.densityDpi);
int pixelSpeed = (int) (densitySpeed * (metrics.densityDpi / 160));
Then your pixel speed will be different, but physical distance per scroll will be same.
More details in link from #harvey_slash
i'm developing a game for android based on the SurfaceView class. Currently i'm stuck trying to optimize the view for different screen-sizes.
Problem 1: i have PNG-Files in my res folder and i draw them using Canvas.drawBitmap. After reading this article ( http://developer.android.com/guide/practices/screens_support.html ) i thought android resizes the bitmaps if the screen is bigger. Unfortunately i recognized no scaling (or any changes) when launching my app on a tablet vs. launching it on a phone. So how is it done? Should i come up with some fancy strategy to calculate the available space and draw my bitmaps using the source- and destination-Rectangle? Would be nice if someone has a best practice or some hints how to draw bitmaps on a canvas. I already read the pixel<->dip conversion topics but i have to say i don't know how to use that "solution" in my app. So any help appreciated...
Problem 2: I have 3 PNGs in my res folder. One ldpi, one mdpi and one hdpi. Ldpi image has 50px*50px, mdpi has 75px*75px and hdpi has 100px*100px. When i load the app in the emulator (800*480) it uses the 100*100 png. When i load the app on the Acer Iconia Tab it uses the 75*75 image. I thought hdpi is for big screens (=tab) and mdpi or ldpi would be used for the emulator screen. At least i thought android would use the hdpi-image also on the tab but i got surprised... Any explantation for this as well much appreciated
Sorry 4 long text, just trying to be clear...
cya
EffDee
For calculating how big your drawing should be, you can use Canvas.getDensity().
The DPI value of a screen depends on the amount of pixels and on the size of the screen. Tablets do have a high resolution, but most are quite large aswell. This leads to a lower DPI value. For more information have a look at http://developer.android.com/guide/practices/screens_support.html
The best practice is to put images into mdpi folder (pixel aspect 1) and then use density with all horizontal dimensions.
For example:
src.left = offsetX * density;
src.top = 0;
src.right = (offsetX + width - 1) * density;
src.bottom = height - 1;
dst.left = x * density;
dst.top = y;
dst.right = (x + width - 1) * density;
dst.bottom = height - 1;
canvas.drawBitmap(myImageStrip, src, dst, null);
For mdpi density is 1.0, ldpi density=0.75 and for hdpi density=1.5
You can obtain these and other values using
density = getResources().getDisplayMetrics().density;
There is another solution: you can put same image in all folders. The system will take proper one, so you dont need to multiply values with density. But in that case, you'll need 3 or more copies of same image.