【问题标题】:Weird movement behaviour Unity2D C#奇怪的运动行为 Unity2D C#
【发布时间】:2016-04-23 11:35:08
【问题描述】:

我正在使用 C# 在 Unity 中制作一个基于回合的自上而下的 2D 地牢爬行者。我目前正在编写蝙蝠敌人跟随玩家的代码。除了一种奇怪的行为外,它运行良好。蝙蝠向 2 个方向移动 2 个方块,而不是向 1 个方向移动 1 个方块,但仅限于它的第一次移动。类似于骑士在国际象棋中的移动。请帮我解决这个问题。任何和所有建议表示赞赏。我的代码可能很糟糕而且过于复杂,但这是我的第一个游戏,所以请温柔。

敌人代码:

Vector3 currentPosition;
Vector3 nextPosition;
public GameObject playerObject;
public Transform[] wallArray;
bool canMove;
public Player thePlayer;

void Update()
{
    currentPosition = transform.position;
    Movement();    
}

void Movement()
{
    if (thePlayer.timeToMove == false)
    {
        if (playerObject.transform.position.x > currentPosition.x)
        {
            nextPosition.x = currentPosition.x + 1;
            canMove = false;
            foreach (Transform wall in wallArray)
            {
                if (wall.transform.position.Equals(nextPosition))
                {
                    nextPosition = currentPosition;
                    canMove = true;
                }
            }

            if (canMove)
            {
                if (playerObject.transform.position.y > currentPosition.y)
                {
                    nextPosition.y = currentPosition.y + 1;
                    foreach (Transform wall in wallArray)
                    {
                        if (wall.transform.position.Equals(nextPosition))
                        {
                            nextPosition = currentPosition;
                        }
                    }
                }

                if (playerObject.transform.position.y < currentPosition.y)
                {
                    nextPosition.y = currentPosition.y - 1;
                    foreach (Transform wall in wallArray)
                    {
                        if (wall.transform.position.Equals(nextPosition))
                        {
                            nextPosition = currentPosition;
                        }
                    }
                }
            }
            if (nextPosition == playerObject.transform.position)
            {
                nextPosition = currentPosition;
            }
            transform.position = nextPosition;
            thePlayer.timeToMove = true;
            Debug.Log("Leaving 'a'...");
            return;
        }

        if (playerObject.transform.position.x < currentPosition.x)
        {
            nextPosition.x = currentPosition.x - 1;
            canMove = false;
            foreach (Transform wall in wallArray)
            {
                if (wall.transform.position.Equals(nextPosition))
                {
                    nextPosition = currentPosition;
                    canMove = true;
                }
            }
            if (canMove)
            {
                if (playerObject.transform.position.y > currentPosition.y)
                {
                    nextPosition.y = currentPosition.y + 1;
                    foreach (Transform wall in wallArray)
                    {
                        if (wall.transform.position.Equals(nextPosition))
                        {
                            nextPosition = currentPosition;
                        }
                    }
                }

                if (playerObject.transform.position.y < currentPosition.y)
                {
                    nextPosition.y = currentPosition.y - 1;
                    foreach (Transform wall in wallArray)
                    {
                        if (wall.transform.position.Equals(nextPosition))
                        {
                            nextPosition = currentPosition;
                        }
                    }
                }
            }
            if (nextPosition == playerObject.transform.position)
            {
                nextPosition = currentPosition;
            }
            transform.position = nextPosition;
            thePlayer.timeToMove = true;
            Debug.Log("Leaving 'b'...");
            return;
        }

        if (playerObject.transform.position.x == currentPosition.x)
        {
            if (playerObject.transform.position.y > currentPosition.y)
            {
                nextPosition.y = currentPosition.y + 1;
                foreach (Transform wall in wallArray)
                {
                    if (wall.transform.position.Equals(nextPosition))
                    {
                        nextPosition = currentPosition;
                    }
                }
            }

            if (playerObject.transform.position.y < currentPosition.y)
            {
                nextPosition.y = currentPosition.y - 1;
                foreach (Transform wall in wallArray)
                {
                    if (wall.transform.position.Equals(nextPosition))
                    {
                        nextPosition = currentPosition;
                    }
                }
            }
            if (nextPosition == playerObject.transform.position)
            {
                nextPosition = currentPosition;
            }
            transform.position = nextPosition;
            thePlayer.timeToMove = true;
            Debug.Log("Leaving 'c'...");
            return;
        }            
    }

玩家代码:

// Movement variables
public Vector3 playerCurrentPosition;
Vector3 nextPosition;
public Transform[] wallArray;
public bool timeToMove;
bool movingToWall;

void Start()
{
    // When we start we can move
    timeToMove = true;
}

void Update()
{
    // Update current position variable
    playerCurrentPosition = transform.position;
    // Move
    Movement();
}

// Movement
void Movement()
{
    // If it's time to move
    if (timeToMove)
    {
        // If right arrow key pressed
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            // Set position to move to
            nextPosition.x = playerCurrentPosition.x + 1;
            // Check wall array
            foreach (Transform wall in wallArray)
            {
                // If the wall we are checking is in the space we want to move to
                if (wall.transform.position.Equals(nextPosition))
                {
                    // We are moving into a wall
                    movingToWall = true;
                }
            }

            // If we are moving into a wall
            if (movingToWall)
            {
                // Don't move
                nextPosition = playerCurrentPosition;
                // Set position
                transform.position = nextPosition;
                // It's time to move again
                timeToMove = true;
                // We're not moving into a wall anymore
                movingToWall = false;
            }
            // If we're not moving into a wall
            else
            {
                // Move
                transform.position = nextPosition;
                // It's no longer time to move
                timeToMove = false;
            }            
        }
        // If left arrow key pressed
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            // Set position we want to move to
            nextPosition.x = playerCurrentPosition.x - 1;
            // Check wall array
            foreach (Transform wall in wallArray)
            {
                // If the wall we are checking is in the space we want to move to
                if (wall.transform.position.Equals(nextPosition))
                {
                    // We are moving into a wall
                    movingToWall = true;
                }
            }
            // If we are moving into a wall
            if (movingToWall)
            {
                // Don't move
                nextPosition = playerCurrentPosition;
                // Set position
                transform.position = nextPosition;
                // We can move again
                timeToMove = true;
                // We are no longer moving into a wall
                movingToWall = false;
            }
            // If we are not moving into a wall
            else
            {
                // Move
                transform.position = nextPosition;
                // It is no longer time to move
                timeToMove = false;
            }
        }
        // If up arrow pressed
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            // Set position to move to 
            nextPosition.y = playerCurrentPosition.y + 1;
            // Check wall array
            foreach (Transform wall in wallArray)
            {
                // If wall we are checking is in space we want to move to
                if (wall.transform.position.Equals(nextPosition))
                {
                    // We are moving into a wall
                    movingToWall = true;
                }
            }
            // If we are moving into a wall
            if (movingToWall)
            {
                // Don't move
                nextPosition = playerCurrentPosition;
                // Set position
                transform.position = nextPosition;
                // We can move again
                timeToMove = true;
                // No longer moving into wall
                movingToWall = false;
            }
            // If we are not moving into a wall
            else
            {
                // Move
                transform.position = nextPosition;
                // It is no longer time to move
                timeToMove = false;
            }
        }
        // If down arrow pressed
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            // Set position to move to
            nextPosition.y = playerCurrentPosition.y - 1;
            // Check wall array
            foreach (Transform wall in wallArray)
            {
                // If wall we are checking is in the space we want to move to
                if (wall.transform.position.Equals(nextPosition))
                {
                    // We are moving into a wall
                    movingToWall = true;
                }
            }
            // If we are moving into a wall
            if (movingToWall)
            {
                // Don't move
                nextPosition = playerCurrentPosition;
                // Set position
                transform.position = nextPosition;
                // We can move again
                timeToMove = true;
                // No longer moving into a wall
                movingToWall = false;
            }
            // If we are not moving into a wall
            else
            {
                // Move
                transform.position = nextPosition;
                // No longer time to move
                timeToMove = false;
            }
        }
    }       
}

【问题讨论】:

  • @JoeBlow 这与浮点数搞砸了有关,但我已经按比例放大了精灵,所以我可以使用整数。这个问题与我假设的糟糕的编码有关。
  • @JoeBlow 玩家的动作现在很完美

标签: c# unity3d 2d game-engine


【解决方案1】:

您的问题是否有可能是,您应该使用分离代码而您没有?你的代码是这样的:

void Movement()
{
if (Player.timeToMove == false)
  {
  if (playerObject.transform.position.x > currentPosition.x)
    {
    // huge amount of code
    }

  if (playerObject.transform.position.x < currentPosition.x)
    {
    // huge amount of code
    }

  if (playerObject.transform.position.x == currentPosition.x)
    {
    // huge amount of code
    }     

  }
}

其实应该是这样的吧?

void Movement()
{
if (Player.timeToMove == false)
  {
  if (playerObject.transform.position.x > currentPosition.x)
    {
    // huge amount of code
    Debug.Log("Leaving 'a'...");
    return;
    }

  if (playerObject.transform.position.x < currentPosition.x)
    {
    // huge amount of code
    Debug.Log("Leaving 'b'...");
    return;
    }

  if (playerObject.transform.position.x == currentPosition.x)
    {
    // huge amount of code
    Debug.Log("Leaving 'c'...");
    return;
    }     

  }
}

我建议尝试一下。


请注意,您确实需要引入一些函数来简化您的代码。你的代码段落是这样的......

foreach (Transform wall in wallArray)
    if (wall.transform.position.Equals(nextPosition))
        {
        movingToWall = true;
        }

应该是一个更像这样的函数:

private bool IsThisAWall(Vector3 p)
  {
  foreach (Transform wall in wallArray)
    if (wall.transform.position.Equals(p))
        {
        return true;
        }
  return false;
  }

然后你会像这样使用它。你会有一个变量“possibleNewPosition”。你会说...

possibleNewPosition = currentPosition + 1; if ( IsThisAWall(possibleNewPosition) ) Debug.Log("既然是墙,什么都不做"); 别的 currentPosition = possibleNewPosition;

你这样做很常见,你有一个变量“可能......”某事或其他!

您确实需要及时执行此操作。 (不要忘记在编程中,任何例程都不应超过 5 或 6 行代码。你的 Movement 等调用太长了。)

【讨论】:

  • 我使用了静态,因为我认为这是让其他脚本访问变量的方式?否则,我将如何允许 Bat.cs 和 Player.cs 都与 timeToMove 变量交互?编辑:对不起,我想我现在明白你的意思了。
  • 正在使用公共播放器thePlayer;比 public GameObject playerObject;?
  • 我现在已经改变了所有的静态变量。没有行为差异。
  • 完成。再次感谢您。
  • 嗨,我又来了。我应该只添加调试和返回调用还是我错过了什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多