Switching between Character Controllers

Hi, I want to build a “Scorched Earth” Clone, where tanks fight each other. I just started prototyping with two tanks.

I implemented a movement script, but of course if I put it on both tanks, they both move the same directions.

How can I force the Input to be read from the “active” player only. I think of creating some Input Manager and doing a kind of STATE (bool active/inactive) but don’t know how to implement it.

How do I implement this?

Here is my script so far:

public class Bewegung : MonoBehaviour
{
    private Vector3 bewegung;

    [SerializeField] private float Geschwindigkeit;
    [SerializeField] private Rigidbody2D playerBody;
    [SerializeField] private bool activated;

    // Update is called once per frame
    void Update()
    {
        //wenn R gedrückt wird, zwischen aktiv und inaktiv wechseln
        if(Input.GetKeyDown(KeyCode.R))
        {
            activated = !activated;
        }

        if (activated)
        {
            bewegung = new Vector2(Input.GetAxis("Horizontal"), 0);


            MovePlayer();
        }
    }

    private void MovePlayer()
    {

        Vector3 MoveVector = transform.TransformDirection (bewegung) * Geschwindigkeit;
        playerBody.velocity = new Vector3(MoveVector.x, playerBody.velocity.y, 0);
    }
}

Hi, can you please edit your post to paste your code where it says "paste code here"? How are you currently tracking which player is active?

3 Answers

3

I now implemented a toggle, for when I press R the boolean switches

But I have to choose on Player to be active manually before I start to play

void Update()
{
    //wenn R gedrückt wird, zwischen aktiv und inaktiv wechseln
    if(Input.GetKeyDown(KeyCode.R))
    {
        activated = !activated;
    }

    if (activated)
    {
        bewegung = new Vector2(Input.GetAxis("Horizontal"), 0);


        MovePlayer();
    }
}

How do I globally set the bool of each Player?

I usually have a class called Controller that reads user input and passes it to the controlled avatar, in your case, the tank. Your controller could have a list of all tanks, and simply loop between them, controlling one tank at a time, while also displaying the currently controlled tank’s stats.

I generally don’t mix input, output (UI, camera, etc) with the avatar. That way, you can easily separate the game logic and the controller, or even AI controller.

sounds great, I will do this later, I want to do very little steps course i'm coworking with a real beginner, so the static variable approach seems suitable as a first solution thanks :)

Static variables are almost never a good idea :D But sure, feel free to experiment.

well in the end I made an extra class for Inputs getting a list of Gameobjects of Tank (tagged) und go trough it after pressing a certain button to deactivate the current element of the list and activating the next one, so it can work with any number of tanks

it looks like this:

public class Inputs : MonoBehaviour
{
    public GameObject[] playerList;
    private int SpielerAktiv;

    //Tastenbelegung

    public KeyCode Spielerwechsel=KeyCode.N;

    // Start is called before the first frame update
    void Start()
    {
        //Packe alle Spieler in eine Liste
        playerList = GameObject.FindGameObjectsWithTag("Player");

        //Spieler 1 soll beginnen
        SpielerAktiv = 0;

        SpielerAktivieren(SpielerAktiv);
                      
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(Spielerwechsel))
        {
            //aktuellen Spieler deaktivieren
            playerList[SpielerAktiv].GetComponent<Bewegung>().activated = false;

            //nächsten Spieler auswählen
            if (SpielerAktiv + 1 < playerList.Length)
            {
                SpielerAktiv++;
            }
            else SpielerAktiv = 0;

            SpielerAktivieren(SpielerAktiv);
        }
    }

    void SpielerAktivieren(int SpielerAktiv)
    {
        playerList[SpielerAktiv].GetComponent<Bewegung>().activated = true;
        Debug.Log("Spieler Nummer: " + SpielerAktiv + " ist am Zug!");
    }
}