Как исправить эту ошибку в Unity3d?

Обучаюсь в Unity3d по книге. Пишу код, но все равно вылазит вот такая ошибка:

NullReferenceException: Object reference not set to an instance of an object
GateKeeper.OnCollisionStay (UnityEngine.Collision coll) (at Assets/__Scripts/GateKeeper.cs:28)


Код переписал правильно. Он должен работать так:
ГГ подходит к двери и она должна поменять Tile на открытую дверь, но вместо этого при столкновением с ЛЮБЫМ Tile выдаёт выше перечисленную ошибку.

Вот код где задействовано столкновение:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GateKeeper : MonoBehaviour
{
    const int lockedR = 95;
    const int lockedUR = 81;
    const int lockedUL = 80;
    const int lockedL = 100;
    const int lockedDL =101;
    const int lockedDR = 102;

    const int openR = 48;
    const int openUR = 93;
    const int openUL = 92;
    const int openL = 51;
    const int openDL  =26;
    const int openDR = 27;

    private IKeyMaster keys;

    void Awake(){
        keys = GetComponent<IKeyMaster>();
    }

    void OnCollisionStay( Collision coll ){
        if (keys.keyCount < 1) return;

        Tile ti = coll.gameObject.GetComponent<Tile>();
        if (ti == null) return;

        int facing = keys.GetFacing();
        Tile ti2;
        switch (ti.tileNum) {
            case lockedR:
                if(facing != 0) return;
                ti.SetTile(ti.x , ti.y , openR);
                break;
            case lockedUR:
                if(facing != 1) return;
                ti.SetTile( ti.x, ti.y, openUR );
                ti2 = TileCamera.TILES[ti.x-1, ti.y];
                ti2.SetTile( ti2.x, ti2.y, openUL );
                break;
            case lockedUL:
                if (facing != 1) return;
                ti.SetTile( ti.x, ti.y, openUL );
                ti2 = TileCamera.TILES[ti.x+1, ti.y];
                ti2.SetTile( ti2.x, ti2.y, openUR );
                break;
            case lockedL:
                if (facing != 2) return;
                ti.SetTile( ti.x, ti.y, openL );
                break;
            case lockedDL:
                if (facing != 3) return;
                ti.SetTile( ti.x, ti.y, openDL );
                ti2 = TileCamera.TILES[ti.x+1, ti.y];
                ti2.SetTile( ti2.x, ti2.y, openDR );
                break;
            case lockedDR:
                if (facing != 3) return;
                ti.SetTile( ti.x, ti.y, openDR );
                ti2 = TileCamera.TILES[ti.x-1, ti.y];
                ti2.SetTile( ti2.x, ti2.y, openDL );
                break;
            
            default:
                return;
        }
        keys.keyCount--;
    }
}


Это код Tile(генерация карты и т.д.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Tile : MonoBehaviour
{
    [Header("Set Dinamically")]
    public int x;
    public int y;
    public int tileNum;

    private BoxCollider bColl;

    void Awake(){
        bColl = GetComponent<BoxCollider>();
    }

    public void SetTile(int eX , int eY , int eTileNum = -1){
        x = eX;
        y = eY;
        transform.localPosition = new Vector3(x , y , 0);
        gameObject.name = x.ToString("D3") + "x" + y.ToString("D3");

        if(eTileNum == -1){
            eTileNum = TileCamera.GET_MAP(x , y);
        }else {
            TileCamera.SET_MAP(x ,  y, eTileNum); 
        }
        tileNum = eTileNum;
        GetComponent<SpriteRenderer>().sprite = TileCamera.SPRITES[tileNum];

        SetCollider();
    }

    void SetCollider(){
        bColl.enabled = true;
        char c = TileCamera.COLLISIONS[tileNum];
        switch (c){
            case 'S':
                bColl.center = Vector3.zero;
                bColl.size = Vector3.one;
                break;
            case 'W':
                bColl.center = new Vector3( 0, 0.25f, 0 );
                bColl.size = new Vector3( 1, 0.5f, 1 );
                break;
            case 'A':
                bColl.center = new Vector3( -0.25f, 0, 0 );
                bColl.size = new Vector3( 0.5f, 1, 1 );
                break;
            case 'D':
                bColl.center = new Vector3(0.25f, 0 ,0);
                bColl.size = new Vector3( 0.5f, 1, 1 );
                break;
            case 'Q':
                bColl.center = new Vector3( -0.25f, 0.25f, 0 );
                bColl.size = new Vector3( 0.5f, 0.5f, 1 );
                break;
            case 'E':
                bColl.center = new Vector3( 0.25f, 0.25f, 0 );
                bColl.size = new Vector3( 0.5f, 0.5f, 1 );
                break;
            case 'Z':
                bColl.center = new Vector3( -0.25f, -0.25f, 0 );
                bColl.size = new Vector3( 0.5f, 0.5f, 1 );
                break;
            case 'X':
                bColl.center = new Vector3( 0, -0.25f, 0 );
                bColl.size = new Vector3( 1, 0.5f, 1 );
                break;
            case 'C':
                bColl.center = new Vector3( 0.25f, -0.25f, 0 );
                bColl.size = new Vector3( 0.5f, 0.5f, 1 );
                break;
            default:
                bColl.enabled = false;
                break;
        }
    }
}


Это код интерфейса для Ключей для двери.:

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

public interface IKeyMaster
{
    int keyCount { get; set; }
    int GetFacing();
}


Прошу помощи, пожалуйста.
  • Вопрос задан
  • 30 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы