Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on a Breakout clone and I decide to use files as method to load level layouts. The file is something like this:

N,N,N,N,N

N,N,N

N,N,N

Only indicates what type of brick I'll instantiate, the initial positions to set this are in the WallBuilder.cs shown next. But I got a problem when I use my script, because the bricks doesn't appear in the rights position, they look moved and translated, and in the start moment, they move, but I don't understand why, I leave you a screenshot of the game when starts:

Level Start

And the configuration of the prefabs of my brick:

Prefabs Brick Configuration

Also, I leave you the WallBuilder.cs, which constructs the level based on the size of the screen and puts each brick next to each other:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;

public class WallBuilder : MonoBehaviour
{
    public float xOffset = 0.31f;
    public float yOffset = 0.15f;
    public GameObject level;
    private List<List<string>> filedata;
    private Dictionary<string, string> prefabMap;

    // Use this for initialization 24
    void Awake ()
    {
        readFile("./Assets/" + Application.loadedLevelName + ".lyt");
        initPrefabMap();
        placeBricks();
    }

    // Update is called once per frame
    void Update ()
    {

    }

    private void initPrefabMap()
    {
        prefabMap = new Dictionary<string, string>();
        prefabMap.Add("F","FastBallsBrick");
        prefabMap.Add("I", "InverseBrick");
        prefabMap.Add("M", "MultipleBallsBrick");
        prefabMap.Add("U", "NonDestroyableBrick");
        prefabMap.Add("N", "NormalBrickPrefab");
        prefabMap.Add("S", "SlowBallsBrick");
        prefabMap.Add("X", "XResBrickPrefab");
        prefabMap.Add("XX", "XXResBrickPrefab");
    }

    private void readFile(string filename)
    {
        TextAsset sr = Resources.Load("Level2") as TextAsset;
        filedata = sr.text.Split('\n').Select(s=>s.Split(',').ToList()).ToList();
    }

    private void placeBricks()
    {
        Camera mainCamera = tk2dCamera.Instance.ScreenCamera;

        float halfWidth = mainCamera.aspect * (mainCamera.orthographicSize/100);
        float tempYOffset = (mainCamera.orthographicSize/100) - yOffset - 0.5f;
        foreach (var data in filedata)
        {
            float tempXOffset = -halfWidth + xOffset;
            foreach (var item in data)
            {
                if (tempXOffset < halfWidth - xOffset)
                {
                    instantiateBrick(item,tempXOffset, tempYOffset);
                }
                else
                {
                    break;
                }
                tempXOffset += xOffset;
            }
            tempYOffset -= yOffset;
        }
    }

    private void instantiateBrick(string type,float xOffset,float yOffset)
    {
        string item = type.Trim ();
        if (prefabMap.ContainsKey (item)) {
            GameObject.Instantiate (Resources.Load (prefabMap [item]), new Vector3 (xOffset, yOffset, 0), Quaternion.identity);
        }
    }
}

Also, I leave you the collision exit method of the brick, just in case:

   void OnCollisionExit2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "Player") {
            brick.addHits ();
            if (brick.getCurrentHits () == brick.getNeededHits ()) {

                Brick.ObjectBrick objectBrick = brick.getObject();

                if (objectBrick != Brick.ObjectBrick.NONE) {
                    String objectBrickStr = StringUtils.GetStringValue(objectBrick);
                    Instantiate(Resources.Load(objectBrickStr), gameObject.transform.position, gameObject.transform.rotation);
                }

                int totalPoints = brick.getPoints()*brick.getCurrentHits();

                GameObject gameObjectGM = GameObject.Find("GameManager");
                GameManager gameManager = (GameManager) gameObjectGM.GetComponent(typeof(GameManager));
                gameManager.addScore(totalPoints);
                gameManager.minusBrick();

                Destroy(gameObject);
            }
        }
    }

I have tried different things:

  1. I harcoded the positions for the blocks, but after the Instantiate method in the WallBuilder.cs, they are set in other positions, maybe I'm wrong, but could be something about physics between the objects.

  2. After that I removed the rigidbody2D of the prefab bricks, and they start to overlap each other no matter the offset I defined in the WallBuilder.cs. (I'll upload a screenshot of this later).

  3. After those tests I notice that this problem doesn't occur when each row of my level has the exact amount of bricks, if I add one in any row, that problem occurs when I start the game.

I hope someone help me out.

Thank you

share|improve this question

This question has an open bounty worth +50 reputation from oscar.rpr ending in 6 days.

This question has not received enough attention.

I can't seem to understand this problem, even, with my tests, I'm just guessing at this point. I know that it's something with the physics or something with the coordinate system, but I can't seem to find the problem.

    
What have you tried? Did you compare the block's positions with what you're setting them to in the file? Have you tried setting a block to a known hard coded position and compared that to where it was actually set in game? There's lots of things you should have tried already and I don't see any effort described here. –  Byte56 2 days ago
    
Yes, I'm sorry, I forgot to put that in the posts. I already edited with the things I had try to fix the problem. Thanks. –  oscar.rpr 2 days ago
    
@oscar.rpr Did you try to step through the code that instantiate the block and check their initial positions ? –  concept3d 13 hours ago
    
@concept3d yes, I use the Instantiate method and after that, I print the position of the object, and it's set correctly, but after that, in some point, changes the position, but can't figure out where. –  oscar.rpr 13 hours ago
    
@oscar.rpr one way to do it. Is to try to disable one feature at a time until you find the culprit. It's time consuming. But I often used this in large software. I think it should take too much time. –  concept3d 13 hours ago

1 Answer 1

A few things catch my attention off the bat. First:

    filedata = sr.text.Split('\n').Select(s=>s.Split(',').ToList()).ToList();  

Feels highly dubious to me. Are you sure this is doing what you expect it do be doing?
Second:

    float halfWidth = mainCamera.aspect * (mainCamera.orthographicSize/100);  
    float tempYOffset = (mainCamera.orthographicSize/100) - yOffset - 0.5f;  

Is just begging for integer division issues. I'd toss an 'f' on each of those 100s, just to be explicitly clear that you are indeed doing float division.

share|improve this answer
    
I thought the same at first. But I checked to find out that orthographicSize is float. So I assume 100 will be promoted to float. –  concept3d 11 hours ago
    
With the way unity handles floats, I would not assume any promotion –  Habitablaba 11 hours ago
    
In C#, an integer will become a float in a float/integer division. Unity does not alter the language or runtime that much. –  Josh Petrie 10 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.