So I'm doing this little game for university and I've encountered a problem with the resizing of the sprites. My game's like a graphic adventure (monkey island, grim fandango and stuff) and it has an inventory where items can be saved. The problem is, although the world object sprites are good and have different sizes, I want their sprites to be resized when and save them in the inventory so they can fit.
I thought this were done using the Bounds class, but I have some issues with it. Also: the tutorial I was following did something that in it's time might work, but now it gives me a compile error. Showing below my function to save an item (and resize its sprite in the process):
void SaveInventoryItem()
{
string name = transform.parent.gameObject.name;
GameObject temporaryObject = Instantiate(inventoryItemPrefab);
temporaryObject.name = name;
temporaryObject.gameObject.GetComponent<SpriteRenderer>().sprite = transform.parent.GetComponent<SpriteRenderer>().sprite;
temporaryObject.transform.parent = inventoryCanvas.transform;
temporaryObject.transform.position = Vector3.forward * -1;
temporaryObject.gameObject.GetComponentInChildren<InteractZone>().interactText = "Usar " + name;
Bounds bounds = temporaryObject.gameObject.GetComponent<SpriteRenderer>().sprite.bounds.size ;
float factor = General.inventoryItemSize / bounds.size.y;
}
The error says cannot convert from UnityEngine.Vector3 to UnityEngine.Bounds
If someone knows a way to solve this error or another way to resize sprites in a default size, please let me know.
Look at #Erik Overflows comment. Use a canvas class in your inventory system, which will contain a bunch of images with properly set sizes. Then you can just assign the sprite to the image, and it should size automatically.
As Erik said in his comment, you can just set the image for the UI canvas element in the inventory to the sprite, it will automatically fit the sprite to the ui element. Then all you need to do is use the system figbar suggested to assign sprites to your images as inventory items are added or removed.
If you know the size of the sprite, under the Inspector, change the Pixels Per Unit to that size.
You could play around with the numbers until it fills, or you can change your Sprite Mode to multiple, click the Sprite Editor button, and go to slice. Select grid by cell size type and it may populate the pixel size, but you can play with it and figure it out if it doesn't.
Related
guys! We are developing a 2D game for desktop and mobile. It is grid-based although we decided not to use tilemaps and, instead, create our own grid by code, because we need to program different actions and interactions for each tile. The game UI is on a canvas and that part resizes as we expected. Also, everything already works quite well "functionality-wise" on both, mobile and desktop. The problem is that, as we made the main grid and objects as sprites, it works great on any 16:9 screen, but some of the screen space gets cut when it runs on any wider screen.
How can we resize the whole sprite scene depending on screen size? I guess it has more to do with the camera than with the actual objects but we don´t have a clear clue. We already looked into "pixel-perfect camera" and, although we haven´t dug too deeply into it, it looks like it´s aimed more towards preserving artwork at full resolution and not so much at what we need.
This one is from the PC where we are developing the game and where it looks as it should:
And this one is from a PC with a wider screen (16:10) where the scene gets cropped from the sides (In the previous picture I marked in orange/yellow the columns that are lost in this one)
I guess there should be a way to stretch all sprites to fit the screen, but I think the best way to go would be to get empty horizontal or vertical bars, on top and bottom or to the sides, in order to preserve the exact proportions, and that would be good enough. But how to do it?
Thanks in advance.
Solved! Starting with the great ideas ephb gave me, I finally decided to get a reference percentage between the screen width and height. So, for 1920x1080, which is the resolution I know the game looks correct in, I did a rule of three and got that 1080 is 56.25% of the screen width, and, that in that case, the camera size should be 5.
Knowing those two elements, now I can check the height proportion for the user´s device and, using another rule of three, calculate the correct camera size, like this:
Camera cam;
void Awake()
{
cam = Camera.main;
cam.orthographicSize = GetHeightProportion() * 5 / 56.25f; //1920x1080 reference ---
}
float GetHeightProportion()
{
return ((float)Screen.height * 100) / (float)Screen.width;
}
I think you are looking to resize fore any aspect ration not screen resolution. You use the aspect ratio dropdown of the game window to see how it looks without running it on different computers.
The default setting is that the vertical field of view of your camera stays the same. Since the 16:10 display is taller this results in your image appearing zoomed with the sides being cut off.
Since you are using sprites and you basically have to recreate what the canvas scaler does but in world space.
You could move your camera, change its FOV if it a perspective camera, change its size if it is an orthographic camera or scale your scene. I will describe the first steps.
Get Screen width and height and calculate the aspect ratio.
Compare against your target aspect ratio. (I assume it is 16/9)
Use this multiplier to scale your scene / move your camera / change it's field of view
I'm learning Unity but when I create a map with Tile Map and look at the map in the game view it has some lines
It's tilemap aliasing, usually goes away when you try a standard resolution in the gameview, which you already have but try 1x scale, also try something like 720p, 1080p or an actual monitor resolution and make sure the game view is set to "Fixed resolution". If the aliasing disappears, you will know it only appears at weird resolutions and you won't have to worry about it.
If it doesn't, theses are some of the things you can try:
First make sure that the filtering mode for your tilemap sprite/s is set to point.
Add a new material to the tilemap gameobject and set it's shader to Sprites/Default, then check the "pixel snap" box.
Try the pixel perfect camera https://blog.unity.com/technology/pixel-perfect-2d
Set the grid cell gap on x and y axis to a very small negative number, like -0.0001
If all of these doesn't work, I think you will have to use the sprite packer to pack your tilemap into a sprite atlas and make it so that there are gaps between each tile. If you wanna know why that is: https://forum.unity.com/threads/tilemap-has-tearing-between-tiles-even-with-pixel-snap.499154/#post-3292216
I'm building a game in Unity for Android in portrait mode. I have a Canvas as big as the display and the render mode is set to Screen Space - Camera. I also have a RawImage (child of the Canvas) colored in blue that I resized and repositioned in code to fit my needs. The problem came when I had to get the corners of the RawImage using the GetWorldCorners property of RectTransform. There was something wrong with the results and I finally found the problem, which is that even though the RawImage was resized and repositioned, the corners of the RawImage were the same as the corners of the Canvas. Look at the image below:
I selected the RawImage from the Hierarchy and currently, the corners of the RawImage are the ones pointed by the RED Arrows. But I need the corners to be the ones pointed by the GREEN Arrows.
Here is a simplified version of the resizing and repositioning function:
private void applyResize()
{
//The values of the Vector2s are the output, in the real function there is a formula that isn't relevant to this question
myRawImage.GetComponent<RectTransform>().sizeDelta = new Vector2(864, 864);
myRawImage.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -1178);
}
I am sure that the problem comes from the 2 lines of code in the above function since you can see in the image that even the Pivot has not changed. I need to find a way to adapt the corners to the repositioned and resized RawImage, not before it was modified. I can provide any additional information if needed. I will greatly appreciate any amount of help. Thank you in advance!
UPDATE 1:
The values of the offset position and the side are NOT fixed, they are calculated based on some of my parameters and based on the display size. The problem is not the values, they are right. As you can see, VISUALLY the RawImage has the right size(864x864) and it is in the right position on the Y axis (-1178). In the Inspector tab you can see that the RawImage is initially placed at the top and center side of the display. I modify it's position and size at Runtime. The problem is even though visually the RawImage is right, the anchors and pivot still remain the same as the Original, before calling the function. I need the corners of the RawImage to change based on the modified size and position. The goal here is to get the right corners of the RawImage because later on I need to draw a line containd within the RawImage so I need the right coordinates. I don't know any other way to approach this.
I googled this for quite some time but only found responses on how to do this the other way, finding coordinates based on color.
This has been probably answered somewhere but it is buried below all of the other responses.
--
So, as a simple way of making a level editor for my game, i have the game load a texture, and then loop through the pixels it. Different colors in the texture equate to different objects.
Everything else is working fine, but i am unable to find how to get the color of the pixel in the given co-ordinates.
Basically what you need to do is to store you texture color informations into a one dimensional array using the Texture2D.GetData Method
var colorTable = new Color[texture.Width*texture.Height];
texture.GetData(colorTable);
then to access a specific pixel (let say X,Y) all what you need to do is to get its corresponding color from the array like so
var pixelColor=colorTable[texture.Width * Y + X];
I'm quite new to the world of 2D-Engines. I figured out how to load images and display those as sprites and stuff, but theres one question that bugs me.
For instance, when a "rocket" hits an object it will deal damage to it and leave a crater behind. I'd like to have the crater shown on that object. That would require "skipping" some of the pixels of that image when rendering, doesn't it?
My question is, how would you do such a thing? What data strcture would you use to save this? How to display a "broken" sprite?
Create a sprite sheet.
This will contain all the spirites your object, in this case the rocket. Some of these images would be of the rocket smashing into many pieces, fire etc...
Then when your object hits, you play the collision animation. Your method would technically work, but it's overkill. Using a sprite sheet is simple, rather than drawing a massive image, you just draw a portion of the sheet, and to play the animation increment in the X an Y axis of the sheet. This naturally requires the sheet to be layed out even, but it's not too much work.
For some situations, you can simply draw another sprite on top of the original sprite. Alternatively, you can switch between different sprites depending on the state of the object.
I see you have tagged this with XNA, so assume that is your API (though this answer could well be applied to any OpenGL/D3d approach with appropriate calls). If you want to do this in an elegant fashion, I suggest using a temporary RenderState. You would switch to the new RenderState and draw your original background texture, then draw crater sprites over the top (you can modify the AlphaSourceBlend and AlphaDestinationBlend properties of the RenderState to create the subtractive effect you are looking for).
Once you have finished drawing, you can retrieve the RenderState as a texture easily using the GetTexture() function.
Keep in mind that if you are changing the blend modes, your SpriteBatch should be performing in the "immediate" mode (I forget the XNA term, but the one where it doesn't do ordering of sprites for efficiency) else it will be reset unexpectedly.
View this: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Adding_craters.php
Slow, but probably fast enough.
public static void Fill(this Texture2D t, Func<int, int, Color> perPixel)
{
var data = new Color[t.Height * t.Width];
for (int y = 0; y < t.Height; y++)
for (int x = 0; x < t.Width; x++)
{
data[x + (y * t.Width)] = perPixel(x, y);
}
t.SetData(data);
}
I was working on something like this on a mobile Java game, a worms/scorched earth clone (actually based on GunBound).
You don't "skip" the pixels in order to leave a crater. You change the pixels in your planet's bitmap, so the crater is now a permanent part of your planet. I assume you know all about bitmaps, blitting transparent, and hit testing.
To create a crater I used a circle-fill algorithm and filled the "explosion area" with the background or transparent color.
So when doing hit-testing you have to do it twice. A bounding-box hit test for speed, then a per-pixel hit test when then bounding boxes overlap.