Unity game on Android phone cuts off edges - android

I am making a simple platformer in Unity. This is what it looks like in the editor:
You see, it is set to be in landscape in a 16 by 9 ratio. This is just fine.
Now, a few days ago, I updated my JDK to the newest version. Before, my game looked just like that on my Samsung S8. It was centered with black pillars to the left and right of it, since the screen isn't 16:9. This was great.
Now after updating, this is what it now looks like:
I am not sure why Unity does this.
Clearly, the game is now cut off on the top and lower ends so that it keeps its ratio. But this isn't what I want. I want my black pillars back to have everything be on screen and not partly be off screen.

I solved this problem with next steps:
PlayerSettings/Aspect Ratio Mode = Legasy(1.86)
PlayerSettings/Supported Aspect Ratios = 16:9 only
Canvas Scaler/UI Scale Mode = Scale With Screen Size
Canvas Scaler/Reference Resolution = any resolution for aspect ratio = 16:9 (1920; 1080)
Canvas Scaler/Match = 1 (for scale based on height)
All Cameras/Background = full black

Fix the resolution and aspect ratio issues directly: add a canvas scaler to the root canvas gameobject.
Canvas Scaler
Basically, force fixed width and let the height vary based on aspect ratio. Make sure all UI is properly anchored from the top or bottom to handle that variation.

Related

Android get dead area size around camera view

I am using FrameLayout or PreviewView to display the camera feed. The view is match_parent for the width and height (as I am unable to wrap_content for the height) and the scaleType is fitCenter to get the correct aspect ratio. Doing that as expected results in black area above and below the camera feed. How can I know the top and bottom dead area heights so that I can position other UI elements exactly in that area?
Thanks!!
So to answer my own. Since I was trying to achieve a fitCenter scale for the camera preview which for mobile phones is 4:3 what I was able to do is within a ConstraintLayout add a frame layout with a dimension ration of 4:3. That way the camera preview was contained exactly in that layout without any dead areas, and I was to position other UI elements above and below by constraining them to the top and bottom of the frame layout.
<FrameLayout
android:id="#+id/cameraView"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="W,4:3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:clipChildren="false" />
The "dead area"/black bars around the preview won't always be on the top and bottom, they might also be on the right and left. Their position depends on the size of the view (which I'm assuming you can get easily), and the aspect ratio of the preview, or even better, its size.
When setting up the Preview use case, if you're configuring its aspect ratio with setTargetAspectRatio(), then you already know the preview's aspect ratio.
Otherwise, you can still indirectly get it, one way I can think of is calling PreviewView.getBitmap() (after the preview has started), the returned Bitmap's size will be the size of the preview, you can use it directly, or you can use its aspect ratio bitmapWidth / bitmapHeight, which will represent the preview's aspect ratio.

how can I fit toggles/buttons into scrolled panel on different screens

I am trying to make a game in Unity3d 5. What I am trying to do right now is to make a scrollable panel filled with toggles/buttons. The panel should fit the frame on the screen and is masked so it hides under image frame. The concept is under this link:
https://www.dropbox.com/s/9zxwx33orz46q60/Screenshot2.png?dl=0
As you can see I managed to make toggles fill the panel, but not exactly as it should be. I us content size fitter on panel with both vertical and horizontal fitting set as preferred size. Also I put LayoutElement on panel and set min width and min height as 200. There is VerticalLAyoutGroup with only "Height" checked.
The panel is filled during runtime with quite simple prefab. It has preferred width also set at 200.
So it would not be much problem but when I buid it and run on Galaxy S5 it looks like this:
https://www.dropbox.com/s/9zrv6kyf4n0ueam/Screenshot1.png?dl=0
So question is: how can I make it to always fit the panel? I was changing a lot of different setting and what I once managed to do was that toggles/prefabs did fit the width of the panel but did not keep aspect ratio about 3 (they were flat and unreadable. On other instances the panels overlap partially or completely.
Please help.
EDIT
I managed to achieve this:
https://www.dropbox.com/s/6w80qnuekqyrx96/Screenshot3.png?dl=0
With settings as:
Panel:
* Content Fitter: horizontal - unconstrained, veertical - preferred size
* Child Force expand - both height and width checked
* Anchors and size stretched to fit scroll rect
Once again I struggle with something for few days, finally post a question here... and solve a problem in few minutes.
So the problem was in keeping aspect ration while resizing the prefab. When it was resized horizontally to fit panel it might be resized vertically too, but the position was not adjusted to compensate this change. So what was needed was to change the preferred height of the prefab on the basis of panel width (could not use toggle width, since it was not right yet (not resized yet)). In the code where I create togges for every toggle I had to put (3f is my aspect ratio):
float width = contentPanel.GetComponent<RectTransform> ().rect.width;
newPower.GetComponent<LayoutElement> ().preferredHeight = width / 3f;
Other settings are:
Panel uses vertical fit as preffered and horizontal as unconstricted
Toggle uses aspect ratio fitter set as Width controls height and aspect as 3

Setting actor size according to screen size in libgdx

I am developing a simple game using libgdx in android. I created an actor. I want to resize the actor according to the screen size. Can anyone please suggest me a simple tutorial to do the same
well it depends on how you set the viewport of your Stage.
lets say your stage viewport is set to stage.setViewport(16,10,false) within your resize()-method.
This way, your screen will always show the region from (0,0) in the bottom left to (16,10) in the top-right corner...
If you create an Actor with width=8 and height=5, it will always be half of the screen width and half of the screen height big.
Of course, the example above will usually distort your screen when it resizes... So you could use the setViewport(16,10,true); This way, you will keep the aspect ratio, but might need to resize or reposition some actors within the resize() method, e.g. when they are to be shown on the right edge of the screen.
The other way is by setting the viewport to the same coordinate systems as the pixels on the screen: stage.setViewport(width,height,false); (within the resize(...)-method). This way, one unit in the stage coordinate system equals one pixel on the screen.
When doing so, you will have to resize the actors in the resize() method after setting the viewport:
actor.setSize(0.2f*stage.getWidth(), 0.2f*stage.getWidth() * actor.getHeight()/actor.getWidth()):
Doing so will always make the actor be exactly one fifth of the screen width and have its height matched so it doesn't get distorted.
Hope this helps a bit...
If you are using the latest version (nightlies) you may have seen the Viewport class.
This class is what you are looking for. Lets say you have a 1600 * 900px monitor and you set your Viewport to 16 * 9, every unit in your Viewport will be 100px on your Screen.
This means, if you set your Stages Viewport to 16 * 9 an Actor with the size of 1 will be 100*100px big. If you are using a 800*450px monitor it will be 50*50px big.
There are also different Viewport types:
StretchViewport: Your Virtual Viewport gets stretched to fill the whole Screen. So if you have a 1600 * 900 monitor and a Virtual Viewport of 16/10, a 1x1 Actor will be 100px wide, but only 90px heigh. So the aspect ratio is not the same anymore.
FitViewport: If your Virtual Viewport has a different aspect ratio the Screen will be filled with black bars. So on a 1600*900 Screen with 16/10 virtual Viewport a collumn of 80px width on both sides of the Screen will be black ((virtualWidth / wirtualHeight) * realHeight = realWidth, physicalWidth - realWidth = blackWidth, to have the game in center blackWidth/2 on both sides), to keep aspect ratio.
There are also others, but those are the most important 2 imho. You can read more on the article i linked.
If you are not using the latest nightlies, you need to use camera. The constructor of the OrthographicCamera takes the viewport width and height. Those are the same as for the viewport. The difference is, that it is a "StretchViewport" automatically, so you have to manually set the glViewport like in this tutorial.
I hope i could help.

Android ImageView scaling

I am using google graph to get the desired graph for me and display it on a android device.
Now I want to display the received graph on a tablet screen but google graph api supports only 300,000 pixels as a max size (width x height) graph.
I am making a request for 500 x 600 px image and display it on a ImageView. I set the scaleType to fitXy and give the imageView width=fill_parrent height=850dpi because I want the image to almost fill the screen.
The problem is that the background of the image goes light gray or blurring after the ImageView scales the image and it looks bad on the white background of my application... If I make the ImageView wrap_content on width and height the graph has white background.
Is there any way to get the image displayed without changing it's background color?
Please note that I don't want to change the image's size.
I'd recommend to instead use width match_parent and then setAdjustViewBounds=true
If that doesn't fix it you probarbly have to change the image.
Unfortunately I had to change the image to a bigger one and the problem disappeared.

Handling different screen resolutions for background images in Android

My Android app (a text-based game) uses background images a lot in order to provide a better visual ambiance. For example, if the action in the game takes you into a tavern, then you get a background image of a tavern in the game. This is a vast improvement, graphically, over the boring black background that you would otherwise get.
It is also a problem, however, since android:background always stretches to the dimensions of the screen. The result is that the background images look very bad if the player switches between portrait and landscape mode. And to make matters worse, many devices have very different aspect ratios (e.g., 320x480 mdpi, 480x800 hdpi, and 480x852 hdpi) and even more variations are coming.
How do others solve this problem? Having individual images for the main resolutions/orientations is not an option for me, as this would result in the apk growing too large.
The first step is to get the screen height and width of the device itself, then stretch/shrink or pad your bitmap as needed. This SO answer has source that should help, copied below. Props to Josef for original answer.
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Here's generic source on getting the orientation.
int orientation = display.getOrientation();
or some more involved source from here (a little messy but looks correct).
public int getscrOrientation()
{
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
// Sometimes you may get undefined orientation Value is 0
// simple logic solves the problem compare the screen
// X,Y Co-ordinates and determine the Orientation in such cases
if(orientation==Configuration.ORIENTATION_UNDEFINED){
Configuration config = getResources().getConfiguration();
orientation = config.orientation;
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(getOrient.getWidth()==getOrient.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(getOrient.getWidth() < getOrient.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
return orientation; // return value 1 is portrait and 2 is Landscape Mode
}
I would suggest you get the width and height of your current view. Right now I am not sure what functions will give you these values but I am sure it is possible. With that you can then calculate an aspect ratio. I'd make the images something like 1000x1000 and just show a certain part of the image, so that the aspect ratio will not be wrong.
I have the same problem with the camera. So my solution was to pick one of the two values, width or height, as fixed, and calculate the correct other value according to the aspect ratio. I'm not sure if there are functions already to just show a part of the image, but I am sure you could write something to copy just a part of the image and show that part.
The drawback is of course that you will be showing just a part of the background. Since the general aspect ratio of the phones is however somewhere between 1:1.3 and 1:1.8 I guess it wouldn't be a too big problem. I for one would rather see the part of an image in the correct way, than looking at an ugly stretched image.
Maybe you could create your background images as NinePatch images so that you are in better control of how it stretches?
Otherwise, you can just prevent your images from stretching (or at least keep the correct aspect ratio) by setting the scaleType attribute e.g. android:scaleType="center".

Categories

Resources