I am trying to make a simple tile-based turn based strategy-game.
So I made a test-map with different things like trees, rivers etc.
My next step is to make classes that I call Unit, that holds the X-Y position and other data. Since Unit will be created/destroyed dynamically during the game (in a List>), I also want PictureBox containing the Unit tile-icon to be created/destroyed as needed.
I want to be able to click on a PictureBox, the box will make a mouse event, the event will check which class is connected to the PictureBoxand perform action as needed.
Dynamically Create and Destroy PictureBox in C#? Or should I make a grid of PictureBox?
I would go a different route. Create one single PictureBox and draw everything in it's Paint event. Do a nested loop through your map's x and y coords for the visible tiles and draw out those tiles using Graphics.Draw commands. After you paint the background tiles you can loop though the unit list and paint those right on top. You can do a simple hit-test on mouse down to see what is being clicked on.
This will be less resource intensive and also allow you to do better animations and graphics later (think sprites crossing tile boundaries or tiles larger than a single physical tile).
Related
Overview: I am making a 2D Tower Defense game with using Tilemaps as the environment and sprites as the towers and enemies. The mouse needs
Problem: I want to trigger different events/methods depending on which tile or sprite the mouse is hovering or clicking on.
Example - Hovering over buildable tiles shows a highlighted tile, but the highlight disappears when the mouse is over a "dead" un-buildable tile.
After 10+ hours of research, I think I need to use Raycasts, 2D Colliders, and Layers to detect when the mouse hovers over or clicks on a tile/object, but I don't know how to trigger different events/methods depending on which specific layer or tag the mouse is interacting with.
Question: How do I detect and access a tile or gameobject with a mouse hover/click? and is there a way to trigger different methods depending on tags/layers I assign to the things I want to detect on hover/click?
First of all you don't need raycasts or colliders to detect mouse events. There are many ways to do this, but you can create eventListener for use on multiple objects. Also as a simple solution you can consider using scripts(includes UnityEventListeners) attached to the objects you want to control.
I'm making what is essentially a board game within Unity 2D. The player will be able to move their pieces along a grid (see below). The larger circular sprites are the pieces, which the player can click on, then click a gridPoint (the small squares) to move to it.
I've created the grid by using empty gameobjects (I've rendered a sprite on them for visual help) at each intersection. These are the points where players can move between. The distance between the points varies, though the horizontal distance is always 1.
The full functionality would be...
A player clicks on a piece,
A preview area of where the piece can move to is shown.
Player clicks on a valid grid point where the piece should move to.
Grid piece moves to new point.
First of all, have I created this in the right way? I need the grid to be accurate, as it will be populated with an accurate sky map. Currently this grid is accurate.
Assuming this is the right way of doing it, how do I, when a piece is selected, work out which grid points are within range? Say a piece can move 4 spaces, then any space 4 grid points away from origin (horizontally, vertically and diagonally) can be moved to. I'd also need to count how many spaces the piece has moved.
I also need to make the piece travel from it's original position, to the new grid point, via grid points using the shortest route.
Any help is appreciated.
OK, there are many solution for this, but let's keep it simple!!
simple overview of your solution step!!
If your grid is fixes size(i.e fix height and width unity length), then put custom placeholder (empty gameobject)in intersection point
detect the swipe detection(assuming you working with this mechanism) from current tapping piece to direction.
using any tween library(i suggest DoTween library from unity asset store, it's free and absolutely amazing.)move your piece to that placeholder.
Now bit more in depth Understanding!!
please refer the below reference.
initial condition of any type of grid
after creating the grid, you can put empty gameobject as an placeholder in between grid(you can make it invisible- i.e make it alpha 0 of image property!)
placeholder in between gap of grid
you can make you piece(player) child of any of these placeholder.
you will detect the swipe or even tap mechanism and check weather in what ever direction you swapping or in which invisible placeholder you tapping, has any child??
if yes, that means that placeholder is already occupied with other piece(player). so no logic to move your current piece. so ignore the swipe.
if no, that means placeholder is empty, so its valid move.
using any tween library, from current placeholder position to desired placeholder, move your piece(player).
after reaching to desired placeholder, make that piece the child of that desired placeholder(using setparent(desiredplaceholder.gameobject.transform.position) kinda code)
and you done!!
hope you find this helpful!!
Does any know or can possibly point me to some instructions or a github repository on how I can create a script where I have an object and in GoogleVr (Cardboard) if I was to gaze over an object, a tooltip would appear?
If anyone is familiar, in the Cardboard Demos under Under Arctic Journey > Learn, when you click on the fox, a tooltip appears to showcase that item along with like a brief description on it. I want to have something similar (maybe even the same thing) except just having a gaze over will automatically show it. Is this possible?
I want to have this done on multiple objects in my project so I want it created so I can easily substitute out text and whatnot.
Have a script with a reference to a World Space Canvas (WSC). The WSC will be your tooltip and be activated when you hover over the object and disabled when you don't.
You can set images and texts of the WSC through the inspector or through code if you make a reference to them.
The script should also always have its rotation set to face the player.
You can use the SetActive(bool) method to show or hide the WSC.
The UI system makes it easy to create UI that is positioned in the world among other 2D or 3D objects in the Scene.
Start by creating a UI element (such as an Image) if you don’t already have one in your scene by using GameObject > UI > Image. This will also create a Canvas for you.
Set the Canvas to World Space
Select your Canvas and change the Render Mode to World Space.
Now your Canvas is already positioned in the World and can be seen by all cameras if they are pointed at it, but it is probably huge compared to other objects in your Scene. We’ll get back to that.
https://docs.unity3d.com/Manual/HOWTO-UIWorldSpace.html
I'm currently creating a large map, that consists of a lot of rectangles (33,844), that all have a unique name (label), which I'm drawing on top of them using a SpriteFont.
Drawing all of the rectangles takes no performance hit at all. But, as soon as I try to write all of their labels with DrawString(), my performance goes into the dumps.
In my head, I would like to draw all my rectangles and text to one texture all at once, and only have to keep redrawing that entire finished texture. My issue is, this is an enormous map, and some of the coordinates for the rectangles are very high (example: one slot's x is 14869 and y is 23622), and they're far bigger than a Texture2D allows.
Since this is a map, I really only need to draw the entire thing once, and then allow the user to scroll/move around it. There's no need for me to continually redraw all of the individual rectangles and their labels.
Does anyone have experience with this type of situation?
Try to only render the labels that you can see on the screen and if you can zoom back far enough, just don't render them.
Textrendering is expensive, since it is basically creating a rectangle to draw on for every character in the font and then applying the same RGBA texture to it. So depending on the number of characters you write, the number of rectangles increases. This means four new vertices per character.
Depending on what you write you could simply create a texture with the text already on it and render that, but it won't be very dynamic.
EDIT: I need to clarify something.
There's no need for me to continually redraw all of the individual rectangles and their labels.
This is wrong. You have to draw the whole thing every frame. Sure, it doesn't increase memorywise, but it still is a lot to render and you will need to render it every frame.
But as I said: Try to only render the labels and the rectangles that collide with the screenboundaries, then you should be fine.
There are two ways to solve your problem.
You can either render your map to a RenderTarget(2D/3D) or you can cull the rectangles/text that are offscreen. However, I am not 100% sure that RenderTargets can go as large as you would need, but you could always segment your map into multiple smaller RenderTargets.
From more information on RenderTargets, you might want to check out RB Whitaker's article on them, http://rbwhitaker.wikidot.com/render-to-texture
Culling, in case you are familiar with the term when used in this context, means to only render what is visible to the end-user. There are various ways that culling can be implemented. This does however require you to have already implemented a camera (or some type of view region) and you perform a basic axis-aligned bounding box collision (AABB collision, which MonoGame's Rectangle supports out of the box) of the rectangles against the camera's viewport and only render it if there is a collision.
A basic implementation of culling would look something like this:
Rectangle myRect = new Rectangle(100, 100, 48, 32);
public void DrawMapItem(SpriteBatch batch, Rectangle viewRegion)
{
if (viewRegion.Contains(myRect))
{
//Render your object here with the SpriteBatch
}
}
Where 'viewRegion' is the area of you world that the camera/end-user can actually see.
You can also combine the two methods, and render the map to multiple render targets, and then cull the render targets.
Hope this helps!
I am creating a game in which the barriers I'm creating that are polygons deteriorate based on where they were hit. I am wondering how I can dynamically add points to the polygon as it normally takes an array and I don't want to have to set every point in the array but rather change them when hit. Can you use lists to draw polygons is basically what I'm getting at?
e.Graphics.DrawPolygon(Pens.White, BarrierArray1);