Garzec Geschrieben 7. März 2017 Melden Share Geschrieben 7. März 2017 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 More sharing options...
MarcoMeter Geschrieben 7. März 2017 Melden Share Geschrieben 7. März 2017 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 More sharing options...
erixx Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 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 More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 Oder einfach public Gradient gradient; public void Update() { light.color = gradient.Evaluate(time); } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 Wie toll und episch der Zyklus sein soll, so weit bin ich ja noch gar nicht 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 ... 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 More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 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 More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 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 More sharing options...
MarcoMeter Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 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 More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 Wenn deine Sonne nur ein Directional Light ist und über die Standard-Skybox gerendert wird, brauchst du nicht einmal das. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 Die Sonne liegt sowieso an einem Empty GO, weil ich dort die Scripte drangepackt habe Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 Na, ist doch perfekt! Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 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 More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 Oh Gott, bitte nicht auf dem Niveau versuchen Performance zu optimieren... da machst du dich ganz schnell unglücklich mit Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 Hm okay ... gibt's nen Grund? Oder soll man sich "wegen so nem Einzeiler" nicht übers Update Gedanken machen? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 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 More sharing options...
MarcoMeter Geschrieben 8. März 2017 Melden Share Geschrieben 8. März 2017 Selbst wenn der Code viel zu viel Leistung fressen würde, dann hättest du jede Sekunde einen ordentlichen Hänger Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 8. März 2017 Autor Melden Share Geschrieben 8. März 2017 Ja sauber sollte der Code schon sein Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.