I instantiate a Board GameObject using this code:
mainBoard.transform.position = camera.ViewportToWorldPoint(new Vector3(0f, 0f, camera.nearClipPlane));
Then I try to fill this board by instantiating Tiles GameObjects with loop:
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Vector3 tempPosition = camera.ViewportToWorldPoint(new Vector3(x, y, camera.nearClipPlane));
GameObject backgroundTile = Instantiate(tilePrefab, tempPosition, Quaternion.identity) as GameObject;
backgroundTile.transform.SetParent(this.transform);
backgroundTile.name = "( " + x + "," + y + ")";
allTiles[x, y] = backgroundTile;
}
}
But the tiles are placed on wrong place. They should be placed one next to each other at the bottom left of the screen but only the first Tile is at correct position.
How can I get all tiles correctly placed on the board?
EDIT
Here is the prefab I am instantiating:
This is what I get:
and this is what I am trying to get:
Thank you.
I did not fully look at your code but try this;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Vector3 tempPosition = camera.ViewportToWorldPoint(new Vector3(x, y, camera.nearClipPlane));
GameObject backgroundTile = Instantiate(tilePrefab, tempPosition, Quaternion.identity,this.transform) as GameObject;
backgroundTile.name = "( " + x + "," + y + ")";
allTiles[x, y] = backgroundTile;
}
}
give it a try, sometimes UI makes stupid things if you set parent after you instantiate. So it is better to setparent when you instantiate like this;
GameObject backgroundTile = Instantiate(tilePrefab, tempPosition, Quaternion.identity,this.transform) as GameObject;
If it is for building UI element, I would use the grid component or the vertical/horizontal layout depending on what you want to do. Just set the instantiated element to the grid parent that will take care of the layout
Related
I'm trying to make a chess game in Augmented Reality. I wrote a script which places chessboard on the Plane in AR. Then I created mesh with 64 squares which match chessboard tiles. I have a problem placing mesh to match my chessboard(screenshots). I think I should rotate mesh by Y axis, but I wasn't able to do that.
placing chessboard:
GameObject placedObject = Instantiate(objectToPlace, placementPose.position, placementPose.rotation * Quaternion.Euler(-90f, 0f, 0f));
script that creates and places mesh:
private float yAdjust = 0F;
private Vector3 boardCenter = GameObject.Find("Interaction").GetComponent<TapToPlaceObject>().placementPose.position;
private void GenerateSquares(float squareSize)
{
adjust = new Vector3(-4 * squareSize, 0, -4 * squareSize) + boardCenter;
squares = new GameObject[8,8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
squares[i, j] = CreateSquare(squareSize,i,j);
}
}
}
private GameObject CreateSquare(float squareSize, int i, int j)
{
GameObject square = new GameObject(string.Format("{0},{1}", i, j));
square.transform.parent = transform;
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(i * squareSize, yAdjust, j * squareSize) + adjust;
vertices[1] = new Vector3(i * squareSize, yAdjust, (j + 1) * squareSize) + adjust;
vertices[2] = new Vector3((i + 1) * squareSize, yAdjust, j * squareSize) + adjust;
vertices[3] = new Vector3((i + 1) * squareSize, yAdjust, (j + 1) * squareSize) + adjust;
int[] triangles = new int[] { 0, 1, 2, 1, 3, 2 };
Mesh mesh = new Mesh();
square.AddComponent<MeshFilter>().mesh = mesh;
square.AddComponent<MeshRenderer>().material = squareMaterial;
//square.transform.rotation = Quaternion.Euler(new Vector3(0, boardRotation.eulerAngles.y, 0));
//square.transform.rotation = boardRotation;
mesh.vertices = vertices;
mesh.triangles = triangles;
square.AddComponent<BoxCollider>();
return square;
}
screenshot of my problem
You could probably try and just add another
* Quaternion.Euler(0f, 45f, 0f)
In general though for your squares there is Transform.SetParent which allows you to pass the optional parameter worldPositionStays as false which is probably what you would want to do. By setting
transform.parent = parent
equals calling
transform.SetParent(parent);
which equals calling
transform.SetParent(parent, true);
so the objects keep their original world space orientation and position.
However, I would actually rather recommend you already create that board once in edit mode, make the entire board a prefab and now when you spawn the board you only need to take care of placing and rotating one single object and all children will already be their correctly placed and rotated within the board.
I've been having problems with the Sprite.Create function lately. I'm using C# to program a box with a border that can stretch and change size, but I didn't want the white border to stretch. I tried to create my own texture, and when I printed out the values of some pixels, it seemed like that worked fine. But when I used the texture for Sprite.Create, it didn't work and just showed a gray square. Here is the code:
`void updateSprite(){
transform.localScale = new Vector3 (scale.x, scale.y, 0);
SpriteRenderer rend = GetComponent<SpriteRenderer>();
Texture2D tex = new Texture2D ((int)(100*scale.x), (int)(100*scale.y));
for (int y = 0; y < tex.height; y++) {
for(int x = 0; x < tex.width; x++){
if(y < 2 || x < 2 || y >= tex.height-2 || x >= tex.width-2){
tex.SetPixel(x, y, Color.white);
}else{
tex.SetPixel(x, y, Color.black);
}
}
}
print (tex.GetPixel (0, 0) + "," + tex.GetPixel(3, 3) + "," + tex.GetPixel(tex.width-1, tex.height-1));
Sprite spr = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f));
rend.sprite = spr;
}`
The scale variable is a Vector2 that I can change before drawing the sprite so it doesn't stretch.
Thanks for your help. I'm using Unity 5, if that has anything to do with it.
I figured it out. It was actually really simple. First I had to add a "dummy" texture to the SpriteRenderer in the editor. I also had to add tex.Apply() to apply the changes.
I'm trying to write an algorithm that will split an arbitrary quad into smaller quads that all have the same x, y, and z scales (so, cubes). Right now I have code that splits quads into scaled down versions of themselves, but I'd like the ratio to be 1:1:1. How would I modify the code below to do that?
for (int x=0; x < 2; x++) {
for (int y=0; y < 2; y++) {
for (int z=0; z < 2; z++) {
GameObject newCube = Instantiate(gameObject);
newCube.transform.localScale = new Vector3(
newCube.transform.localScale.x/2,
newCube.transform.localScale.y/2,
newCube.transform.localScale.z/2
);
newCube.transform.position = new Vector3(
newCube.transform.position.x + ((x-0.5f) * newCube.transform.localScale.x),
newCube.transform.position.y + ((y-0.5f) * newCube.transform.localScale.y),
newCube.transform.position.z + ((z-0.5f) * newCube.transform.localScale.z)
);
}
}
Destroy(gameObject);
If I understood you correctly, you want to make squares from a rectangle (actually the 3D equivalent of those, but whatever).
So your inner squares must have a side, at most, half of the SMALLER side of the rectangle. And, since they are squares, all the sides must have the same size. So, you must find which is the smaller side of x, y and z, and create your cubes with all sides set to half of that value.
Putting that into your code:
for (int x=0; x < 2; x++) {
for (int y=0; y < 2; y++) {
for (int z=0; z < 2; z++) {
GameObject newCube = Instantiate(gameObject);
var cubeSize = Math.Min(oldQuad.x, Math.Min(oldQuad.y, oldQuad.z)) / 2;
newCube.transform.localScale = new Vector3(
cubeSize,
cubeSize,
cubeSize
);
newCube.transform.position = new Vector3(
newCube.transform.position.x + ((x-0.5f) * newCube.transform.localScale.x),
newCube.transform.position.y + ((y-0.5f) * newCube.transform.localScale.y),
newCube.transform.position.z + ((z-0.5f) * newCube.transform.localScale.z)
);
}
}
Destroy(gameObject);
Since you told nothing about how you want to position them, I keep that part the same.
I manually (from editor) create empty object with boxes. It rotate around center.
But if I create same object with boxes from script. It rotate around unknown point for me.
I found the cause. It happening because boxes has scale (0.1, 0.2, 0.1). If I set (1,1,1) - it work.
How to fix it? I want small boxes.
var wall = new GameObject();
//wall.transform.parent = room.transform;
wall.transform.name = "Wall";
wall.transform.position = new Vector3(0,0,0);
for (int x = -3; x < width-3; x++)
{
for (int y = -3; y < height-3; y++)
{
var plate = Instantiate(SimplePlate);
var pos = plate.transform.position;
float posZ = pos.z - (x * plate.transform.lossyScale.z);
float posY = pos.y + (y * plate.transform.lossyScale.y);
var newPos = new Vector3(0, posY, posZ);
plate.transform.position = newPos;
plate.transform.parent = wall.transform;
plate.name = "Plate " + x;
}
}
You could create another empty GameObject and stuff your box inside. Then rotate the parent you just created?
Also, how can you rotate an object with a scale of (0,0,0). Did you mean (1,1,1)?
I've been trying to combine a couple of riemers tutorials to make a terrain that is textured and lit. I'm almost there but I can't get the application of the texture right. I believe the problem is in SetUpVertices() with the setting of the texture coordinates. I know currently the code reads that they're all set to (0, 0) and I need to have it so that they are set to the corners of the texture but I can't seem to get the code right. Anybody out there able to assist?
private void SetUpVertices()
{
vertices = new VertexPositionNormalTexture[terrainWidth * terrainHeight];
for (int x = 0; x < terrainWidth; x++)
{
for (int y = 0; y < terrainHeight; y++)
{
vertices[x + y * terrainWidth].Position = new Vector3(x, -y, heightData[x, y]);
vertices[x + y * terrainWidth].TextureCoordinate.X = 0;
vertices[x + y * terrainWidth].TextureCoordinate.Y = 0;
}
}
}
I've added the full code of Game1.cs to this pastie http://pastebin.com/REd8QDZA
You can stretch the texture across the surface by interpolating from 0 to 1:
vertices[x + y * terrainWidth].TextureCoordinate.X = x / (terrainWidth - 1.0);
vertices[x + y * terrainWidth].TextureCoordinate.Y = y / (terrainHeight - 1.0);