在Unity MonoBehaviour脚本中实例化自定义对象

时间:2020-04-14 16:43:07

标签: c# unity3d

我正在尝试在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);
        }
    }
}

0 个答案:

没有答案
相关问题