我正在做一個基于回合制統一的 roguelike 游戲,運動更像是國際象棋,你從網格中的一個地方移動到另一個地方。更像是在向量之間移動然后是網格本身。
我做了玩家的移動和敵人的移動,如果我分別單擊 w、a、s、d 鍵,它們就可以正常作業。但是當我試圖握住它時,玩家仍然移動得很好,但是敵人移動的空間比玩家多,而且它也不會從網格到網格,而且大部分時間都停留在網格之間,更像是你在下棋你把女王的一半放在一個空間,另一半放在另一個空間。
我知道問題在于它與Update()函式有關,只有當我按住其中一個移動鍵時才會發生這種情況,PlayerScript 和 EnemyScript 代碼都是正確的。以下3個代碼分別來自GameManager、PlayerScript和EnemyScript,第一個負責回合,第二個負責玩家移動,第三個負責敵人移動。在此先感謝您的幫助 :)
`
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;
public GameObject enemy;
public List<GameObject> enemies;
void Awake()
{
int[,] map = new int[0,0];
boardScript = GetComponent<BoardManager>();
boardScript.makeMap(map, ref player, ref enemies, enemy);
game_state = PLAYER_TURN;
}
public void Update()
{
if(Input.anyKey)
{
Debug.Log("oi");
char c = Input.inputString[0];
player.GetComponent<PlayerScript>().movement(c);
game_state = ENEMY_TURN;
}
if(game_state == ENEMY_TURN)
{
for (int i = 0; i < enemies.Count; i )
{
enemies[i].GetComponent<EnemyScript>().movement();
}
game_state = PLAYER_TURN;
}
}
}
`
`
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 (Input.GetKey(KeyCode.C) && !isMoving)
StartCoroutine(movePlayer(new Vector3(1, -1, 0)));
if (Input.GetKey(KeyCode.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;
}
}
`
public class EnemyScript : MonoBehaviour
{
private bool isMoving;
private Vector3 origPos, targetPos;
private float timeToMove = 0.2f;
public void movement()
{
int rand = Random.Range(0, 4);
if (rand == 1)
{
StartCoroutine(moveEnemy(Vector3.left));
}
if (rand == 2)
{
StartCoroutine(moveEnemy(Vector3.right));
}
if (rand == 3)
{
StartCoroutine(moveEnemy(Vector3.down));
}
if (rand == 0)
{
StartCoroutine(moveEnemy(Vector3.up));
}
}
private IEnumerator moveEnemy(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;
}
}
`
uj5u.com熱心網友回復:
但是當我試圖抓住它時,玩家仍然可以正常移動,但是敵人移動的空間比玩家多
我懷疑這是因為你讓敵人在玩家開始移動時立即移動,即使玩家還沒有到達他的目標位置。并且因為你沒有使用isMoving來阻止你的敵人同時運行多個協程(就像你和你的玩家一樣)所以當你按住一個鍵時,你的玩家開始移動但是你的敵人同時得到幾個動作而你的玩家協程仍在運行。
但也大部分時間保持在網格之間,更像是如果你在下棋,你把皇后的一半放在一個空間,另一半放在另一個空間。
同樣,我懷疑這是因為您同時moveEnemy運行了多個協程。所以當協程的第二個實體開始時,敵人在網格空間之間有一點點,因為協程的第一個實體還沒有完成。因此,即使協程的第二個實體僅將他移動了 1 個空格,他也會在空格之間開始,因此他將在空格之間結束。然后這個問題會根據協程運行的實體數量而復雜化。
有一堆的方法來解決這個問題,但我建議的方法是將值更改game_state到ENEMY_TURN只有一次您的播放機已經完成移動,并把它設定為PLAYER_TURN只有一次所有的敵人移動完。然后添加稱為BETWEEN_TURNS或類似的第三個狀態,并在玩家或敵人開始移動后立即設定game_state為BETWEEN_TURNS。然后在 期間不接受任何輸入BETWEEN_TURNS。這樣,您可以確保在開始下一個轉彎之前完成一個完整的轉彎,并且不會同時移動物體(除非這是您想要的,在這種情況下您需要不同的解決方案)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/389452.html
