简体   繁体   English

奇怪的运动行为Unity2D C#

[英]Weird movement behaviour Unity2D C#

I'm making a turn-based top-down 2D dungeon crawler in Unity with C#. 我正在使用C#在Unity中制作一个基于回合的自上而下的2D地牢爬虫。 I'm currently programming the code for the bat enemy to follow the player. 我目前正在编程蝙蝠敌人的代码以跟随玩家。 It's working well except for one weird behavior. 除一种奇怪的行为外,它运行良好。 The bat moves in 2 directions by 2 blocks instead of in 1 direction by 1 block, but only for it's first movement. 蝙蝠在2个方向上移动2块,而不是在1个方向上移动1块,但这仅是第一次移动。 Similar to the movement the knight makes in chess. 类似于骑士下棋的动作。 Please help me figure this out. 请帮我解决这个问题。 Any and all suggestions appreciated. 任何和所有建议表示赞赏。 My code is probably awful and overly complicated, but this is my first game so please be gentle. 我的代码可能很糟糕且过于复杂,但这是我的第一个游戏,因此请保持谨慎。

Enemy code: 敌人代码:

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;
        }            
    }

Player code: 播放器代码:

// 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;
            }
        }
    }       
}

Is there a chance that your problem is, you should be using breakaway code and you are not? 是否有可能是您的问题所在,您应该使用脱离代码而不是? Your code is like this: 您的代码是这样的:

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
    }     

  }
}

In fact, should it be like this ? 其实应该是这样吗?

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;
    }     

  }
}

I suggest trying that. 我建议尝试一下。


Note, you truly need to introduce some functions to simplify your code. 注意,您确实需要引入一些函数来简化代码。 Your code passage like this ... 您的代码段落是这样的...

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

should be a function more like this: 应该是这样的函数:

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

you would then use it sort of like this. 然后,您将使用这种方式。 you'd have a variable "possibleNewPosition". 您将拥有一个变量“ possibleNewPosition”。 you'd say ... 你会说...

possibleNewPosition = currentPosition + 1; 可能的NewPosition = currentPosition + 1; if ( IsThisAWall(possibleNewPosition) ) Debug.Log("doing nothing since it's a wall"); if(IsThisAWall(possibleNewPosition))Debug.Log(“因为它是墙所以什么也不做”); else currentPosition = possibleNewPosition; 否则currentPosition =可能的NewPosition;

It's very common that you do that, you have a variable "possible ..." something or other! 这样做是很常见的,您可能会在变量“ possible ...”中添加其他内容!

You really need to do this in time. 您确实需要及时执行此操作。 (Don't forget in programming, no routine should ever be longer than say 5 or 6 lines of code. Your Movement etc calls are tremendously too long.) (不要忘记在编程中,任何例程的时间都不应超过说5或6行代码。您的Movement等调用非常长。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM