My camera won't move enymore when I put my mouse at the edge of the screen. I'm not sure how to fix it?

hello, so in my project I have a camera that move with WASD and when the mouse is on the edge of the screen and it worked very well. But my project is kind of a city builder so to be able to place building I make an object follow the cursor, sice then the camera doesn’t move when the mouse is on the edge of the screenno matter what.

I think it might be because of my input system but I’m not sure.

camera movement script :

public class MoveCam : MonoBehaviour
{
    [SerializeField] private float speed;
    [SerializeField] private int screenEdge;
    private Vector2 _moveInput;
    private Rigidbody2D _rb;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        _rb.linearVelocity = _moveInput.normalized * speed;
    }

    public void Move(InputAction.CallbackContext ctx)
    {
        _moveInput = ctx.ReadValue<Vector2>();
    }
    
    public void EdgeMove(InputAction.CallbackContext ctx)
    {
        if (ctx.ReadValue<Vector2>().y < screenEdge)
        {
            _moveInput.y = -1f;
            print("work");
        }
        else if (ctx.ReadValue<Vector2>().y > Screen.height - screenEdge)
        {
            _moveInput.y = +1f;
            print("work");
        }
        
        if (ctx.ReadValue<Vector2>().x < screenEdge)
        {
            _moveInput.x = -1f;
            print("work");
        }
        else if (ctx.ReadValue<Vector2>().x > Screen.width - screenEdge)
        {
            _moveInput.x = +1f;
            print("work");
        }

        if (ctx.ReadValue<Vector2>().y > screenEdge && ctx.ReadValue<Vector2>().y < Screen.height - screenEdge &&
            ctx.ReadValue<Vector2>().x > screenEdge && ctx.ReadValue<Vector2>().x < Screen.width - screenEdge)
        {
            _moveInput.x = 0f;
            _moveInput.y = 0f;
        }
    }
}

placement script :

public class Placement : MonoBehaviour
{
    [SerializeField] private Batiment batiment;
    [SerializeField] private bool plassable;
    private Camera mainCam;
    private Collider2D collider;
    [SerializeField] private List<GameObject> bloking = new List<GameObject>();
    public Material placementMat;
    private Transform placementPosition;
    private InputAction mousePos;
    private InputAction button;
    
    public TypeMana costMana1;
    public TypeMana costMana2;
    public TypeMana costMana3;
    public int manaAmount1 = 0;
    public int manaAmount2 = 0;
    public int manaAmount3 = 0;
    
    [SerializeField] private playerStat player;

    private void Awake()
    {
        player = GameObject.Find("player").GetComponent<playerStat>();
    }
    
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        mainCam = Camera.main;
        collider = GetComponent<Collider2D>();
        placementPosition = GetComponent<Transform>();
        placementMat = GetComponent<Renderer>().material;
        mousePos = InputSystem.actions["mousePosBatiment"];
        button = InputSystem.actions["leftClickPlaceBat"];
    }

    // Update is called once per frame
    void Update()
    {
        FollowMousePosition();
        
        if (bloking.Count != 0 || EnoughMana())
        {
            print(bloking.Count);
            print(EnoughMana());
            plassable = false;
            placementMat.SetColor("_Color", Color.red);
        }
        else
        {
            print("plassable");
            plassable = true;
            placementMat.SetColor("_Color", Color.green);
        }

        if (button.triggered)
        {
            Place();
        }
    }

    private bool EnoughMana()
    {
        bool mana1 = false;
        bool mana2 = false;
        bool mana3 = false;
        if (costMana1 != TypeMana.None)
        {
            if (player.getMana(costMana1) - manaAmount1 < 0)
            {
                mana1 = true;
            }
            else
            {
                mana1 = false;
            }
        }
        else
        {
            mana1 = false;
        }

        if (costMana2 != TypeMana.None)
        {
            if (player.getMana(costMana2) - manaAmount2 < 0)
            {
                mana2 = true;
            }
            else 
            {
                mana2 = false;
            }
        }
        else
        {
            mana2 = false;
        }

        if (costMana3 != TypeMana.None)
        {
            if (player.getMana(costMana3) - manaAmount3 < 0)
            {
                mana3 = true;
            }
            else
            {
                mana3 = false;
            }
        }
        else
        {
            mana3 = false;
        }

        if (mana1 || mana2 || mana3)
        {
            return true;
        }

        return false;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Batiment"))
        {
            bloking.Add(collision.gameObject);
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Batiment"))
        {
            bloking.Remove(collision.gameObject);
        }
    }

    public void Place()
    {
        if (plassable)
        {
            print("performed");
            Payment();
            Instantiate(batiment, placementPosition.position, placementPosition.rotation);
            Destroy(gameObject);
        }
    }

    private void Payment()
    {
        if (costMana1 != TypeMana.None)
        {
            player.subMana(costMana1,manaAmount1);
        }
        
        if (costMana2 != TypeMana.None)
        {
            player.subMana(costMana2,manaAmount2);
        }
        
        if (costMana3 != TypeMana.None)
        {
            player.subMana(costMana3,manaAmount3);
        }
    }

    private void FollowMousePosition()
    {
        placementPosition.position = GetWorldPosition();
    }
    
    private Vector2 GetWorldPosition()
    {
        return mainCam.ScreenToWorldPoint(mousePos.ReadValue<Vector2>());
    }
}

my input system :


I’ve tryed to put them on the same input but that didn’t fix enything, I don’t really know what to try, so eny idea/tips ?
thank in advance for your wisdom.

well, one thing id change is stop using the same comment for each choice, I see print “work” at least 4 times, for x/y choices, how will you know which one it picked if you just print the same thing?

Other things, you’ve assumingly read into Move when the mouse has moved? so why are you reading it again, and again, and again?? read it once, check the value you got. what differentiates between Move and EdgeMove?

move(InputAction.CallbackContext ctx) : move the camera when WASD are pressed
edgeMove(InputAction.CallbackContext ctx) : move the camera when the mouse is within one of the boundaries set for the edge of the screen

the prints are there to check if the script play and enter the if... statement (witch it does) that why they’re the same.

this feels like a lot of hassle, when cinemachine exists..

so what has your debugging shown you so far?

I do use cinemachine but not to move the camera (I have another script to zoom so it would mess things up).

for the moment it shows that my when the mouse is within one of the boundaries set for the edge of the screen, it does trigger and enter the if{...} statement and print “work” but it doesn’t move the camera.

You asked this or very similar camera motion related questions before here and here.

That’s 1.5 months of little to no progress apparently. You keep running out of ideas “to try” with code that’s very simple. Apply the scientific method. Understand every bit of the code you implement. Implement it in a way that you don’t repeat the same code in multiple places because this makes it difficult to reason about and to change the code.

You know how to log. Now dig a little deeper and learn to debug code. This will be very instructive as it will quickly inform you what is working and what isn’t, and most importantly why - since you see all the variables in context. Granted, for camera motion it’s a bit tricky since this needs analyzing over multiple frames or even input over multiple frames, but conditional breakpoints are going to help you here.

What you should not do is to change some code based on a hunch. This would be a huge waste of time. You need to form an understanding why things happen to fail, especially when they worked before.

I’m saying this because you completely changed the way you handle input for no apparent reason. I already gave you the answer to the 3-times input event execution, it would have been a straightforward fix. So if you keep changing the way your code works on a fundamental level you’re very commonly introduce different behaviour that you have to chase down.

So implement one thing, and one thing only, so that it works perfectly. Input that calls the Place() method. Put that in a script of its own and don’t touch it again. Do this for every functional piece of code on a small but reasonable scope. That way you build the logic on top of functional and tested pieces. That will have you build the functionality on top of a stable foundation. This is a very important programming concept that’s relatively easy to implement.

Then you aren’t using Cinemachine properly. If you set the position of Camera.main that’s bypassing Cinemachine. You give Cinemachine a target object that it follows, which you then move.

the first link is when I had just started and couldn’t find tutorial that would work for me (they were using the old input system while I’m using the new, and the other link is a mess of many different problems that I manage to fix exept for the camera one (that why I made another post).

I was very occupied for like a month and couldn’t work on it. I’m not really running out of ideas, it’s more like a turn of phrase that I use to say that I’ve tryed many/different things before asking for help.

The thing is, I do not change some code based on a hunch and i do understand why and how my code work, but here the thing is that I can’t understand why it stopped working when I’ve never even touched the edgeMove(InputAction.CallbackContext ctx) ever since it started working.

Your solution for the 3-times input worked and I wont take that away from you, but there were other problems, namely the fact that it triggered still when the object was disable or not even in the scene so I had to come up with somthing else.

The thing is I tryed to do it this way but since I’ve got 2 ways to move the camera around it would cause some “conflict” between the keys way of mouvement and the mouse way of mouvement, plus the zoom would have made the target object bigger or smaller.

edit : I would like to add that I still use cinemachine to have a bounding shape so the player doesn’t get lost somewhere they can’t do enything.

(I’m replying late because I live in europe and I supose you’re in america)

This sounds very much like a recipe for disaster.

May I ask why ?

Alright, I’ve fixed it. all I had to do was to delete and recreate the unity event, I must have done something wrong when I created the other pointer input.

because you have 2 things to fight over the same work.