Jump to content
Unity Insider Forum

Doppelray?


Kojote

Recommended Posts

Hallo!

Ich habe bei mir für Charaktere eine Slotauswahl, in der sind die Charaktere hinterlegt. Möchte ein Spieler nun einen Charakter nutzen und auf eine Spielfläche setzen habe ich hier ein kleines Script:

    private void FixedUpdate() {
        if (Time.timeScale == 0) {
            if (zuSetzenderCharakter > 0) {
                zuSetzenderCharakter = 0;
            }
            return;
        }

        // Charakter auf dem Spielfeld setzen und bewegen
        // Wichtig: Sollte der Charakter zwei mal hintereinander angeklickt werden, wird die Ausahl aufgehoben
        if (Input.GetMouseButtonDown(0) & !Input.GetMouseButtonDown(1) & spielGestartet == false) {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(ray, out hit)) {
                if (hit.collider.gameObject.tag == "Charakter_1") {
                    if (zuSetzenderCharakter != 1) {
                        zuSetzenderCharakter = 1;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[0]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.tag == "Charakter_2") {
                    if (zuSetzenderCharakter != 2) {
                        zuSetzenderCharakter = 2;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[1]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.tag == "Charakter_3") {
                    if (zuSetzenderCharakter != 3) {
                        zuSetzenderCharakter = 3;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[2]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.tag == "Charakter_4") {
                    if (zuSetzenderCharakter != 4) {
                        zuSetzenderCharakter = 4;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[3]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.tag == "Charakter_5") {
                    if (zuSetzenderCharakter != 5) {
                        zuSetzenderCharakter = 5;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[4]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.tag == "Charakter_6") {
                    if (zuSetzenderCharakter != 6) {
                        zuSetzenderCharakter = 6;
                        CharkterAndereCharaktereAbwaehlen(zuSetzenderCharakter);
                        outLineEffect.ChangeOutlineObjectsSingle(charaktere[5]);
                    } else {
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        zuSetzenderCharakter = 0;
                    }
                } else if (hit.collider.gameObject.layer == 10 & zuSetzenderCharakter > 0) {
                    int zaehler = 0;
                    // Verhindert das mehrere Charaktere an die selbe stelle gesetzt werden
                    for (int i = 0; i < charaktere.Length; i++) {
                        if (hit.collider.gameObject.transform.position == charaktere[i].transform.position) {
                            zaehler++;
                        }
                    }
                    if (zaehler == 0) {
                        // Wenn die Bodenplatte nicht belegt ist, kann der Charakter positioniert werden
                        charaktere[zuSetzenderCharakter - 1].transform.position = hit.collider.gameObject.transform.position; // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        gesetzteCharaktere[zuSetzenderCharakter - 1] = true; // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        charakterSlot.SlotDeaktivieren(zuSetzenderCharakter); // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        zuSetzenderCharakter = 0;
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        if (buttonStart.GetComponent<Button>().interactable == false) {
                            CharakterKontrolle();
                        }
                    } else if (zaehler == 1 & (charaktere[zuSetzenderCharakter - 1].transform.position == hit.collider.gameObject.transform.position)) {
                        // Ausnnahmeregel, sollte die Bodenplatte angeklickt werden, auf dem der Charakter schon steht, wird die Auswahl aufgehoben
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                    }
                }
            }
        }
    }

Dieses Script sorgt zum einen dazu, den Charakter auf eine Bodenfläche zu setzen, wenn diese nicht belegt ist, zum anderen kann man den Charakter markieren und auf eine andere Fläche setzen. Funktioniert auch ganz gut soweit, habe nur leider einen sporadischen Bug.

Genauer gesagt hier:

if (Input.GetMouseButtonDown(0) & !Input.GetMouseButtonDown(1) & spielGestartet == false) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
}

In diesem Abschnitt wird ein Ray abgeschossen auf eine Spielfläche, ist die Fläche leer, wird der Charakter hiermit positioniert:

if (hit.collider.gameObject.layer == 10 & zuSetzenderCharakter > 0) {
                    int zaehler = 0;
                    // Verhindert das mehrere Charaktere an die selbe stelle gesetzt werden
                    for (int i = 0; i < charaktere.Length; i++) {
                        if (hit.collider.gameObject.transform.position == charaktere[i].transform.position) {
                            zaehler++;
                        }
                    }
                    if (zaehler == 0) {
                        // Wenn die Bodenplatte nicht belegt ist, kann der Charakter positioniert werden
                        charaktere[zuSetzenderCharakter - 1].transform.position = hit.collider.gameObject.transform.position; // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        gesetzteCharaktere[zuSetzenderCharakter - 1] = true; // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        charakterSlot.SlotDeaktivieren(zuSetzenderCharakter); // -1 Ausgleich wegen Arry, da es von 0 an rechnet
                        zuSetzenderCharakter = 0;
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                        if (buttonStart.GetComponent<Button>().interactable == false) {
                            CharakterKontrolle();
                        }
                    } else if (zaehler == 1 & (charaktere[zuSetzenderCharakter - 1].transform.position == hit.collider.gameObject.transform.position)) {
                        // Ausnnahmeregel, sollte die Bodenplatte angeklickt werden, auf dem der Charakter schon steht, wird die Auswahl aufgehoben
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());
                    }

Layer 10 ist die Bedingung, dass der Charakter auf diese Bodenplatte gesetzt werden darf. Der Zähler kontrolliert ob eventuell schon ein anderer Charakter darauf steht, wenn nicht, ist der Zähler 0. Er wird gesetzt. Nun sollte eigentlich die Charakterauswahl aufgehoben werden:

                        zuSetzenderCharakter = 0;
                        outLineEffect.ChangeOutlineObjects(new List<GameObject>().ToArray());

Problem ist, sehr selten, wird die Auswahl nicht aufgehoben. Ich dachte erst dass der Zähler anderswo hochgesetzt wird oder der Outline Effekt einen Bug hat, aber Fehlanzeige.

Es scheint, dass wenn der Ray abgeschossen wurde und der gesetzt wurde, der Ray entweder zwei mal abgeschossen wird, was ich eher nicht glaube. Alternativ, durch den Tastendruck der Maus, der Vorgang wiederholt wird. Habt ihr eine Idee wie man das verhindern könnte?

Grüße Kojote

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du benutzt Get(MouseButton/Button/Key)(Down/Up) in FixedUpdate, das führt zu solchen Fehlern. Die Werte, die von diesen Funktionen zurückgegeben werden, werden im Update-Schritt jeweils einmal geändert. FixedUpdate kann allerdings mehrere Male oder gar nicht zwischen zwei Updates aufgerufen werden. Bedeutet, dass gerne Mal gar nichts passieren kann, wenn du klickst, aber eben auch, dass es mehrere Male mit nur einem Klick passiert.

Deshalb diese Funktionsgruppe nur in Update verwenden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Lädt...
×
×
  • Neu erstellen...