How to align tile game objects in a grid - unity3d

How do I align tile game objects to my tilemap grid? I've the following settings:
tileSprite:
pixels per unit: 32
Grid (created tilemap gameobject):
Grid component:
cell size: 32, 32, 0
GridController script component:
tileSprite
In the GridController script:
public class GridController : MonoBehaviour {
public Sprite tileSprite;
// Use this for initialization
void Start () {
for (int x=0; x<5; x++) {
for (int y=0; y<5; y++) {
GameObject tile = new GameObject();
tile.transform.localPosition = new Vector3(x, y, 0);
tile.transform.localScale += new Vector3(32, 32, 1);
SpriteRenderer tile_sr = tile.AddComponent<SpriteRenderer>();
tile_sr.sprite = tileSprite;
}
}
}
}
I would like it to be placed side by side but it seems like they are only 1 pixel apart. Ie. I would like 1 unit to be equals to 32 pixels.
How do I do this? Thank you so much for your help!
I'm using Unity 2017.3.1f1.

Just by looking at your code:
tile.transform.localPosition = new Vector3(x, y, 0);
You used the loop's variables directly,
but you need to calculate the place where the tile is placed.
e.g.(might not be fully correct):
tile.transform.localPosition = new Vector3(x*32, y*32, 0);

Related

Scaling UI exactly as Gameobject

I have a gameobject in my scene. I want to show the dimension of the gameobject as shown here: So, I created a UI prefab. Now when I am trying to scale the UI (Which us a world UI canvas) prefab. It's not scaling properly! How can I do it? I am trying this now which is indeed not working. Help Needed!
public void setDimension()
{
GameObject g = Instantiate(dimUiPrefab);
BoxCollider b = activeFurniture.GetComponent<BoxCollider>();
Vector2 cameraViewPort =
Camera.main.WorldToViewportPoint(activeFurniture.transform.lossyScale);
g.transform.position = new Vector3(b.transform.position.x/2,b.transform.position.y +2f, b.transform.position.z);
g.GetComponent<RectTransform>().transform.localScale = cameraViewPort;
}
If you are using UGUI,
GameObject g = Instantiate(dimUiPrefab);
RectTransform rectTransform = g.GetComponent<RectTransform>();
// Set size
rectTransform.sizeDelta = new Vector2(width, height);
// Set position
rectTransform.position = new Vector3(posX, posY, posZ);

How do I convert a RectTransform (UI Panel) to screen coordinates?

I want to determine the screen coordinates of a RectTransform in Unity3D. How is this done, taking into consideration that the element may be anchored, or even scaled?
I am trying to use RectTransform.GetWorldCorners and then converting each Vector3 to screen coordinates, but the values are wrong.
public Rect GetScreenCoordinates(RectTransform uiElement)
{
var worldCorners = new Vector3[4];
uiElement.GetWorldCorners(worldCorners);
var result = new Rect(
worldCorners[0].x,
worldCorners[0].y,
worldCorners[2].x - worldCorners[0].x,
worldCorners[2].y - worldCorners[0].y);
for (int index = 0; index < 4; index++)
result[index] = Camera.main.WorldToScreenPoint(result[index]);
return result;
}
Although the help says that it returns coordinates in world space, they are actually in screen space (at least when the UI is not in world space). So the solution is simple:
public Rect GetScreenCoordinates(RectTransform uiElement)
{
var worldCorners = new Vector3[4];
uiElement.GetWorldCorners(worldCorners);
var result = new Rect(
worldCorners[0].x,
worldCorners[0].y,
worldCorners[2].x - worldCorners[0].x,
worldCorners[2].y - worldCorners[0].y);
return result;
}

Draw a Rect using GUI.DrawTexture on exactly gameobject's position Unity

I have to use the "GUI.DrawTexture(new Rect..." function to draw a rectangle on my screen(actually, it's a gradient GUI bar i got from https://www.assetstore.unity3d.com/en/#!/content/19972, but deep inside it's just a rectangle). I want to do it right beside a gameobject i have on my screen.
The problem is: It seems like rectangle's coordinates are not the same as a gameobjects coordinates(i have searched online and i guess it's true). I have tried the function below to convert a gameobject's position to a rectangle's coordinates but still no luck:
public Vector2 WorldToGuiPoint(Vector2 position)
{
var guiPosition = Camera.main.WorldToScreenPoint(position);
guiPosition.y = Screen.currentResolution.height - guiPosition.y;
return guiPosition;
}
My best strike was when i did this:
Vector3 gameObjectsPosition = Camera.main.WorldToScreenPoint(gameObject);
And then when i wanted to draw the rectangle i did:
GUI.DrawTexture(new Rect(gameObjectsPosition.x, Screen.height - gameObjectsPosition.y, Background.width * ScaleSize, Background.height * ScaleSize), Background);
But still, the Rect isn't on the exact gameObject's position. It's x is right but y don't and when i searched the internet, they said I only had to do the "Screen.height - gameObjectsPosition.y" when drawing the Rect. It didn't work for me, the y is still wrong.
What should i do to create a rectangle that's like, right beside a current gameobject on screen (like, if the gameobject's position is x = -401 and y = -80, i want it on y=-80 and x=-300)
You need to use Screen.height instead of
Screen.currentResolution.height
using UnityEngine;
using System.Collections;
public class GuiPosition : MonoBehaviour
{
public Vector2 WorldToGuiPoint(Vector3 GOposition)
{
var guiPosition = Camera.main.WorldToScreenPoint(GOposition);
// Y axis coordinate in screen is reversed relative to world Y coordinate
guiPosition.y = Screen.height - guiPosition.y;
return guiPosition;
}
void OnGUI()
{
var guiPosition = WorldToGuiPoint(gameObject.transform.position);
var rect = new Rect(guiPosition, new Vector2(200, 70));
GUI.Label(rect, "TEST");
}
}
I've just tested attaching that MonoBehaviour to a Cube GameObject and it works

How to center parent game object in the screen?

I am trying to make a Scrabble word game using a fixed camera, but I have a simple issue.
I add some boxes as game objects and the number of these boxes is the length of the word so if the word is "Fish" we will add 4 boxes dynamically. I did that successfully, but I can't center those boxes in the screen. I tried to add those game objects as children under another game object, then center the parent, but with no effect.
This is my code:
void Start () {
for (int i=0; i<word.Length; i++) {
GameObject LetterSpaceObj = Instantiate(Resources.Load ("LetterSpace", typeof(GameObject))) as GameObject;
LetterSpaceObj.transform.parent = gameObject.transform;
LetterSpaceObj.transform.localPosition = new Vector2(i*1.5f,0.0f);
LetterSpaceObj.name = "LetterSpace-"+count.ToString();
count++;
}
gameObject.transform.position = new Vector2 (0.0f, 0.0f);
}
This image shows you the idea:
I believe your code is working, but the problem is that your first letter is located at your parent object, and then every letter from then on is added to the right. That means that when you center the parent object what you are doing is putting the first letter in the center of the screen.
If you run the game and use the scene view to look at where the parent object is this can confirm this. What you can do instead is that rather than placing the parent at the center of the screen, offset it by an amount equal to the length of the word.
gameObject.transform.position = new Vector2 (-(word.Length / 2.0f) * 1.5f, 0.0f);
You might also want to consider changing some of those constants, such as the 1.5f into variables with names like LetterSize or basing it off the actual prefab so that way any future changes will work automatically.
This is the last solution after some edits to fix this issue.
GameObject LetterSpaceObjRow;
int count = 1;
string word = "Father";
float ObjectXPos;
float LocalScaleX;
void Start () {
for (int i=0; i<word.Length; i++) {
GameObject LetterSpaceObj = Instantiate(Resources.Load ("LetterSpace", typeof(GameObject))) as GameObject;
LocalScaleX = LetterSpaceObj.transform.localScale.x;
ObjectXPos = i*(LocalScaleX+(LocalScaleX/2));
LetterSpaceObj.transform.parent = gameObject.transform;
LetterSpaceObj.transform.localPosition = new Vector2(ObjectXPos,0.0f);
LetterSpaceObj.name = "LetterSpace-"+count.ToString();
count++;
}
gameObject.transform.position = new Vector2 (-(ObjectXPos/2.0f) , 0.0f);
}

Is there any way to make some rectangular areas of a mask to be transparent?

I am using UGUI to make a Novice guide to guide people to play my game.
And need the whole UI be mask, but some rectangular areas to be lighted.
How to do?
Create a new gameobject and add a image component to it. Create a image with transparent areas where you want your ui to be visible. Assign that image to the image component. Then add a mask component
Put your other gui elements inside this gameobject so that is could overlap and hide everything except transparent areas. Here is the picture of demo setup.
IMHO, what you want to achieve is not easy to be done perfectly in Unity. Here is my personal solution:
I put a black panel below every other GUI, so that it darkens my entire screen.
I put an empty game object called BrightRoot below the panel, so that everything under BrightRoot will float over and "brightened".
In my tutorial script, I add function to look for a UI game object by name and change its parent to the BrightRoot. In example:
// To brighten the object
GameObject button = GameObject.Find("PlayButton");
Tansform oldParent = button.transform.parent;
button.transform.SetParent(BrightRoot, true);
// To darken it again
button.transform.SetParent(oldParent, true);
The perfect solution would be to write a UI shader that darken any pixel outside some rectangles and brighten the inside. Then set that shader to all UI objects.
Editted:
This just another easy method, using UI Vertex effect. Just need to implement IsPointInsideClipRect, put this component to your UI objects, and set the rectangles list:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
[AddComponentMenu("UI/Effects/Clip")]
public class Clip : BaseVertexEffect
{
// We need list of rectangles here - can be an array of RectTransform
public RectTransform[] ClipRects;
public override void ModifyVertices(List<UIVertex> vertexList)
{
if (!IsActive())
{
return;
}
bool isClipped = true;
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
foreach (RectTransform rect in ClipRects)
{
if (IsPointInsideClipRect(rect, uiVertex.position))
{
isClipped = false;
break;
}
}
}
Color32 color = isClipped ? new Color32(0.5f, 0.5f, 0.5f, 0.5f) : new Color(1.0f, 1.0f, 1.0f, 1.0f);
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
uiVertex.color = color;
}
}
private static bool IsPointInsideClipRect(RectTransform rect, Vector3 position)
{
// ...
}
}