我正在尝试在Unity中编程自己的小游戏,我不是编程新手,而是Unity和C#的新手。问题是我写了自己的类来处理游戏地图,并且试图将这些类连接到Unity中的MonoBehaviour脚本。
我有一个名为 InputManager 的脚本,该脚本应该通过鼠标和键盘等处理输入。在此脚本中,我想创建一个 MapManager 类的对象>可以访问我的图块和东西。我遇到的问题是,我似乎无法在InputManager中创建MapManager的实例,无论如何也不能与公共new MapManager()
一起创建。当我使用此方法时,会创建某种NullPointer吗?
我没有得到编译错误,但是在游戏启动后出现了一个错误:
NullReferenceException: Object reference not set to an instance of an object
InputManager.Update () (at Assets/Scripts/InputManager.cs:55)
谢谢您的帮助!
!UPDATE!:
我尝试使用一种变通办法,因此首先调用 Start()或 Update()并不重要,这意味着我只是在第一个< strong> Update()调用。但是,当我运行程序时,错误仍然相同。我的结论是,某种程度上我的构造函数无法正常工作,或者 Monobehaviour 脚本某种程度上不允许使用标准构造函数...有什么想法吗?
这是我的代码:
InputManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class InputManager : MonoBehaviour
{
public int mapRightBorder = 10;
public int mapLeftBorder = -10;
public int mapTopBorder = 8;
public int mapBottomBorder = -4;
public double camSpeed = 0.2;
public double mouseSensitivity = 0.3;
public double scrollSensitivity = 2;
public double maxZoomIn = -3;
public double maxZoomOut = -12;
public Tilemap ground, overlays, buildings;
public Tilemap selected;
public AnimatedTile animatedTile;
private double detectionBorder;
private double leftRightCorrection;
private MapManager mapManager;
// Start is called before the first frame update
void Start()
{
detectionBorder = 50;
leftRightCorrection = 1.2;
mapManager = new MapManager();
mapManager.ground = ground;
mapManager.overlays = overlays;
mapManager.buildings = buildings;
mapManager.selected = selected;
mapManager.animatedTile = animatedTile;
Cursor.lockState = CursorLockMode.Confined;
}
// Update is called once per frame
void Update()
{
moveCam();
checkMouse();
mapManager.updateTilemaps();
}
private void moveCam()
{
double moveX = Camera.main.transform.position.x;
double moveY = Camera.main.transform.position.y;
double moveZ = Camera.main.transform.position.z;
double xPos = Input.mousePosition.x;
double yPos = Input.mousePosition.y;
double zDelta = Input.GetAxis("Mouse ScrollWheel");
if (Input.GetKey(KeyCode.LeftArrow))
{
moveX -= camSpeed * leftRightCorrection;
}
else if (xPos >= 0 && xPos < detectionBorder)
{
moveX -= camSpeed * mouseSensitivity * leftRightCorrection;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
moveX += camSpeed * leftRightCorrection;
}
else if (xPos <= Screen.width && xPos > Screen.width - detectionBorder)
{
moveX += camSpeed * mouseSensitivity * leftRightCorrection;
}
if(moveX > mapRightBorder || moveX < mapLeftBorder)
{
moveX = Camera.main.transform.position.x;
}
if (Input.GetKey(KeyCode.DownArrow))
{
moveY -= camSpeed;
}
else if (yPos >= 0 && yPos < detectionBorder)
{
moveY -= camSpeed * mouseSensitivity;
}
else if (Input.GetKey(KeyCode.UpArrow))
{
moveY += camSpeed;
}
else if (yPos <= Screen.height && yPos > Screen.height - detectionBorder)
{
moveY += camSpeed * mouseSensitivity;
}
if(moveY > mapTopBorder || moveY < mapBottomBorder)
{
moveY = Camera.main.transform.position.y;
}
if (!(moveZ + zDelta * scrollSensitivity > maxZoomIn || moveZ + zDelta * scrollSensitivity < maxZoomOut))
{
moveZ += zDelta * scrollSensitivity;
}
Vector3 newPos = new Vector3((float)moveX, (float)moveY, (float) moveZ);
Camera.main.transform.position = newPos;
}
private void checkMouse()
{
if (Input.GetMouseButtonDown(0))
{
mapManager.selectTile(Input.mousePosition);
}
}
}
MapManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
public class MapManager
{
public int mapWidth = 16;
public int mapHeight = 16;
public Tilemap ground, overlays, buildings;
public Tilemap selected;
public AnimatedTile animatedTile;
private Vector3Int currentlySelected;
private OwnTilemap tilemap;
public MapManager()
{
tilemap = new OwnTilemap(mapWidth, mapHeight, ground, overlays, buildings);
currentlySelected = new Vector3Int(-1, -1, 0);
}
private Vector3Int mouseToTilemap(Vector3 mousePosition)
{
Ray ray = Camera.main.ScreenPointToRay(mousePosition);
// create a plane at 0,0,0 whose normal points to +Y:
Plane hPlane = new Plane(Vector3.forward, Vector3.zero);
// Plane.Raycast stores the distance from ray.origin to the hit point in this variable:
float enter = 0.0f;
if (hPlane.Raycast(ray, out enter))
{
//Get the point that is clicked
Vector3 hitPoint = ray.GetPoint(enter);
Vector3Int cell = ground.WorldToCell(hitPoint);
return cell;
}
return new Vector3Int(-1, -1, 0);
}
private bool isInBorders(Vector3Int p)
{
if (p.z != 0) return false;
if (p.x < 0 || p.x >= mapWidth) return false;
if (p.y < 0 || p.y >= mapHeight) return false;
return true;
}
public void updateTilemaps()
{
tilemap.updateTilemaps();
}
public void previewBuilding()
{
}
public void selectTile(Vector3 mousePosition)
{
if(currentlySelected != new Vector3Int(-1, -1, 0))
{
selected.SetTile(currentlySelected, null);
}
if (isInBorders(mouseToTilemap(mousePosition)))
{
selected.SetTile(mouseToTilemap(mousePosition), animatedTile);
currentlySelected = mouseToTilemap(mousePosition);
}
}
}