0
votes

I have a test 2D game where my player moved from left to right and when he reached the end of the screen it would just transform on the other side. I had a change of heart and made my player move diagonally. It did work, but I have no idea how to make the player stop when it hits the end of the screen. I don't want it to transform on the other side, but rather just stop. So far all my results are either some glitching on the edges or not stopping at all. I have provided my PlayerController script. Right now my player moves diagonally and he will just continue after the edge of the screen. If anyone can assist me I would be very grateful. I never thought I will deal with diagonal movement, but I really want to learn how to do it.

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


public class PlayerController : MonoBehaviour {

    public float speed = 7;
    public float speedy = 7;

    public event System.Action OnPlayerDeath;
    float screenHalfWidthInWorldUnits;
    Rigidbody2D rb;

    void Start () {
        rb = GetComponent<Rigidbody2D>();
        float halfPlayerWidth = transform.localScale.x / 2f;
        screenHalfWidthInWorldUnits = Camera.main.aspect * Camera.main.orthographicSize;
    }

    void Update()
    {
        float inputX = Input.GetAxisRaw("Horizontal");
        float velocity = inputX * speed;
        transform.Translate(Vector2.right * velocity * Time.deltaTime); 
    }


    public void MoveRight()
    {
        rb.velocity = new Vector2(speed, speedy);
    }

    public void MoveLeft()
    {
        rb.velocity = new Vector2(-speed, -speedy);
    }


    public void Stop()
    {
        rb.velocity =  Vector2.zero;
    }

    void OnTriggerEnter2D(Collider2D triggerCollider)
    {
        if (triggerCollider.tag =="Box")
        {
            if (OnPlayerDeath != null)
            {
                OnPlayerDeath();
            }
            Destroy(gameObject);
        }
    }
}
1
Do you want to destroy player when reach to edge? - MGDroid
Why not just create colliders where you want to limit the player? - Ian H.
@MGDroid No, I just want him to stop. It worked fine when it was left or right, but with diagonal, I am missing something. - TheNewbie
Quick question, why are you moving the player with transform.Translate instead of using your methods MoveRight() and MoveLeft()? (This would currently ignore physics objects, such as colliders.) - Ian H.
Would it be possible to add a short video/gif of the situation and the problem? I am kinda having a hard time to imagine what is going on. - Ian H.

1 Answers

1
votes

You can check if the player is at what you define as the border of the map.

If you check this for the x and y axis respectively, you can then lock his x or y axis to the border and not further.

Here is an example of a script I made earlier that does that.

If I understand you correctly you would like to be able to move diagonally. In my sample script below you can move both straight and diagonally, you can also warp between the edges or stop at the edges as you spoke of wanting to.

This script is a bit more advanced than what you need probably, so let me know if something about it confuses you.

Please note that if you set the boolean _ShouldWarp to false he will stop at the border, otherwise he will warp from edge to edge of the map.

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

public class Player : MonoBehaviour
{

    public float _Speed = 5f;
    public WorldBounds _WorldBounds;
    public bool _ShouldWarp; //If _ShouldWarp is false, will block players movement instead.

    void Update()
    {
        Move();
        WarpIfAtBoundary();
    }

    void Move()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
        transform.Translate(Vector3.up * Time.deltaTime * _Speed * vertical);
    }

    void WarpIfAtBoundary()
    {
        //X Axis
        //If player is at positive X boundary
        if (transform.position.x > (_WorldBounds.xPlus + _WorldBounds.xBuffer))
        {
            if (_ShouldWarp) //Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(_WorldBounds.xMinus, transform.position.y, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(_WorldBounds.xPlus + _WorldBounds.xBuffer, transform.position.y, transform.position.z);
            }
        }
        //Else if player is at negative X boundary
        else if (transform.position.x < (_WorldBounds.xMinus - _WorldBounds.xBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(_WorldBounds.xPlus, transform.position.y, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(_WorldBounds.xMinus - _WorldBounds.xBuffer, transform.position.y, transform.position.z);
            }
        }

        //Y Axis
        //If player is at positive Y boundary
        if (transform.position.y > (_WorldBounds.yPlus + _WorldBounds.yBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus + _WorldBounds.yBuffer, transform.position.z);
            }
        }
        //Else if player is at negative Y boundary
        else if (transform.position.y < (_WorldBounds.yMinus - _WorldBounds.yBuffer))
        {
            if (_ShouldWarp)//Teleport/warp player is set to enabled
            { 
                transform.position = new Vector3(transform.position.x, _WorldBounds.yPlus, transform.position.z);
            }
            else //Otherwise keep player in border position
            {
                transform.position = new Vector3(transform.position.x, _WorldBounds.yMinus - _WorldBounds.yBuffer, transform.position.z);
            }
        }
    }
}

//Set as serializable so it displays correctly in Unity's inspector window.
[System.Serializable]
public class WorldBounds
{
    [Header("Bounds")]
    public float xMinus = -9.4f;
    public float xPlus = 9.4f;
    public float yMinus = -9.4f;
    public float yPlus = 9.4f;
    [Header("BufferZone")]
    public float xBuffer = 1f;
    public float yBuffer = 1f;
}

EDIT:

With your additions will I be able to assign the movement to my two buttons. One is up and right and the other is down and left.

        void Move()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        transform.Translate(Vector3.right * Time.deltaTime * _Speed * horizontal);
        transform.Translate(Vector3.up * Time.deltaTime * _Speed * horizontal);
    }

This should work to move diagonally left and down as well as up and right.

The change i made is to use the Horizontal input for both X and Y movement.

I don't need the warp. Just to step at the defined borders

You can set the Warp boolean to false or remove the warp parts from the code then :-), should work.