Unity Выровняйте префаб по левому верху (2D-игра) - PullRequest
0 голосов
/ 04 июня 2019

Я делаю свою первую игру, в которой препятствия (которые являются префабами) помещаются сценарием в сцену. Все они разных размеров в 2D-среде. Я размещаю их, используя этот код ниже

Instantiate(normal1, new Vector3(x, y , 0), Quaternion.identity);

Это работает отлично, за исключением того, что мне нужно, чтобы все препятствия были расположены сверху слева. Таким образом, если бы у меня было 0, 0 для моих x и y, только угол препятствия покрывал бы позицию 0, 0, а не все. Из того небольшого, что я работал с элементами графического интерфейса, вы можете настроить то, что вам нравится. Это то же самое с prefab, и если да, то как? Или вы можете как-то перенести происхождение объекта?

1 Ответ

1 голос
/ 04 июня 2019

Полагаю, вы говорите об элементах, не относящихся к интерфейсу пользователя.

Проще всего было бы дать вашим объектам родительский GameObject и расположить их таким образом, чтобы родительский GameObject уже имел точку поворота, в которой вы его хотите (верхний левый угол). Вы делаете это, сначала правильно позиционируя (будущий) родительский объект, а затем просто перетаскиваете дочерний объект в него в иерархии (пока он сохраняет свою текущую позицию).

enter image description here

Тогда в вашем скрипте вы должны использовать Camera.ScreenToWorldPoint, чтобы найти верхнее левое угловое положение экрана в трехмерном мире, например

// an optional offset from the top-left corner in pixels
Vector2 PixelOffsetFromTopLeft;

// Top Left pixel is at 
// x = 0
// y = Screen height

// and than add the desired offset
var spawnpos = new Vector2(0 + PixelOffsetFromTopLeft.x, Screen.height - PixelOffsetFromTopLeft.y);

// as z we want a given distance to camera (e.g. 2 Units in front)
spawnedObject = Instantiate(Prefab, camera.ScreenToWorldPoint(new Vector3(spawnpos.x, spawnpos.y, 2f)), Quaternion.identity);

Полный скрипт, который я использовал в качестве примера

public class Spawner : MonoBehaviour
{
    public GameObject Prefab;

    public Vector2 PixelOffsetFromTopLeft = Vector2.zero;

    private GameObject spawnedObject;
    private Camera camera;

    private void Start()
    {
        camera = Camera.main;
    }

    private void Update()
    {
        if (Input.anyKeyDown)
        {
            // you don't need this I just didn't want to mess up the scene
            // so I just destroy the last spawned object before placing a new one
            if (spawnedObject)
            {
                Destroy(spawnedObject);
            }

            // Top Left pixel is at 
            // x = 0
            // y = Screen height

            // and than add the desired offset
            var spawnpos = new Vector2(0 + PixelOffsetFromTopLeft.x, Screen.height - PixelOffsetFromTopLeft.y);

            // as z we want a given distance to camera (e.g. 2 Units in front)
            spawnedObject = Instantiate(Prefab, camera.ScreenToWorldPoint(new Vector3(spawnpos.x, spawnpos.y, 2f)), Quaternion.identity);
        }
    }
}

enter image description here

Теперь будет всегда появляться объект, привязанный к верхнему левому углу. Так не будет, если камера перемещается или размер окна изменяется.


Если ваш вопрос касался сохранения этой позиции и при изменении размера окна, вы можете использовать тот же код, например. в методе Update (позже из-за эффективности вы должны вызывать его только тогда, когда это действительно необходимо / размер окна действительно изменился), например

public class StickToTopLeft : MonoBehaviour
{
    private Camera camera;

    public Vector2 PixelOffsetFromTopLeft = Vector2.zero;

    private void Start()
    {
        camera = Camera.main;
    }

    // Update is called once per frame
    private void Update()
    {
        var spawnpos = new Vector2(0 + PixelOffsetFromTopLeft.x, Screen.height - PixelOffsetFromTopLeft.y);

        // This time simply stay at the current distance to camera
        transform.position = camera.ScreenToWorldPoint(new Vector3(spawnpos.x, spawnpos.y, Vector3.Distance(camera.transform.position, transform.position)));
    }
}

Теперь объект всегда привязан к верхнему левому углу даже после изменения размера окна и позволяет впоследствии корректировать его смещение.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...