ML-агенты Unity: исключение NullReferenceException в AgentReset () - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь создать фигуру, которая может двигаться в направлении других фигур. У меня есть два скрипта:

  • PieceMan.cs, который есть у всех частей и который отвечает за общие логики частей c
  • PieceAgent.cs, что только "умный" штук есть. Этот сценарий расширяет сценарий агента

Я продолжаю получать следующую ошибку, и даже после долгой отладки я все еще не понимаю, откуда она взялась:

NullReferenceException: Object reference not set to an instance of an object
PieceAgent.AgentReset () (at Assets/Scripts/PieceAgent.cs:26)
MLAgents.Agent._AgentReset () (at Assets/ML-Agents/Scripts/Agent.cs:895)
MLAgents.Academy.ForcedFullReset () (at Assets/ML-Agents/Scripts/Academy.cs:563)
MLAgents.Academy.EnvironmentStep () (at Assets/ML-Agents/Scripts/Academy.cs:606)

Это PieceAgent.cs:

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

public class PieceAgent : Agent
{
    private GameObject[] remaining_pieces;
    private GameObject controller;

    void Start()
    {
        this.remaining_pieces = GameObject.FindGameObjectsWithTag("BrainlessPiece"); 
        this.controller = GameObject.FindGameObjectWithTag("GameController");
        SetReward(1.0f);
    }

    public override void AgentReset()
    {
        this.GetComponent<PieceMan>().Demote();
        int random_x = UnityEngine.Random.Range(1,6);
        int random_y = UnityEngine.Random.Range(1,6);

        if (random_x != this.GetComponent<PieceMan>().GetXBoard() || random_y != this.GetComponent<PieceMan>().GetYBoard())
            this.controller.GetComponent<Game>().MoveUnchecked(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard(), random_x, random_y, false);

        foreach (GameObject brainless_piece in this.remaining_pieces)
        {
            brainless_piece.GetComponent<PieceMan>().Demote();
            int brainless_random_x = this.GetComponent<PieceMan>().GetXBoard();
            int brainless_random_y = this.GetComponent<PieceMan>().GetYBoard();
            int prev_x = brainless_piece.GetComponent<PieceMan>().GetXBoard();
            int prev_y = brainless_piece.GetComponent<PieceMan>().GetYBoard();
            while(brainless_random_x == this.GetComponent<PieceMan>().GetXBoard() && brainless_random_y == this.GetComponent<PieceMan>().GetYBoard())
            {
                brainless_random_x = UnityEngine.Random.Range(1, 6);
                brainless_random_y = UnityEngine.Random.Range(1, 6);
            } 
            this.controller.GetComponent<Game>().MoveUnchecked(prev_x, prev_y, brainless_random_x, brainless_random_y, false);
        }
    }

    public override void CollectObservations()
    {
        AddVectorObs(new Vector2(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard()));
    }

    public override void AgentAction(float[] vectorAction, string vectorString)
    {
        List<int[]> possible_moves = new List<int[]>();
        if (this.GetComponent<PieceMan>().IsHorizontal())
            possible_moves = this.GetComponent<PieceMan>().TestLineHorizontally(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard(), this.GetComponent<PieceMan>().IsMaster());
        else
            possible_moves = this.GetComponent<PieceMan>().TestLineVertically(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard(), this.GetComponent<PieceMan>().IsMaster());
        this.GetComponent<PieceMan>().DestroyMovePlates();

        int movement = Mathf.FloorToInt(vectorAction[0]) % possible_moves.Count;

        int[] chosen_movement = possible_moves[movement];
        int move_x = chosen_movement[0];
        int move_y = chosen_movement[1];
        bool attack = chosen_movement[2] == 1;
        this.controller.GetComponent<Game>().MoveUnchecked(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard(), move_x, move_y, attack);

        if(attack)
        {
            Done();
            AddReward(1.0f);
        }
        else 
            AddReward(-0.5f);

        if (GetStepCount() > 998)
        {
            Done();
            AddReward(-1.0f);
        }
    }
}

Я действительно не понимаю, из-за чего он ломается на этой строке:

this.controller.GetComponent<Game>().MoveUnchecked(this.GetComponent<PieceMan>().GetXBoard(), this.GetComponent<PieceMan>().GetYBoard(), random_x, random_y, false);

Еще более странно то, что все вроде работает правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...