最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How to flip character up and down - Stack Overflow

programmeradmin0浏览0评论

I'm trying to make an google snake like game and I got the movement all right but it doesn't flip up and down. If I click A and D on my keyboard it flips left and right, but if I click W or S it flips left or right for some reason.

Here is my code:

using System.Collections; using System.Collections.Generic; using UnityEngine;

public class snakemovement : MonoBehaviour 
{
    private Vector2 _direction = Vector2.right; bool facingRight = true;
 
    void Update() 
    {
        if (Input.GetKeyDown(KeyCode.W)) 
        {
            _direction = Vector2.up; Flip(); 
        } 
        else if (Input.GetKeyDown(KeyCode.S)) 
        { 
            _direction = Vector2.down; Flip(); 
        }
        else if (Input.GetKeyDown(KeyCode.D)) 
        { 
            _direction = Vector2.right; Flip(); 
        }
        else if (Input.GetKeyDown(KeyCode.A)) 
        { 
            _direction = Vector2.left; Flip(); 
        } 
    }

    private void FixedUpdate()
    {
        this.transform.position = new Vector3(
            Mathf.Round(this.transform.position.x) + _direction.x,
            Mathf.Round(this.transform.position.y) + _direction.y,
            0.0f);
    }

    void Flip()
    {
        Vector3 currentScale = gameObject.transform.localScale;
        currentScale.x *= -1;
        gameObject.transform.localScale = currentScale;

        facingRight = !facingRight;
    }
}

I'm trying to make an google snake like game and I got the movement all right but it doesn't flip up and down. If I click A and D on my keyboard it flips left and right, but if I click W or S it flips left or right for some reason.

Here is my code:

using System.Collections; using System.Collections.Generic; using UnityEngine;

public class snakemovement : MonoBehaviour 
{
    private Vector2 _direction = Vector2.right; bool facingRight = true;
 
    void Update() 
    {
        if (Input.GetKeyDown(KeyCode.W)) 
        {
            _direction = Vector2.up; Flip(); 
        } 
        else if (Input.GetKeyDown(KeyCode.S)) 
        { 
            _direction = Vector2.down; Flip(); 
        }
        else if (Input.GetKeyDown(KeyCode.D)) 
        { 
            _direction = Vector2.right; Flip(); 
        }
        else if (Input.GetKeyDown(KeyCode.A)) 
        { 
            _direction = Vector2.left; Flip(); 
        } 
    }

    private void FixedUpdate()
    {
        this.transform.position = new Vector3(
            Mathf.Round(this.transform.position.x) + _direction.x,
            Mathf.Round(this.transform.position.y) + _direction.y,
            0.0f);
    }

    void Flip()
    {
        Vector3 currentScale = gameObject.transform.localScale;
        currentScale.x *= -1;
        gameObject.transform.localScale = currentScale;

        facingRight = !facingRight;
    }
}
Share Improve this question edited 2 days ago marc_s 755k184 gold badges1.4k silver badges1.5k bronze badges asked 2 days ago Mr penguinMr penguin 193 bronze badges New contributor Mr penguin is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1
  • 3 I think some code for changing currentScale.y is missing in the Flip() function? – Luuk Commented 2 days ago
Add a comment  | 

3 Answers 3

Reset to default 1

Also if you press D key various times the character will flip left and right even if still advancing on the same direction.

You should add to flip a parameter, for example a Vector2 one with the desired directions of the flip instead of using an alternating strategy.

Define Flip as this:

void Flip(Vector2 direction)
{
    Vector3 currentScale = gameObject.transform.localScale;
    if (direction.x != 0f) currentScale.x *= direction.x;
    if (direction.y != 0f) currentScale.y *= direction.y;
    gameObject.transform.localScale = currentScale;  
}

Call to Flip with:

Flip(_direction);

The facingRight variable is useless as you use it. Also you should perform all in Update instead of using FixedUpdate because you are not using physics there. And whistl you will get a variable-velocity moving character you should multiply by Time.deltaTime instead.

Your Flip method seems to mirror the character across the y axis if I understand it correctly. Since you are calling the Flip method every time the W or S key gets pressed, the character will be mirrored across the y axis (flip left or right) every time one of those keys gets pressed.

I am not very experienced with Unity but based on your code I assume that you can set gameObject.transform.localScale.y to -gameObject.transform.localScale.y to mirror the character across the x axis.

So to fix your problem you should rename your Flip method to FlipHorizontal and create a new method called FlipVertical. The FlipVertical method could look something like this:

private void FlipVertical()
{
    Vector3 currentScale = gameObject.transform.localScale;
    currentScale.y *= -1;
    gameObject.transform.localScale = currentScale;
}

I would also suggest not making the method toggle the orientation of the character but instead setting it based on a parameter to make the code more readable and reliable.

private enum Orientation
{
    Left,
    Right,
    Up,
    Down
}

private void SetOrientation(Orientation orientation)
{
    Vector3 currentScale = gameObject.transform.localScale;

    switch(orientation)
    {
        case Orientation.Left or Orientation.Right:
            currentScale.x = Orientation.Right ? 1 : -1; // Multiply by a size variable if you want to change the size of your character
            break;
        case Orientation.Up or Orientation.Down:
            currentScale.y = Orientation.Up ? 1 : -1;
            break;
        default:
            break;
    }

    gameObject.transform.localScale = currentScale;
}

And then just call the method like this

SetOrientation(Orientation.Right); // Or any other orientation

Your function is missing how to handle the vertical y axis, as pointed in the comments; other that it's just flipping without checking if it's already on the right direction. You can use one of multiple approaches, like passing to Flip() a key value to handle each axis like:

void Update()
{
    if (Input.GetKeyDown(KeyCode.W))
    {
        _direction = Vector2.up; Flip(KeyCode.W);
    }

    else if (Input.GetKeyDown(KeyCode.S))
    {
        _direction = Vector2.down; Flip(KeyCode.S);
    }

    else if (Input.GetKeyDown(KeyCode.D))
    {
        _direction = Vector2.right; Flip(KeyCode.D);
    }

    else if (Input.GetKeyDown(KeyCode.A))
    {
        _direction = Vector2.left; Flip(KeyCode.A);
    }
}


void Flip(key)
{
    switch (key)
    {
        case KeyCode.W:
            if (!facingUp)   {
                Vector3 currentScale = gameObject.transform.localScale;
                currentScale.y *= -1;
                gameObject.transform.localScale = currentScale;

                facingUp = true;
            }
            break;
        case KeyCode.A:
            if (facingRight)   {
                Vector3 currentScale = gameObject.transform.localScale;
                currentScale.x *= -1;
                gameObject.transform.localScale = currentScale;

                facingRight = false;
            }
            break;
        case KeyCode.S:
            if (facingUp)   {
                Vector3 currentScale = gameObject.transform.localScale;
                currentScale.y *= -1;
                gameObject.transform.localScale = currentScale;

                facingUp = false;
            }
            break;
        case KeyCode.D:
            if (!facingRight)   {
                Vector3 currentScale = gameObject.transform.localScale;
                currentScale.x *= -1;
                gameObject.transform.localScale = currentScale;

                facingRight = true;
            }
            break;
        default:
            break;
    }
}

Another option is to split Flip into two separate functions, say, FlipVertically() and FlipHorizontally(). Something along these lines:

void Update()
{
    if (Input.GetKeyDown(KeyCode.W))
    {
        _direction = Vector2.up; FlipVertically();
    }

    else if (Input.GetKeyDown(KeyCode.S))
    {
        _direction = Vector2.down; FlipVertically();
    }

    else if (Input.GetKeyDown(KeyCode.D))
    {
        _direction = Vector2.right; FlipHorizontally();
    }

    else if (Input.GetKeyDown(KeyCode.A))
    {
        _direction = Vector2.left; FlipHorizontally();
    }
}

void FlipHorizontally()
{
    Vector3 currentScale = gameObject.transform.localScale;
    currentScale.x *= -1;
    gameObject.transform.localScale = currentScale;

    facingRight = !facingRight;
}
void FlipVertically()
{
    Vector3 currentScale = gameObject.transform.localScale;
    currentScale.y *= -1;
    gameObject.transform.localScale = currentScale;

    facingUp = !facingUp;
}

Ultimately the choice is yours, but remember to include another bool if you need to store the facing of your character or better, try to save its state in an enum. That can be simple as

enum direction
{
    UP,
    DOWN,
    LEFT,
    RIGHT
}

and you replace the various bools with it

发布评论

评论列表(0)

  1. 暂无评论