UnityEngine.Component:get_transform() Error

Hi everyone, I am working on a tetris like game.
So I have a class called OBlock. It has a 2x2 multidimensional array of prefabs called Block. OBlock doesn’t inherit from MonoBehaviour. I use a timer in OBlock to move the blocks in the 2D array one step down.

in OBlock

private void MoveDownOneBlock()
{
    OBlocks[0, 0].MoveDownOneBlock(); // Line 151
    OBlocks[0, 1].MoveDownOneBlock();
    OBlocks[1, 0].MoveDownOneBlock();
    OBlocks[1, 1].MoveDownOneBlock();
}

in Block

public void MoveDownOneBlock()
{
    move = -0.5f;
    transform.position = new Vector3(transform.position.x, transform.position.y + move, transform.position.z); // Line 159
    RowNum++;
}

When I run this code I get the following error.

UnityEngine.Component:get_transform()
Block:MoveDownOneBlock() (at Assets\Scripts\Block.cs:159)
OBlock:MoveDownOneBlock() (at Assets\Scripts\OBlock.cs:151)
OBlock:Update() (at Assets\Scripts\OBlock.cs:80)
OBlock:Timer_Elapsed(Object, ElapsedEventArgs) (at Assets\Scripts\OBlock.cs:202)
System.Timers.Timer:Callback(Object)

I get the same error even when I do this

public void MoveDownOneBlock()
{
    move = -0.5f;
    transform.Translate(new Vector3(0, move, 0));
    RowNum++;
}

The weird thing is that I was able to change the blocks’ location at the start of the code.

in OBlock.cs

public void init()
{
    OBlocks[0, 0].RowNum = 0
    OBlocks[0, 0].ColumnNum = 5;
    OBlocks[0, 0].InitPosition();

    OBlocks[0, 1].RowNum = 0; OBlocks[0, 1].ColumnNum = 6; OBlocks[0, 1].InitPosition();
    OBlocks[1, 0].RowNum = 1; OBlocks[1, 0].ColumnNum = 5; OBlocks[1, 0].InitPosition();
    OBlocks[1, 1].RowNum = 1; OBlocks[1, 1].ColumnNum = 6; OBlocks[1, 1].InitPosition();
}

in Block.cs

public void InitPosition()
{
    MaxRight = 3.5f;
    MaxLeft = -1.5f;
    MaxUp = 4.7f;
    MaxDown = -3.3f;
    transform.position = new Vector3((ColumnNum * 0.5f) + MaxLeft, ((RowNum * 0.5f) - MaxUp) * -1, transform.position.z); // Line 40
}

and no error appeared.
So I tried this

public void MoveDownOneBlock()
{
    RowNum++;
    InitPosition();
}

but I got the same error pointing to line 40.

Can someone help me with this?
Sorry for the long question. I want to give you as much details as possible.

I’m pretty sure .Net Timers are executed in their own thread. In Unity it is not possible to manipulate the scene hierarchy (all objects instantiated on the current scene) from outside the main thread.

But I don’t understand the need of timers. Unity API already provide everything you need for timed behaviours. You may want to use the Time.deltaTime in an Update() of your script or a coroutine.


With a coroutine:

bool m_bIsGameFinished = false;
IEnumerator Start()
{
    while( !m_bIsGameFinished )
    {
        yield return new WaitForSeconds( 1.0f );
        MoveDownOneBlock();
    }
}

Inside Update method:

float m_fElapsedTime = 0.0f;
void Update()
{
    this.m_fElapsedTime += Time.deltaTime;
    if( this.m_fElapsedTime >= 1.0f )
    {
        this.m_fElapsedTime = 0.0f;
        MoveDownOneBlock();
    }
}