Home > Blockchain >  Unity: coroutine couldn't start because the game object 'Player' is inactive
Unity: coroutine couldn't start because the game object 'Player' is inactive

Time:12-22

So, I have this problem in Unity where I make a player in GameManager, then I instantiate it to BoardManager and want to use the turn system in GameManager, the player script is in another file called PlayerScript. I want to create the player in BoardManager, then use it in GameManager. When I try to call the function movement() I get an error "Coroutine couldn't start because the game object 'Player' is inactive".

Obs1: I assign player to instance2 so that I can use it in GameManager.

Obs2: The problem is in Coroutine that doesnt initialize, all the movement is working, the calling method also, its seems to me that the player doesnt exist or something so the function cant be called, I tested the code in different ways but nothing seems to work.

Thanks in advance for the help :)

The code bellow is from BoardManager:

            //map = grid of 50 per 50 of numbers, these numbers says if a floor, wall, player, 
            //enemies, etc are going to be placed in the grid done from procedural generation
            for (int i = 0; i < rows; i  )
            {
                for (int j = 0; j < columns; j  )
                {
                    if (map[i,j] == 0)
                    {
                        GameObject instance = Instantiate(wallTile, new Vector3(i, j, 0f), Quaternion.identity) as GameObject;
                    }

                    if (map[i,j] == 1)
                    {
                        GameObject instance = Instantiate(floorTile, new Vector3(i, j, 0f), Quaternion.identity) as GameObject;    
                    }

                        if (map[i,j] == 2)
                    {
                        GameObject instance1 = Instantiate(floorTile, new Vector3(i, j, 0f), Quaternion.identity) as GameObject;
                        GameObject instance2 = Instantiate(player, new Vector3(i, j, 0f), Quaternion.identity) as GameObject;
                        player = instance2;
                    }
                }
            }

This next block of code is from GameManager: basically I try to get the script from the player that is in the map and use the movement function from this script.

public class GameManager : MonoBehaviour
    {
        public static BoardManager boardScript;
        private int PLAYER_TURN = 1;
        private int ENEMY_TURN = 2;
        private int game_state;
        public GameObject player;
        
        void Awake()
        {
            int[,] map = new int[0,0];
            boardScript = GetComponent<BoardManager>();
            boardScript.makeMap(map, player);
        }
    
        public void Update()
        {
            game_state = PLAYER_TURN;
            if(Input.anyKey)
            {
                char c = Input.inputString[0];
                player.GetComponent<PlayerScript>().movement(c);
                game_state = ENEMY_TURN;
            }  
        }
    }
}

The next block of code is from PlayerScript

public class PlayerScript : MonoBehaviour
{
    private bool isMoving;
    private Vector3 origPos, targetPos;
    private float timeToMove = 0.2f;

    public void movement(char c)
    {
        if (c == 'w' && !isMoving)
            StartCoroutine(movePlayer(Vector3.up));

        if (c == 'a' && !isMoving)
            StartCoroutine(movePlayer(Vector3.left));

        if (c == 's' && !isMoving)
            StartCoroutine(movePlayer(Vector3.down));

        if (c == 'd' && !isMoving)
            StartCoroutine(movePlayer(Vector3.right));

        if (c == 'q' && !isMoving)
            StartCoroutine(movePlayer(new Vector3(-1, 1, 0)));

        if (c == 'e' && !isMoving)
            StartCoroutine(movePlayer(new Vector3(1, 1, 0)));

        if (c == 'c' && !isMoving)
            StartCoroutine(movePlayer(new Vector3(1, -1, 0)));

        if (c == 'z' && !isMoving)
            StartCoroutine(movePlayer(new Vector3(-1, -1, 0)));
    }

    private IEnumerator movePlayer(Vector3 direction)
    {
        isMoving = true;
        float elapsedTime = 0;
        origPos = transform.position;
        targetPos = origPos   direction;

        while(elapsedTime < timeToMove)
        {
            transform.position = Vector3.MoveTowards(origPos, targetPos, (elapsedTime / timeToMove));
            elapsedTime  = Time.deltaTime;
            yield return null;
        }
        transform.position = targetPos;
        isMoving = false;
    }
}

CodePudding user response:

The issue lies with how you're passing the player variable into the boardscript.MakeMap()function. Since function parameters, unless specified, pass by value instead of passing by reference. Which means you are essentially making a copy of the variable for the function to use. The function can assign that variable a value for it's local scope, but it doesn't affect the variable that was passed in outside of the function. See here: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters

To remedy this you can use void makeMap(int[][] map, ref GameObject player), then you to call it you would need to do boardScript.makeMap(map, ref player);

Ref Docs: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref

  • Related