Обучаюсь в 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();
}
Прошу помощи, пожалуйста.