构造函数在Unity中未按预期工作

时间:2017-04-14 14:40:54

标签: c# unity3d

我试图在Update / Awake函数中创建我的GridData数据作为测试。但我似乎无法让我的构造函数工作。我是CSharp和Unity的新手。所以,我有点卡在这里。

GridData类

[System.Serializable]
public class GridData  {

    [System.Serializable]
    public struct rowData{
        public float[] colum;

    }
    public static int numRows =30;
    public static int numColums =20;
    public rowData[] rows = new rowData[numRows]; 


    //
    //Constructor
    public GridData(int x, int y){
        numRows =y;
        numColums = x;
        rowData[] rows = new rowData[numColums];
    }
}

FactalMapData类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FractalMapData : MonoBehaviour {

    public int gridWidth =20;
    public int gridWHight =20;
    public GridData fractalGrid ;   
    void Update () {

        //TEST
        fractalGrid =new GridData(gridWidth,gridWHight);
        Debug.Log ("row" + fractalGrid.rows.Length); //Object reference not set to an instance of an object
        Debug.Log ("colum" + fractalGrid.rows[0].colum.Length);//Object reference not set to an instance of an object
    }
}

3 个答案:

答案 0 :(得分:1)

您永远不会在代码中的任何位置初始化public float[] colum;

因此,当您调用构造函数时,虽然您正确地创建了一个初始化的rows数组,但每个colum实例的rowData字段尚未初始化并将抛出null尝试访问集合的长度时引用异常。

答案 1 :(得分:1)

public GridData(int x, int y){
    numRows =y;
    numColums = x;
    rowData[] rows = new rowData[numColums];  // BUG HERE
}

此处您声明了一个LOCAL变量rows,其名称与名为rows的实例字段相同。因此,实例字段rows永远不会被分配。

你的意思是:

public GridData(int x, int y){
    numRows =y;
    numColums = x;
    rows = new rowData[numColums];
}

答案 2 :(得分:1)

根据我的评论中的建议,我建议您在构建oop代码之前实际学习 oop。

但是,错误的学习并不是那么糟糕,所以在这里你做的是:

[System.Serializable] // not a mistake, but do you really need this?
public class GridData  {

    [System.Serializable] 
    public struct rowData{
        public float[] colum;
    }
    // why are you using a struct with only one field in it
    // do you really need a struct?

    // PITFALL: you'll be wondering later on, why the values for numRows and numColums are the same for all instances
    // Why? Because they are static! That means there are *not* instantiated
    public static int numRows =30;
    public static int numColums =20;

    // You are initializing your rowData here
    // and again in the constructor. What do you actually want?
    public rowData[] rows = new rowData[numRows]; 


    //
    //Constructor
    public GridData(int x, int y){
        // As mentioned before: 
        // you are assigning instantiating values to static fields

        numRows =y;
        numColums = x;

        // you are *defining* a local variable called rows and initializing it with an array of length numColums
        // After we leave the constructor this get's lost
        rowData[] rows = new rowData[numColums];
    }
}

您应该考虑另一件事:为什么要创建

如果你发现,你有充分的理由,问问自己班上的责任是什么。例如:它是否只保留一些数据,它是否提供任何抽象,它是否会操纵它拥有的数据,是否应该公开数据?

我认为你没有回答大部分问题。

以下是可以工作的方式

  • "我需要一个包含一些网格数据的类"
  • "我希望底层数据结构是一维数组" (无论出于何种原因)
  • "抽象是,该类将数据公开为二维网格"
  • "我不需要使用现有数据初始化课程" (现在)

然后你可以实现类

 public class GridData {

    // The concrete data doesn't have to be exposed
    // let's make it private
    private float[] data;

    // let's use properties for this (= less code)
    // get; means it's accessible as defined at the beginning (public)
    // private set; means only the class it self can change these numbers
    public int RowCount { get; private set; }
    public int ColCount { get; private set; }

    // I want to represent the data as a 2D grid so let's make a function
    public float GetCell(int x, int y) {
        // validate requests!
        if( 
            x >= ColCount || x < 0
        ||
            y >= RowCount || y < 0
        ) {
            // don't be shy to throw exceptions!
            // they communicate exceptional circumstances!
         throw new ArgumentOutOfRangeException("Requested cell is not on grid");
        } 

        return data[y * RowCount + x];
    }

    // I want the data to be set from outside
    public float SetCell(int x, int y, float value) {
        // excercise for you!
    }

    public GridData(int cols, int rows) {
        RowCount = rows;
        ColCount = cols;

        this.data = new float[rows * cols];
    }
}

请注意,有多种方法可以实现符合我制定的需求的类。