Jump to content
Unity Insider Forum

Simplen Tag/Nacht Zyklus mithilfe von Slider darstellen


Garzec

Recommended Posts

Guten Abend,

Ich habe einen sehr einfachen Tageszyklus, aufgerufen im Update:

light.transform.RotateAround(Vector3.zero, Vector3.right, timeData.RotationSpeed * Time.deltaTime);
    light.transform.LookAt(Vector3.zero);

Nun möchte ich im Spieler Interface diesen Zyklus darstellen, erstmal durch einen Slider. Der Slider hat den Wertebereich 0 bis 1.

 

Ich bin also der Ansicht, ich brauche 1. die maximale Dauer, einer Umkreisung und 2. pro Frame den aktuellen Stand.

 

Die Sonne steht auf (0,100,0), ihre Rotation auf (90,0,0) und ihre Geschwindigkeit auf 10. Sie rotiert um Vector3.Zero.

 

Nun habe ich mir mal ein paar Formeln rausgekramt, berechne die Gesamtdauer wie folgt:

 

public float CycleLength
   {
       get
       {
           return 2 * Mathf.PI * Vector3.Distance(Sun.transform.position, Vector3.zero) / RotationSpeed;
       }
   }

 

Meine erste Frage wäre, stimmt diese Formel überhaupt?

2 * PI * Radius / Geschwindigkeit

 

Meine 2. Frage ist, wie berechne ich denn den aktuellen Stand?

 

Mein Ziel wäre, beim Slider schreiben zu können

slider.value = current / maxDuration;
Link zu diesem Kommentar
Auf anderen Seiten teilen

Mach es dir doch viel einfacher.

 

360° benötigt eine volle Umdrehung.

 

Der Slider hat einen Bereich von 0 - 1 oder anders dargestellt von 0 - 100%.

 

Den Winkel, in dem deine Sonne steht kannst du ja berechnen. Dann brauchst du nur den Winkel durch 360° teilen, um die Vollständigkeit der Rotation dem Slider als Wert zu übergeben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, ich hab eine Formel aufgestellt, die die Helligkeit/Alphawerte von Licht/Farbuebergangen per Lerp mit dem Faktor 0-1 in Abhaengigkeit von der aktuellen Tageszeit (0 - 24 Uhr) und dem Halbtageswert ausrechnet. Vielleicht kannst du sie dir ja an deine Bedeurfnisse anpassen:

 

var halfday:int=12;

 bright=-(((currentTime-halfday)/halfday)*((currentTime-halfday)/halfday))+1;
  //sunset
  if (currentTime >=halfday) {

  curCol=Color.Lerp(color2, color1,bright);
  }
  //sunrise
if (currentTime <halfday){

  curCol=Color.Lerp(color1, color2,1-bright);
  }

 

LG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie toll und episch der Zyklus sein soll, so weit bin ich ja noch gar nicht :P

 

Also weshalb ich mich so schwer tue, ist, weil die Sonne und der Mond durch das LookAt(); eine Rotation auf der y-Achse von 180 (Sonne) und 0 (Mond) einnehmen.

 

Sie rotieren auf X ja auch nie bis 360 oder 180 Grad. Hier mal ein wundervolles Gemälde von mir ...unknown.png

 

Da ich jetzt erstmal @MarcoMeters Vorschlag umsetzen wollte, habe ich geschrieben

   private void Update()
   {
    TimeProgressSlider.value = timeData.CurrentTime;
   }

 

wobei

public float CurrentTime { get { return  ??? / 360; } }

 

Und durch meine Überlegungen oben, weiß ich nicht, ob das so passen wird und 2. weiß ich auch nicht so recht, welchen Winkel man genau benötigt.

 

Ich könnte ja die Rotation übers Transform holen

 

Sun.transform.rotation.x

 

oder mit einem Quaternion oder die lokale Rotation oder ...

 

Zb. Das ist das, wobei ich Hilfe bräuchte :S

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sie rotieren auf X ja auch nie bis 360 oder 180 Grad.

Aber warum denn nicht?

 

Mach es dir doch viel einfacher.

Der Ansatz mit 0-1 ist schon sehr gut.

Wenn du alle Werte (Rotation, Farben, ...) von diesem einen Wert ableitest, machst du dir das Leben sehr viel einfacher.

[Range(0f, 1f)]
public float dayProgress;
[Tooltip("One day's duration in seconds.")]
public float dayDuration = 60 * 60; // = 1 hour

void Update()
{
 var delta = Time.deltaTime / dayDuration;
 dayProgress = Mathf.Repeat(dayProgress + delta, 1);

 UpdateVisuals();
}

private void UpdateVisuals()
{
 transform.localRotation = Quaternion.Euler(dayProgress * 360, 0, 0);
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dadurch bleibt die Sonne aber doch an einem Punkt und rotiert nur um ihre eigene Achse. Eigentlich müsste sie doch um den Vector3.Zero rotieren, also eine Kreisbahn ablaufen. Zumindest hatte ich das so mit RotateAround() gemacht.

 

Oder macht man das nicht? So bleibt die Sonne ja fix, der Mond fällt dann weg, weil er ja nicht mehr mit der Sonne um die Erde rotiert.

 

Edit: Also vielen Dank, das klappt wunderbar :) Ich wollte nur noch fragen, so zur Information quasi

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dadurch bleibt die Sonne aber doch an einem Punkt und rotiert nur um ihre eigene Achse. Eigentlich müsste sie doch um den Vector3.Zero rotieren, also eine Kreisbahn ablaufen. Zumindest hatte ich das so mit RotateAround() gemacht.

 

Häng deine Sonne an ein Empty GameObject, welches am Punkt (0,0,0) liegt. Dann brauchst du nur das Empty GameObject drehen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich darf davon ausgehen, für das sekündliche Updaten der Bar eine Coroutine zu nehmen anstatt Update? Ich denke, es macht einen Performanceunterschied aus oder?

 

Weil jeden Frame updaten, das brauch ja kein Mensch. Eine Sekunde Zeit reicht ja. Aber mir geht es eher um die Performance :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Letzteres. Das Aufrufen von Unity-Events passiert ja über Reflection und das ist etwas langsamer als andere Varianten. Aber ob du jetzt für dieses eine Skript 30 oder 34 Nanosekunden brauchst... da würde ich lieber auf Codequalität als auf Performance achten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...