1

I want my character to stop everytime I hit the edge of the screen/canvas, so I added some rectangle at the end of each border(with a 2d collider), so my character will collide with it and stop moving in that direction, but the thing is that if, for example, I hit the left rectangle and I still press A to move left, my character strarts 'shaking'. I tried to solve that by setting the speed of it to 0 when it hits the certain rectangle, but then I cant move at all in any directions after I get to the edge.

public class CharacterMovement : MonoBehaviour {

public float speed = 5f;



void Start() {


}


void Update() {
    if (Input.GetKey(KeyCode.W))
    {
        transform.Translate(0, speed * Time.deltaTime, 0);
    }
    if (Input.GetKey(KeyCode.S))
    {
        transform.Translate(0, -speed * Time.deltaTime, 0);
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.Translate(-speed * Time.deltaTime, 0, 0);
    }
    if (Input.GetKey(KeyCode.D))
    {
        transform.Translate(speed * Time.deltaTime, 0, 0);
    }
}


void OnCollisionEnter2D(Collision2D col)
{
    if (col.gameObject.name == "offscreen")
    {
        speed = 0f;
    }else
    {
        speed = 5f;
    }
}

}

Alex Arek
  • 57
  • 7

3 Answers3

1

I'm not familiar with mono behavior methods but I think the issue is when you're equal to the edge it stays true for the next update. Since nothing makes it false, the speed remains 0.

Try putting the check within your update method for each key that's pressed.

Something like

if (key ==moveleft)
{
    if(sprite.leftedge>edgeoftheleftscreen+1)
         Sprite.moveleft();   
}
if(key==moveright)
{
    if(sprite.rightedge<edgeoftherightscreen-1)
         Sprite.moveright();
}

Hope this helps.

Rye
  • 90
  • 6
1

Shaking happens, because you're just putting your character inside border's collider and physics is trying to take him back. I'm not really fan of relying on colliders in cases like that. Let's say you set your character very high speed or your frames dropped and your character may appear on the other side of your collider or at least your shaking will occur again. What i would do is checking if point:

deltaPos = speed * Time.deltaTime
transform.position + deltaPos

is out of the screen. If it is you should clamp your deltaPos to distance to the screen's border.

Smith
  • 319
  • 2
  • 12
1

Try disabling the individual inputs when the character collides with the sides, that way you can move to the other side after touching the sides, instead of setting speed to 0.

The problem you currently have is that when you collide with the side, you set the speed to 0 while you are still touching the side, and you can't move away from the side that you are constantly touching, because the speed is 0.

public class CharacterMovement : MonoBehaviour {

    public float speed = 5f;

    public bool touchingLeft;
    public bool touchingRight;


    void Start() {


    }


    void Update() {
        if (Input.GetKey(KeyCode.W))
        {
            transform.Translate(0, speed * Time.deltaTime, 0);
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.Translate(0, -speed * Time.deltaTime, 0);
        }
        if (Input.GetKey(KeyCode.A) && !touchingLeft)
        {
            transform.Translate(-speed * Time.deltaTime, 0, 0);

            touchingRight = false;
        }
        if (Input.GetKey(KeyCode.D) && !touchingRight)
        {
            transform.Translate(speed * Time.deltaTime, 0, 0);

            touchingLeft = false;
        }
    }


    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.name == "leftOffscreen")
        {
            touchingLeft = true;
        } 

        if else (col.gameObject.name == "rightOffscreen")
        {
            touchingRight = true;
        }
    }
}

However, there are more effective ways to do this, but I feel like this works well with your existing code.

If the screen resizes though, you would probably want to clamp the x-value of the player to the x-values of the edge of the screen.

Hope it helps

Eric Bishop
  • 469
  • 5
  • 13