Wie warte ich, um Code auszuführen?

7

Ich versuche, einen relativ einfachen Aufzug zu bauen (der den Spieler im Wesentlichen teleportiert), aber ich möchte nicht, dass er sie sofort teleportiert. Ich möchte, dass der Spieler den Collider betritt, 2-3 Sekunden wartet und es dann so macht, dass es etwas natürlicher erscheint.

Mein bisheriger Code:

using UnityEngine;
using System.Collections;

public class Teleporter : MonoBehaviour
{
    public GameObject TeleportTo;
    //public Material NewSkybox;

    void TimerInvoke()
    {

    }

    void OnTriggerEnter(Collider other)
    {

        Vector3 displacement = other.transform.position - this.transform.position;

        other.transform.position = TeleportTo.transform.position;
        other.transform.position += displacement;

        //RenderSettings.skybox = NewSkybox;
    }
}

Auch wenn möglich möchte ich mich von Coroutinen entfernen. Wie soll ich das machen?

Tordis
quelle
4
Ich bin gespannt, warum Sie das Tool vermeiden möchten, das genau auf dieses Szenario zugeschnitten ist.
Schatten

Antworten:

5

Normalerweise mache ich das mit Coroutines, aber da Sie sehr genau waren, dass Sie sie vermeiden möchten, könnten Sie in Ihrem Fall vielleicht etwas ganz Einfaches ausprobieren, wie:

float delay = 0;
bool trigger = false;

public Update()
{
    if (delay > 0) delay -= Time.deltaTime;
    if (delay <= 0 && trigger) TeleportPlayer();
}

void OnTriggerEnter(Collider other)
{
    delay = 3;
    trigger = true;
}

void TeleportPlayer()
{
    Vector3 displacement = other.transform.position - this.transform.position;
    other.transform.position = TeleportTo.transform.position;
    other.transform.position += displacement;
    trigger = false;
}

Natürlich können Anpassungen vorgenommen werden, je nachdem, wie lange Sie warten möchten. Bedenken Sie auch, dass deltaTime nicht in jedem Frame gleich ist. Wenn Sie also für Ihr Warten Präzision auf wissenschaftlicher Ebene benötigen, sind wahrscheinlich einige Anpassungen erforderlich. Aber ich denke, Sie haben die Idee, was der Code tut.

Vielleicht auch von Interesse, sehen Sie sich diese Implementierung einer WaitUntil-Funktion an, die genau zur Vermeidung von Coroutinen erstellt wurde: http://theinstructionlimit.com/a-replacement-for-coroutines

BEARBEITEN: Obwohl die Antwort nur die Absicht hatte, eine grundlegende Vorstellung davon zu geben, wie mit dem OP umgegangen werden soll, habe ich beschlossen, die Bool-Variable "Trigger" als einfache Möglichkeit einzuschließen, um zu vermeiden, dass der Code die gewünschte Aktion startet (in diesem Fall) , die Funktion "TeleporPlayer"), wenn der Code initialisiert wird. Auf diese Weise wird das Leben zukünftiger lernender Leser einfacher.

MAnd
quelle
Ich habe Ihr Skript ausprobiert, aber ich erhalte die Meldung "Der Name" Andere "existiert im aktuellen Kontext nicht.
Sie
@KernelPanic Oh, der Grund dafür ist, dass die Funktion "TeleportPlayer" nur ein Teil der OP-Frage ist, um die Verwendung des Codes zu veranschaulichen. Stattdessen sollten Sie einfach die Funktion ersetzen, die Sie nach der angegebenen Verzögerung ausführen möchten.
12.
1
Wird dieser Code nicht sofort ausgelöst? Die Werbeverzögerung ist = 0?
Leggy7
@ Leggy7 Sicher, das war eine vereinfachte Grundidee, die nur das OP erfassen konnte. In einer Antwort auf eine ähnliche Antwort habe ich mich um das gekümmert, was Sie sagen: gamedev.stackexchange.com/questions/111275/… Aber auf jeden Fall werde ich diese Antwort hier bearbeiten, um es zukünftigen Lesern zu erleichtern, die vorbeikommen könnten. Vielen Dank für Ihren Kommentar
MAnd
4

Sie können auch Invoke verwenden, um dies zu erreichen.

void OnTriggerEnter(Collider other)
{
    Invoke("TeleportPlayer", 3f);
}
 void TeleportPlayer()
{

    Vector3 displacement = other.transform.position - this.transform.position;

    other.transform.position = TeleportTo.transform.position;
    other.transform.position += displacement;

    //RenderSettings.skybox = NewSkybox;
}
Justin Markwell
quelle
3

Verwenden Sie Coroutinen. Sie können yield return new waitforseconds(3);in der TeleportPlayer-Methode sehen. Das wird 3 Sekunden warten, bevor der Spieler teleportiert wird. Denken Sie jedoch daran, dass nur die Ausführung der nächsten Zeile innerhalb der Coroutine angehalten wird. Alle anderen Methoden werden weiterhin ausgeführt.

 void OnTriggerEnter(Collider other)
        {
           StartCoRoutine("TeleportPlayer");

        }

IEnumerator TeleportPlayer()
{

            Vector3 displacement = other.transform.position - this.transform.position;
      Yield return new waitforseconds(3);

            other.transform.position = TeleportTo.transform.position;
            other.transform.position += displacement;

}
SanSolo
quelle
1
Ich habe nur darauf hingewiesen, dass das OP erwähnt hat, dass Coroutinen nach Möglichkeit vermieden werden sollten. Nicht, dass Ihre Antwort falsch oder nicht nützlich wäre.
12.
@ MAnd mein schlechtes hat diese letzte Zeile nicht gelesen
SanSolo
2

Natürlich können Sie dies im Code tun, aber mein Ansatz ist etwas "natürlicher".

In Ihrem Beispiel - Aufzug - werde ich Folgendes tun:

  • Wenn der Spieler den Aufzug betritt, spielen Sie eine Animation ab (z. B. Schließen der Türen).
  • In dieser Animation würde ich am Ende einen Code für den "teleportierenden" Spieler platzieren.

Sie müssen also nicht alles per Code optimieren, aber Sie würden dies in Animationen tun, damit es einfacher und natürlicher ist.

KebabuTurka
quelle