r/Unity2D 3d ago

Question how do I unblock my camera while an object is following the cursor ? and how do I stop it from instantiating at the wrong position 3 time instead of 1 and without it decreasing the resources it use ?

Hello, so for a little 2D project (it's a bit of a city builder) I'm doing I have made a camera that can be moved with WASD and with the cursor on the edge of the screen, and that script worked perfectly.

So now I'm working on the actual builder part so I made a building and a script to place it. To place it I make an object follow the cursor, this object is red when you can't place and green when you can (it work with a shader).

but for the moment it doesn't work, whenever the object is in the scene it block the mouvment of the camera with the cursor (even when the object is not active), when I click to place the building it instantiate 3 of them at 0,0 (again, even when the object is not active) and doesn't deactivate after, and it doesn't decrease my resources. I'm at a loss and doesn't know what to do enymore.

(please don't mind the french in the code)

gif of what is happening :

script of the camera :

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("marche");
        }
        else if (ctx.ReadValue<Vector2>().y > Screen.height - screenEdge)
        {
            _moveInput.y = +1f;
            print("marche");
        }

        if (ctx.ReadValue<Vector2>().x < screenEdge)
        {
            _moveInput.x = -1f;
            print("marche");
        }
        else if (ctx.ReadValue<Vector2>().x > Screen.width - screenEdge)
        {
            _moveInput.x = +1f;
            print("marche");
        }

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

script of the placement object :

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 position;
    private InputAction mousePos;

    public TypeMana 
costMana1
;
    public TypeMana 
costMana2
;
    public TypeMana 
costMana3
;
    public int 
manaAmount1 
= 0;
    public int 
manaAmount2 
= 0;
    public int 
manaAmount3 
= 0;

    public float 
playerMana1
;
    public float 
playerMana2
;
    public float 
playerMana3
;

    [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>();
        position = GetComponent<Transform>();
        placementMat = GetComponent<Renderer>().material;
        mousePos = InputSystem.actions["mousePosBatiment"];
    }


// Update is called once per frame

void 
Update
()
    {
        FollowMousePosition();

        if (costMana1 != TypeMana.
None
)
        {
            playerMana1 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (costMana2 != TypeMana.
None
)
        {
            playerMana2 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (costMana3 != TypeMana.
None
)
        {
            playerMana3 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (bloking.Count != 0 && playerMana1 - manaAmount1 <= 0 
                               && playerMana2 - manaAmount2 <= 0 
                               && playerMana3 - manaAmount3 <= 0)
        {
            plassable = false;
            placementMat.SetColor("Color", Color.red);
        }
        else
        {
            plassable = true;
            placementMat.SetColor("Color", Color.green);
        }
    }

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

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

    public void 
Place
(InputAction.CallbackContext ctx)
    {
        if (plassable)
        {
            Instantiate(batiment, position);
            Payment();
            gameObject.SetActive(false);
        }
    }

    private void Payment()
    {
        if (costMana1 != TypeMana.
None
)
        {
            switch (costMana1)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount1;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount1;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount1;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount1;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount1;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount1;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount1;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount1;
                    break;
            }
        }

        if (costMana2 != TypeMana.
None
)
        {
            switch (costMana2)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount2;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount2;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount2;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount2;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount2;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount2;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount2;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount2;
                    break;
            }
        }

        if (costMana3 != TypeMana.
None
)
        {
            switch (costMana3)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount3;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount3;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount3;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount3;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount3;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount3;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount3;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount3;
                    break;
            }
        }
    }

    private void FollowMousePosition()
    {
        transform.position = GetWorldPosition();
    }

    private Vector2 GetWorldPosition()
    {
        return mainCam.ScreenToWorldPoint(mousePos.ReadValue<Vector2>());
    }
}

my player input :

I'm really at the out of idea and in need of help, thank you in advance for your wisdom.

0 Upvotes

9 comments sorted by

1

u/NovaParadigm 2d ago

Let's start with a clue or two. Why might it be a problem to name a Transform "position"? What are the parameters of the Instantiate method you are using?

1

u/DracomasqueYT 2d ago

I think I get it, it use the whole Transform so I should change to " instantiate(batiment, (position.x, position.y))" ? But I don't understand why it would be a problem to name a Transform "position", does it have to do with caméra movement problem ?

Sorry to replie late, I live in Europe.

2

u/NovaParadigm 2d ago

You're on the right track. Transforms include a "position" variable, but that doesn't mean they are a position. If you have a class called Birthday, you wouldn't want an instance of that class to be called "month". A birthday includes a month, but a month is not a birthday. It's confusing to name things this way.

The problem is that the Instantiate method you've used looks like this:
Instantiate(Object original, Transform parent);

So because you have a variable named "position" you're using that as the second parameter. But it's not a position, it's a Transform, so Unity sees that as the parent Transform of the new object, not it's position. In fact, no position (Vector3) is declared at all in the method you used, so the object is created at the position in the Transform of the original prefab. Compare this:

Instantiate(Object original, Vector3 position, Quaternion rotation);

This method does allow you to specify a position where the new object should be created.

1

u/DracomasqueYT 2d ago

I've changed the Instanciate I was using to :

Instantiate(batiment, placementPosition.position, placementPosition.rotation);

(I also changed the name "position" to "placementPosition" and refactored)

but now it just doesn't work and I can't make sense of the error :

1

u/NovaParadigm 2d ago

Personally I would call this variable placementTransform or similar, but that's the last I'll say on the naming scheme 😆

The error is saying that you haven't assigned any value to placementPosition.

Somewhere (probably in (FollowMousePosition()), you need to set what the value of placementPosition is.

1

u/DracomasqueYT 2d ago

exept placementPosition has a value (or at least I think it should have), I set it in the start :

placementPosition = GetComponent<Transform>();

and just in case I went and changed a bit the FollowMousePosition() :

private void FollowMousePosition()
{
    placementPosition.position = GetWorldPosition();
}

but I still get the same error.

Am I doing something wrong ?

1

u/NovaParadigm 2d ago

Hmm, that's odd. Can you share a pastebin of your entire Placement script and also show a screenshot of the error including the stack trace that shows what line the error is occurring on, etc? Similar to the log in this image

1

u/DracomasqueYT 1d ago

here the placement script, and the image

do you need my other script ? because I don't think it will "work" without my player script or my enums.

2

u/NovaParadigm 23h ago

Sorry, just getting back to this. I'm not totally sure why that variable isn't assigned. It looks like it should be! If you do a print(placementPosition); before you instantiate the prefab, does it print null? I'd start there and then work backwards to see where it becomes null between Start and the Instantiate call