- Home /
Coroutine called more than once
Hello all and good day!
I am new to unity and I am creating a game based on grid system. I want to move the player's unit from one grid to another based on their input from joystick. However, I am getting strange behavior of:
- unit moving less than it should be (if player move joystick four times there should be four moves)
- sometimes a movement is much slower than it should be (given the speed I set)
- from the log I see that sometimes it only record one joystick input but multiple times of movement.
I am suspecting somewhere in the code I let the coroutine to call more than once, which is not what I intend. I understand that there are similar questions that have been asked but I still couldn't get a clue on what is wrong with my code. So, I would like to obtain some advice from you guys on which direction should I check. Appreciate your time reading this and sorry for my bad English.
Thank you and have a great day!
Here are extract of my code:
public class GameHandler : MonoBehaviour
{
//To get player input from joystick
void Update()
{
float verticalDirection = variableJoystick.Vertical;
float horizontalDirection = variableJoystick.Horizontal;
if (!inAction)
{
inAction = true;
// Joystick Up
if (verticalDirection > 0.5 && Mathf.Abs(horizontalDirection) < 0.5)
{
StartCoroutine(PlayerMove(PlayerUnit.MoveDirection.Up));
Debug.Log("joystick moved");
}
// Joystick Down
else if (verticalDirection < -0.5 && Mathf.Abs(horizontalDirection) < 0.5)
{
StartCoroutine(PlayerMove(PlayerUnit.MoveDirection.Down));
Debug.Log("joystick moved");
}
// Joystick Right
else if (horizontalDirection > 0.5 && Mathf.Abs(verticalDirection) < 0.5)
{
StartCoroutine(PlayerMove(PlayerUnit.MoveDirection.Right));
Debug.Log("joystick moved");
}
// Joystick Left
else if (horizontalDirection < -0.5 && Mathf.Abs(verticalDirection) < 0.5)
{
StartCoroutine(PlayerMove(PlayerUnit.MoveDirection.Left));
Debug.Log("joystick moved");
}
else
{
inAction = false;
//Debug.Log("joystick moved a little");
}
}
}
//Player's move
IEnumerator PlayerMove(BattleUnit.MoveDirection moveDirection)
{
Debug.Log("Player Move");
battleUnit.UnitMove(moveDirection);
while (canProceed == false)
{
yield return null;
}
if (activePlayerUnit.actionPoint <= 0)
{
EndThisTurn();
}
inAction = false; //Completed action
canProceed = false; // Set up for next action
}
}
public class BattleUnit : MonoBehaviour
{
// Find movement destination
public void UnitMove(MoveDirection moveDirection)
{
Map map = GameObject.Find("GridMapManager").GetComponent<Map>();
BattleGrid targetGrid = null;
switch (moveDirection)
{
case MoveDirection.Up:
targetGrid = map.GetGridObject(belongGrid.GetX(), belongGrid.GetY() + 1);
//belongGrid.GetX
break;
case MoveDirection.Down:
targetGrid = map.GetGridObject(belongGrid.GetX(), belongGrid.GetY() - 1);
break;
case MoveDirection.Left:
targetGrid = map.GetGridObject(belongGrid.GetX() - 1, belongGrid.GetY());
break;
case MoveDirection.Right:
targetGrid = map.GetGridObject(belongGrid.GetX() + 1, belongGrid.GetY());
break;
}
StartCoroutine(UnitMoveCoroutine(targetGrid));
}
// Move player's unit to destination
IEnumerator UnitMoveCoroutine(BattleGrid targetGrid)
{
GameHandler gameHandler = GameObject.Find("GameHandler").GetComponent<GameHandler>();
Map map = GameObject.Find("GridMapManager").GetComponent<Map>();
float speed = 2.8f;
float step = speed * Time.deltaTime;
moveDone = false;
if (targetGrid == null || targetGrid.isOccupied == true)
{
Debug.Log("cannot move to target");
moveDone = true;
}
else
{
while (moveDone == false)
{
transform.position = Vector3.MoveTowards(transform.position, map.GetWorldPosition(targetGrid), step);
if (transform.position == map.GetWorldPosition(targetGrid))
{
Debug.Log("Unit Arrived!");
actionPoint -= targetGrid.actionPointUse;
gameHandler.canProceed = true; // Indicate player action finished and can proceed to next action
moveDone = true;
}
yield return null;
}
}
}
}
Your answer
