我正在学习团结,我正在重新制作我在XNA中团结一致的游戏。
我有主要的相机脚本来调整自己到播放器变换的位置,但我希望它仅限于地图边界。
这给了我两个问题:
1)将限制相机移动的脚本部分添加到地图的边界
2)从地图上抛出的大量预制件中获取实际的地图边界。
这是Red-Black tree关于与不起作用的墙壁的碰撞(如果你愿意的话,请进入帖子,因为我也希望对碰撞问题有一些帮助)
当我在地图上大致居中时,这是相机尺寸为4.5的样子:
当相机只是显示地图的某些部分并且没有它时,这就是相机尺寸4.5的样子
当我将相机尺寸降低到3时,它看起来大致如此:
基于此,有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);
}
}
}