Can't assign materials to objects from an array

Can someone please tell me what is wrong with this code? Depending on how I try to solve the problem, I get rotating list of errors, usually to do with a requirement for an instance of an object to reference a non static value.

The troublesome lines are marked with *

I don't understand why this object can't access it's own local variable.

I must be missing something, so if someone could help me see how I'm getting this wrong, I'd be very greatful.


using System;
using System.Collections;
using UnityEngine;

public class BuildManager {
    //debug info
    private static int count = 0;

    /**** local to class *****/
    *** public Material[] baseMaterials;***

    public static void buildRoad(int x, int z){
        Debug.Log("I have built "+BuildManager.count+" road tiles so far");
        Tile tile = new Tile();
                tile.Awake(x, z, _ROAD);
        tile.GO = GameObject.CreatePrimitive(PrimitiveType.Plane);
        tile.GO.name = "road_"+x+"_"+z;
        tile.GO.tag = "road";       
        tile.GO.transform.position = new Vector3(x, 0, z);
        ***tile.GO.transform.renderer.material = baseMaterials[0];***
        }

I have tried creating a Material manager class and assigning from there, I have tried deriving this class from MonoBehaviour... something just isn't clicking.

Any and all help is welcome.

Best Wishes,

S.

The "buildRoad" function is static, but the "baseMaterials" array is not--it is an instance member. For comparison, you have referenced "BuildManager.count" within the same function as a static member. Declaring baseMaterials as static would get it compiling (but it still may not accomplish what you're trying to do, which is not entirely clear).

Thanks for your reply, Molix :)

I tried to add this reply as a comment, but it wouldn't take...

Basically, the functionality I'd like to end up with is this: 1) Have one single instance of the BuildManager running, like a daemon. Any time a road needs to be built, the BuildManager should get called to put the tile down in the location specified. While creating that Tile, it should assign an appropriate material to the tile from the array of materials I assign to it. I've created those materials in the Editor, and am assigning them through the editor as well.

2) A single instance of a game state manager, which takes care of dispatching and receiving requests and coordinating game logic, calls BuildManager any time it needs a Tile built. It sends the coordinates and type of building to be built to the buildmanager. The buildmanager might either return the instantiated building for the manager daemon to keep track of, or might add it to a master reference list (I currently do this).

I had this all working in Javascript, but needed an easy way to create and manipulate 2d arrays of unspecified sizes.

I understand what you're saying with respect to conflict between a static function, and the non-static array... I looked that up and discovered that issue in c#. But, if I declare baseMaterials as static then it doesn't get exposed to the editor... I could assign materials in code, but for heavens sake, what a pain to have to write that code as well.

Any thoughts?

On the other end of the spectrum of what Molix is saying, you could make BuildManager a singleton.

So something like this

// create a game object and assign this to it
class BuildManager : Monobehaviour
{
    public Material[] baseMaterials; // assign this in editor

    // very simple singleton pattern (doesn't prevent multiple instances, though)
    static BuildManager instance;
    void Awake() { instance = this; }

    // your static function
    public static void BuildRoads( /* whatever */ )
    {
        // your current code

        // get the instance's baseMaterials array and use that
        tile.GO.transform.renderer.material = instance.baseMaterials[0]; 

        // etc

    }
}

Alternatively you could make BuildRoads non static, make instance a public variable, remove the `instance` from the line of code above, and then do `BuildManager.instance.BuildRoads`