Уроки:Движение 2D космического корабля (Часть 2)

Материал из Blitz3D to Unity3D Wiki Project
Перейти к: навигация, поиск

Итак часть вторая - пролет через края экрана.

Для этого нам понадобятся 2 скрипта. Первый будет рассчитывать область экрана, второй будет работать на каждом объект, который должен пролетать через края экрана.

1. Скрипт расчета области игры.

using UnityEngine;

// скрипт рассчитывает область, выходя за которую 
// корабль перемещается на другую сторону экрана
public class RectangleArea : MonoBehaviour
{
    // статическая переменная области, 
    // которая используется в скрипте RectangleAreaObject
    public static Vector3 areaSize;
    public static Vector3 areaHalfSize;

    // буферная область для перелета за экраном
    public float bufferArea;

    // считаем область каждый кадр, 
    // но по хорошему надо считать только при смене разрешения игры
    public void Update()
    {
        CalculateArea();
    }

    // функция рассчета области
    public void CalculateArea()
    {
        var cam = Camera.mainCamera;
        var camTransform = cam.transform;
        // считаем что камера оп осям z и x не смещена, т.е. x и z равны нулю
        // само действи игры происходит в проскости x0z
        var distance = camTransform.position.y;
        var halfAngle = cam.fov * 0.5f;
        var height = distance * Mathf.Tan(halfAngle * Mathf.Deg2Rad) * 2;
        var width = height * cam.aspect;
        areaSize = new Vector3(width + bufferArea, 20, height + bufferArea);
        areaHalfSize = areaSize * 0.5f;
    }

    // при нажатии Play можно увидеть саму область
    public void OnDrawGizmos()
    {
        Gizmos.DrawWireCube(Vector3.zero, areaSize);
    }
}

Вешаем этот скрипт на пустой объект, объект должен находиться в сцене, чтобы выполнялся расчет. В примере буферная зона равна 10 единицам мира.

2. Скрипт для объектов.

using UnityEngine;

// скрипт необходимо вешать на каждый объект,
// который должен переходить через края экрана
public class RectangleAreaObject : MonoBehaviour
{
    public void Update()
    {
        var size = RectangleArea.areaSize;
        var halfSize = RectangleArea.areaHalfSize;

        // если координата объекта выходит за половину размера области, 
        // то смещаем объект в обратную сторону по этой координате на полный размер

        if (transform.position.x > halfSize.x)
        {
            var pos = transform.position;
            pos.x -= size.x;
            transform.position = pos;
        }
        else if (transform.position.x < -halfSize.x)
        {
            var pos = transform.position;
            pos.x += size.x;
            transform.position = pos;
        }

        if (transform.position.z > halfSize.z)
        {
            var pos = transform.position;
            pos.z -= size.z;
            transform.position = pos;
        }
        else if (transform.position.z < -halfSize.z)
        {
            var pos = transform.position;
            pos.z += size.z;
            transform.position = pos;
        }

    }
}

Этот скрипт вешаем на корабль на тот же объект, на котором висит контроллер корабля, написанный в предыдущем примере.

Собственно результат

Скачать доработанный пример