Unity将相机定位在变换和限制相机移动到地图上

时间:2015-12-19 14:09:27

标签: c# unity3d camera

我正在学习团结,我正在重新制作我在XNA中团结一致的游戏。

我有主要的相机脚本来调整自己到播放器变换的位置,但我希望它仅限于地图边界。

这给了我两个问题:

1)将限制相机移动的脚本部分添加到地图的边界
2)从地图上抛出的大量预制件中获取实际的地图边界。

这是Red-Black tree关于与不起作用的墙壁的碰撞(如果你愿意的话,请进入帖子,因为我也希望对碰撞问题有一些帮助)

当我在地图上大致居中时,这是相机尺寸为4.5的样子:

another post of mine

当相机只是显示地图的某些部分并且没有它时,这就是相机尺寸4.5的样子

enter image description here

当我将相机尺寸降低到3时,它看起来大致如此:

enter image description here

基于此,有3件事要做:

1)限制相机尺寸不能大于地图宽度
2)限制相机移动不能移动到地图之外
2.1)为了能够做到(2)我需要得到地图边界。

要生成地图,我使用我在其他帖子中指定的教程中的脚本,并更改​​为我的需求:

using System.Collections.Generic;
using UnityEngine;

namespace Assets.Scripts
{
    internal enum BlockPosition
    {
        None = -1,
        Top = 0,
        Bottom,
        Left,
        Right,
        TopLeft,
        TopRight,
        BottomLeft,
        BottomRight
    }

    public class BoardManager : MonoBehaviour
    {
        private const int BORDER_COL = -1;
        public int columns = 15;
        public int rows = 15;

        // Up, Down, Left, Right, TopLeft, TopRight, BottomLeft, BottomRight
        public GameObject[] wallTiles;
        public GameObject[] floorTiles;

        private readonly List<Vector3> floorPositions = new List<Vector3>();

        private Transform boardHolder;
        private Transform floorHolder;
        private Transform wallsHolder;

        private void InitializeFloorPositionsList()
        {
            floorPositions.Clear();

            for (int i = 0; i < columns; ++i)
            {
                for (int j = 0; j < rows; ++j)
                {
                    floorPositions.Add(new Vector3(i, j, 0f));
                }
            }
        }

        /// <summary>
        /// Gets the BlockPosition based on where on the wall grid the block is
        /// </summary>
        /// <param name="row">Row of the block</param>
        /// <param name="col">Column of the block</param>
        /// <returns>BlockPosition representing the position of the wall, or BlockPosition.None if it's a center block(a floor)</returns>
        private BlockPosition GetBlockIndex(int row, int col)
        {
            ///////////
            // 1 2 3 //
            // 4 5 6 // Number represents position in map
            // 7 8 9 //
            ///////////
            if (row == BORDER_COL)
            {
                if (col == BORDER_COL)
                    return BlockPosition.BottomLeft;    // 7
                if (col == columns)
                    return BlockPosition.BottomRight;   // 9
                return BlockPosition.Bottom;            // 8
            }
            if (row == rows)
            {
                if (col == BORDER_COL)
                    return BlockPosition.TopLeft;       // 1
                if (col == columns)
                    return BlockPosition.TopRight;      // 3
                return BlockPosition.Top;               // 2
            }
            if (col == BORDER_COL)
                return BlockPosition.Left;              // 4
            if (col == columns)
                return BlockPosition.Right;             // 6
            return BlockPosition.None;                  // 5
        }

        private void SetUpWalls()
        {
            boardHolder = new GameObject("Board").transform;
            floorHolder = new GameObject("Floors").transform;
            floorHolder.parent = boardHolder;
            wallsHolder = new GameObject("Walls").transform;
            wallsHolder.parent = boardHolder;

            for (int col = BORDER_COL; col < columns + 1; col++)
            {
                for (int row = BORDER_COL; row < rows + 1; row++)
                {
                    BlockPosition pos = GetBlockIndex(row, col);
                    if (pos == BlockPosition.None) continue;

                    GameObject toInstantiate = wallTiles[(int)pos];
                    GameObject instance =
                        Instantiate(toInstantiate, new Vector3(col, row, 0f), Quaternion.identity) as GameObject;
                    instance.transform.parent = wallsHolder;
                }
            }
        }

        private Vector3 RandomPosition()
        {
            int randomIndex = Random.Range(0, floorPositions.Count);
            Vector3 position = floorPositions[randomIndex];
            floorPositions.RemoveAt(randomIndex);
            return position;
        }

        private void LayoutObjectsAtRandom(GameObject[] objects, int amount, Transform parent)
        {
            for (int i = 0; i < amount; ++i)
            {
                Vector3 position = RandomPosition();
                GameObject instantiatedObject = objects[Random.Range(0, objects.Length)];
                GameObject instantiated = Instantiate(instantiatedObject, position, Quaternion.identity) as GameObject;
                instantiated.transform.parent = parent;
            }
        }

        /// <summary>
        /// Sets up the floors and the extraWalls
        /// </summary>
        /// <param name="extraWalls">for dev purposes, amount extra walls to be spreaaround the map</param>
        public void SetUpScene(int extraWalls)
        {
            InitializeFloorPositionsList();
            SetUpWalls();
            LayoutObjectsAtRandom(wallTiles, extraWalls, wallsHolder);
            LayoutObjectsAtRandom(floorTiles, floorPositions.Count, floorHolder);
        }
    }
}

正如你所看到的,我遵循了教程,最终有一个变换,它包含所有实例化的地图部分 - 它被称为“Board”,它还拥有另外两个名为“Floors”和“Walls”的变换,持有地板和墙壁。
您将如何解决我上面提到的这三个问题?

我只是Unity的初学者,我只是一名C#/ C ++开发人员,所以XNA对我来说更简单,因为它比团结更加以代码为中心。

编辑:这是CameraController脚本:

using UnityEngine;

namespace Assets.Scripts
{
    public class CameraController : MonoBehaviour
    {
        public Transform player;
        public Vector2 margin, smoothing;

        public bool IsFollowing { get; set; }

        public void Start()
        {
            IsFollowing = true;
        }

        public void Update()
        {
            var x = transform.position.x;
            var y = transform.position.y;

            if (IsFollowing)
            {
                if (Mathf.Abs(x - player.position.x) > margin.x)
                    x = Mathf.Lerp(x, player.position.x, smoothing.x * Time.deltaTime);

                if (Mathf.Abs(y - player.position.y) > margin.y)
                    y = Mathf.Lerp(y, player.position.y, smoothing.y * Time.deltaTime);
            }

            transform.position = new Vector3(x, y, transform.position.z);
        }
    }
}

0 个答案:

没有答案