Can't get component on Instiantiated Object

I'm completely new to photon. I have a fair bit of experience with Unity but learning multiplayer feels like learning a new game engine lol.

I'm using photon and making a chess game, so I've put photon Views and practically everything, except the objects I want to be unique. I feel like I've gotten most of it figured out, but for some reason, when I start a multiplayer game, it doesn't initialize my chess pieces properly. So, I have it placing all the pieces at start, with this nested for loop,
for (int x = 0; x < boardGrid.GetLength(0); x++)
        {

            for (int y = 0; y < boardGrid.GetLength(1); y++)
            {

                    boardGrid[x, y] = new Vector3(chessPieceContainer.position.x + x * spaceBetweenPieces, chessPieceContainer.position.y + y * spaceBetweenPieces, 0);

                    if (y < 2 || y > 5)
                    {

                        GameObject spawnedPiece = PhotonNetwork.InstantiateRoomObject("Prefabs/Piece", boardGrid[x, y], transform.rotation);
                        pieces[x, y] = spawnedPiece.GetComponent<ChessPiece>();
                        pieces[x, y].posOnBoard = new Vector2Int(x, y);
                    }
                
            }
        }
The "pieces" array is a 2D array of the ChessPiece class, which assigns the sprites, team, and movesets based on position on the board. It's very strange, it works just fine on a single player game, but if I build the game and play two player(which is the exact same script, it just disables the AI), for some reason, only the build gets a null reference exception error at this line,
pieces[x, y] = spawnedPiece.GetComponent<ChessPiece>();
It seems to be unable to get a reference to the chesspiece, and therefore, it sets all the pieces to white rooks as white rook is in the default position. Weirdly, the pieces initialize properly on the editor's screen. And also, if I play the build version in single player, it seems to initialize everything just fine.

Does anyone know what could be causing this? It's spawning the pieces just fine, but it doesn't seem to be able to get the component on the script...

Comments

  • sdsdink
    sdsdink
    edited March 2021
    well, without having the game and scripts at my disposal, all I can really do is just guess.. That said, null reference means the referenced object does not exist

    Therefore, Id have to guess that either:

    pieces[x,y] is non-existant.
    spawnedPiece is non-existant
    or
    ChestPiece is non-existant.

    Please do a Debug.,Log() on the line before you call this code, and let me know what each of those values are referenced as, to unity.

    Id say its more spawnedPiece than anything.. maybe you just didn't assign it correctly.
  • But it works just fine if I play the game in singleplayer, and even if I play it in multiplayer, with one running on my editor and one running on a build, it will assign the
    pieces[x, y].posOnBoard = new Vector2Int(x, y);
    Just fine on the editor, but not on the build. If I build it, and play singleplayer, it will play the game just fine, which I don't understand because literally the only difference between singleplayer and mutliplayer is the AI gets disabled in multiplayer(which is just one call in the start method)

    It's probably because I don't have much knowledge on multiplayer, I'm sure I'm just doing something wrong... But here's my script, if it's any help, I think the method I posted is the only part that is failing though.

    https://pastebin.com/bVUJ25Yu

    So, to reiterate, if I play singleplayer in the editor or build, it works fine, if i play multiplayer, it works fine on the editor, but it fails to get the component in the build.
  • And I am certain they are in the same game, if I move one piece on the editor, it moves in the build as well...
  • Mashimaro7
    edited March 2021
    Can anybody please help? I've tried asking this question everywhere and haven't received any help... It seems like it's a simple issue, I'm just too dumb to fix it lol.

    I have determined that the issue only occurs on the joining player's screen, I tested it by running the editor after the build had already joined and the null refence exception only occurred on the editor. Also, yes I have photonviews on everything, and there is no duplicate objects or managers in the scene or anything of the sort.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @Mashimaro7,

    Thank you for choosing Photon!

    I can't help with the issue in the original (and previous) post (NullReferenceException) but I can give a few observations and notes about the code you provided in pastebin.

    Not sure why the chess pieces are networked room objects (InstantiateRoomObject).
    I think each player should have his own pieces as his own networked objects (InstantiateObject).

    Make sure to read "Ownership & Control".

    Besides, I don't think it's correct to call InstantiateObject inside an RPC.
    Just go ahead and call Instantiate! get rid of the RPC!
    Or maybe inside the RPC you could make use of photonView.IsMine.

    Hmm...I just checked I don't see "photonView.RPC("InitiateBoard", )" and instead I see call to InitiateBoard() directly. So maybe you are not using this as an RPC and should remove the "[PunRPC]" attribute?

    In my opinion, for a chess game:
    You don't have to have everything as networked objects (PhotonView).
    You could make use of room properties (board state) and RaiseEvent or SetProperties to change or move pieces.
  • JohnTube wrote: »
    Hi @Mashimaro7,
    Hmm...I just checked I don't see "photonView.RPC("InitiateBoard", )" and instead I see call to InitiateBoard() directly. So maybe you are not using this as an RPC and should remove the "[PunRPC]" attribute?

    In my opinion, for a chess game:
    You don't have to have everything as networked objects (PhotonView).
    You could make use of room properties (board state) and RaiseEvent or SetProperties to change or move pieces.
    Thank you for your response, yes, I am not calling the RPC, I was playing around with a few different ways to initiate the board. It was initiating the board with 2 pieces on each spot, which is why I changed it to InstantiateRoomObject.

    Although, I just tried removing it and it seems to have been fixed, I probably unwittingly fixed it haha.

    Learning networking feels like a brand new language, and I would know, I'm bilingual lol, I shouldn't have waited so long to learn it. I can even tell Photon makes it a lot easier than most systems... What is RaiseEvent? Would you be able to give me an example with the MovePiece method at line 219, please? Would I have to make an Event and call the move piece as well as capture piece through that event?
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited March 2021
    Hi @Mashimaro7,

    See here for RaiseEvent.
    I'm not saying you should change your code to switch from PhotonView/RPC to RaiseEvent.
    It's just my opinion.

    EDIT: I'm also bilingual btw. I recommend that you start with some tutorials (PUN Basics Tutorial and some YouTube ones). Photon Realtime Unity SDK has a Memory Demo which is turn-based, async and has a "board"-like. You could take a look for inspiration. Also, PUN has a PunTurnManager script to help (it was made in PUN Classics for RockPaperScissors which was not ported to PUN2).

    You could do this using PhotonView/RPC still of course.
    And all my suggestions are just to help you and if you think it makes things more complicated forget about them and just focus on fixing your issues one by one.
  • Mashimaro7
    edited March 2021
    JohnTube wrote: »
    Hi @Mashimaro7,

    See here for RaiseEvent.
    I'm not saying you should change your code to switch from PhotonView/RPC to RaiseEvent.
    It's just my opinion.

    EDIT: I'm also bilingual btw. I recommend that you start with some tutorials (PUN Basics Tutorial and some YouTube ones). Photon Realtime Unity SDK has a Memory Demo which is turn-based, async and has a "board"-like. You could take a look for inspiration. Also, PUN has a PunTurnManager script to help (it was made in PUN Classics for RockPaperScissors which was not ported to PUN2).

    You could do this using PhotonView/RPC still of course.
    And all my suggestions are just to help you and if you think it makes things more complicated forget about them and just focus on fixing your issues one by one.

    Ayy, Biligual bro!

    I'll check out that demo, I've found some tutorials, but it's very hard to adapt these ideas into a chess game, and it's hard to figure out what exactly needs to be networked.

    Okay, so I'll just do it with RPCs, so I tried running an RPC on the MovePiece method, but it gave an error on the Vector2Int that I'm passing in? "Exception Write failed. Custom type not found: UnityEngine.Vector2Int"

    This is how I'm calling it,
    Vector2Int position = CheckGridPosAtCoords(mousePos);
     photonView.RPC("MovePiece",RpcTarget.All, position, selectedPiece);
    
  • JohnTube
    JohnTube ✭✭✭✭✭
    Photon has a list of supported types that can be exchanged.
    See list here.
    You need to change exchanged data type and replace Vector2Int with something else (Vector2, or two parameters int, int) or register custom type Vector2Int.

    NOTE: Sorry I'm not bilingual, I actually speak more than 2 languages and I just wanted to say that English is not my mother tongue.
  • Mashimaro7
    edited March 2021
    JohnTube wrote: »
    Photon has a list of supported types that can be exchanged.
    See list here.
    You need to change exchanged data type and replace Vector2Int with something else (Vector2, or two parameters int, int) or register custom type Vector2Int.

    NOTE: Sorry I'm not bilingual, I actually speak more than 2 languages and I just wanted to say that English is not my mother tongue.

    Oh okay... So I also ran into an issue with the piece selection, it moves properly on one screen, but the other screen doesn't know which piece is selected. I tried making the selected piece an RPC, but now I can't pass in the "ChessPiece" class anymore, and don't know how to select a piece, because it's checking for the piece at the mouse position, but of course, this means it is checking for two separate mouse positions across two separate games.

    Ah, English is my native language, but I was just saying learning networking feels like learning a new language did :P

    Edit: Oh, nevermind. I got that working. Now I just need to get team switching working lol. I bet I'll have issues capturing pieces as well, but I'll see.