Jump to content
Unity Insider Forum
ShV

Objekt soll steigen und nach bestimmter Zeit fallen

Recommended Posts

Ich möchte, dass mein Objekt, sobald es keinen Kontakt mehr zum Boden hat, 2 Sekunden auf der y- Achse steigt. Hat jemand eine Idee, wie ich das machen kann?

Share this post


Link to post
Share on other sites

Hallo

 

ja, du musst ab dem Zeitpunkt,Wonder Kontakt verloren geht, einen Timer starten. Ohne dein Aufbau zu kennen, würde ich oncollionsexit abfangen und dann zu einer Variable immer deltaTime addieren. In jedem Frame fragst du ab, die Variable größer als zwei ist.

 

christoph

  • Thanks 1

Share this post


Link to post
Share on other sites

Die Erkennung, ob das Objekt nicht mehr auf dem Boden ist, kannst Du mit OnCollisionExit machen, wie @chrische5 schon schreibt. Wenn dieses Ereignis eintritt, kannst Du in eine Variable die aktuelle Zeit schreiben und im Update dann prüfen ob die aktuelle Zeit - die gespeicherte Zeit 2 Sekunden ergibt bzw. darunter liegt. Solange eben das Objekt bewegen.

Beispiel Pseudo Code

private float groundExitTime;
private const float moveUpDuration = 2f;

void OnCollisionExit(Collision collisionInfo)
{
  groundExitTime = Time.timeSinceLevelLoad;
}

void Update()
{
  if(Time.timeSinceLevelLoad - groundExitTime <= moveUpDuration)
  {
    //move up
  }
}

 

Share this post


Link to post
Share on other sites

mit dem OnCollisionExit stimme ich zu allerdings kommt das auf deinen Anwendungsfall an, da gibt es sicher noch andere / leichtere lösungen für

von der Lösung die @devandart vorgeschlagen hat würde ich jedoch abraten ... bei diesem Code wird das objekt sobald das level geladen ist erstmal direkt 2 sekunden steigen wenn nicht gleich OnCollisionExit aufgerufen wird. Besser ist es eine bool variable z.b. isGrounded = true und eine timerVariable zu haben. Wenn OnCollisionEnter eintritt setzt du die timerVariable auf 2f und isGrounded auf false. In der Update() funktion machste dann

private bool isGrounded = true;
private float moveUpTimer;
private const float moveUpDuration = 2f;

void OnCollisionEnter(Collision collisionInfo)
{
  // Wenn collision mit ground
  isGrounded = true;
}

void OnCollisionExit(Collision collisionInfo)
{
  // wenn keine collision mehr mit ground
  moveUpTimer = moveUpDuration;
  isGrounded = false;
}

public void Update()
{
 if(isGrounded)
      return;
  
  	moveUpTimer -= Time.deltaTime;
    if(moveUpTimer > 0f)
    {
      // move up
    }
  
}

gruß Cxyda

Share this post


Link to post
Share on other sites

Hatte dieses Mal initial keine Lust, den "das geht auch soundso"-Typen rauszuholen, aber da jetzt hier lauter Varianten aufgezählt werden, mach ich's halt doch :D

Man kann in Update hoch- oder runterzählen oder auch Timestamps vergleichen. Man kann aber auch eine Coroutine benutzen:

private void OnCollisionExit()
{
  StopAllCoroutines();
  StartCoroutine(MoveUp(2f));
}

private IEnumerator MoveUp(float duration)
{
  for (var time = 0f; time < duration; time += Time.deltaTime)
  {
    transform.Translate(Vector3.up * speed * Time.deltaTime);
    yield return null;
  }
}

Man kann auch so etwas machen:

private bool moving;

private void OnCollisionExit()
{
  StartCoroutine(MoveUp(2f));
}

private IEnumerator MoveUp(float duration)
{
  moving = true;
  yield return new WaitForSeconds(duration);
  moving = false;
}

private void Update()
{
  if (moving)
  {
    transform.Translate(Vector3.up * speed * Time.deltaTime);
  }
}

Oder man nutzt Invoke für diese Variante. Invoke ist aber doof, lieber meinen Invoker benutzen :D:

private bool moving;

private void OnCollisionExit()
{
  StopAllCoroutines();
  moving = true;
  StartCoroutine(Invoker.Invoke(() => moving = false, 2f));
}

private void Update()
{
  if (moving)
  {
    transform.Translate(Vector3.up * speed * Time.deltaTime);
  }
}

Oder du nimmst die eine Tween-Bibliothek. Tweens sind genau für so etwas ("mach mal etwas X Sekunden lang") und mehr da. Auch dafür hab ich ne kleine Klasse, aber Tween-Frameworks gibt's lauter verschiedene, kannst du dir ja mal ansehen. Mit meiner Klasse würde das so aussehen:

private void OnCollisionExit()
{
  // Hier wird distance statt speed benutzt, das eine kann man aber durch das andere ausrechenen
  var targetPosition = transform.position + Vector3.up * distance;
  StartCoroutine(CorouTweens.Interpolate(transform.position, // von wo
                                         targetPosition, // nach wo
                                         duration, // wie lange
                                         CorouTweens.linear, // welche Kurve (z.B. erst schneller, dann langsamer, hier aber gleichbleibend)
                                         pos => transform.position = pos));
}

 

Share this post


Link to post
Share on other sites

😉 @Sascha also nur um nach X Zeit eine funktion zu callen brauchst keine Coroutine da reicht auch ein einfaches

 


Invoke(nameOf(MyStopFunction), 2f);

... und in deiner ersten coroutine fehlt ein "yield return" 🤓

aber ja... du bekommst den Keks für die ausführlichste Antwort ! 👍

Share this post


Link to post
Share on other sites
vor 5 Stunden schrieb Cxyda83:

... und in deiner ersten coroutine fehlt ein "yield return" 🤓

Na, das stimmt. Hab's korrigiert., danke!

vor 5 Stunden schrieb Cxyda83:

Invoke(nameOf(MyStopFunction), 2f);

Oha.... auf die Idee bin ich nicht gekommen. Empfehle immer, Invoke wegen des String-Parameters nicht zu benutzen, aber so ist's ja wieder sicher.

Die Doku sagt allerdings selbst

Zitat

For better performance and maintability, use Coroutines instead.

Ich nehme an, dass da Reflection passiert ist nicht so prickelnd. Hab's mal durch den Benchmark laufen lassen: MonoBehaviour.Invoke braucht bei mir 230ns beim Aufruf, die Coroutine mit dem Invoker nur 2µs.

Mit "maintability" (maintainability...) meinen die vermutlich genau das String-Problem, das man mit nameof ja umgeht. Reicht also in der Tat, aber ich werde weiterhin den Invoker empfehlen :D

Oh, und Nachtrag: Beim Invoker muss man keine Methode definieren, sondern kann einfach einen Lambda-Ausdruck reinknallen. Finde ich jetzt auch nicht unwichtig :)

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

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

Loading...

×
×
  • Create New...