Jump to content
Unity Insider Forum

Tageszeiten


Shalafi

Recommended Posts

Hi,

ich habe ein Skript, das je nach Tageszeit das directional Light in der Scene anpasst, quasi die Sonne.

 

public class LightingManager : MonoBehaviour
{
    //Scene References
    [SerializeField] private Light DirectionalLight;
    [SerializeField] private LightingPreset Preset;
    //Variables
    [SerializeField, Range(0, 24)] private float TimeOfDay;
	[SerializeField, Range(-10, 10)] public float speedMultiplier;//Here you adjust the value

    private void Update()
    {
        if (Preset == null)
            return;

        if (Application.isPlaying)
        {
            //(Replace with a reference to the game time)
            TimeOfDay += Time.deltaTime * speedMultiplier;
            TimeOfDay %= 24; //DO NOT MODIFIED 

            UpdateLighting(TimeOfDay / 28f);
			TimeOfDay %= 24;
        }
        else
        {
            UpdateLighting(TimeOfDay / 24f);
        }
    }


    private void UpdateLighting(float timePercent)
    {
        //Set ambient and fog
        RenderSettings.ambientLight = Preset.AmbientColor.Evaluate(timePercent);
        RenderSettings.fogColor = Preset.FogColor.Evaluate(timePercent);

        //If the directional light is set then rotate and set it's color, I actually rarely use the rotation because it casts tall shadows unless you clamp the value
        if (DirectionalLight != null)
        {
            DirectionalLight.color = Preset.DirectionalColor.Evaluate(timePercent);

            DirectionalLight.transform.localRotation = Quaternion.Euler(new Vector3((timePercent * 360f) - 90f, 170f, 0));
        }

    }



    //Try to find a directional light to use if we haven't set one
    private void OnValidate()
    {
        if (DirectionalLight != null)
            return;

        //Search for lighting tab sun
        if (RenderSettings.sun != null)
        {
            DirectionalLight = RenderSettings.sun;
        }
        //Search scene for light that fits criteria (directional)
        else
        {
            Light[] lights = GameObject.FindObjectsOfType<Light>();
            foreach (Light light in lights)
            {
                if (light.type == LightType.Directional)
                {
                    DirectionalLight = light;
                    return;
                }
            }
        }
    }

}

 

Wie kann ich das Skript so ändern, dass es nicht so lange dunkel ist, zB nur von 22 - 06 Uhr?

 

 

Gruß

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist ne interessantere Frage, als man vielleicht anfangs erwarten würde.

Mein erster Ansatz wäre anzuschauen, warum es in der Realität nicht genau 50% der Zeit dunkel ist.

ravsunImage2.jpg

(Quelle)

Hatte erst selber ungefähr dasselbe mit Paint gemalt, aber dann das hier gefunden :P

Weil die Rotationsachse der Erde geneigt ist, haben Nordhalbkugel längere - und die Südhalbkugel gleichzeitig kürzere - Tage, und dann umgekehrt. Im Herbst und Frühling gibt's dann den einen Zeitpunkt, wo Tag und Nacht gleichlang sind.

Das Problem ist, dass du in Unity keine heliozentrische Szene (Erde dreht such im Sonne) hast, sondern einen geozentrischen Aufbau (Directional Light dreht sich um Boden). Wie man aus den Erkenntnissen des Bildes einen sinnvollen, intuitiven Aufbau einer Szene ziehen könnte... Man könnte einen Äquanten einführen, um den sich das Directional Light dreht, und dann mit einem Einzeiler-Script mit Transform.LookAt dafür sorgen, dass das Licht immer in die richtige Richtung scheint.

Ansonsten kann man das ganze natürlich auch komplett faken und irgendwie mit einer Sinuskurve oder einer AnimationCurve die Tage stumpf länger machen. Dann ist der Verlauf der Schatten über den Tag nicht korrekt - ob das einer merkt, wäre aber die nächste Frage.

So beim Lesen, hast du schon eine Präferenz? :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

danke für die Ausführung ;)

Ich denke faken reicht fürs erste aus.

Meine Idee war anfangs, die Rotation in den Nacht-Stunden etwas zu beschleunigen, und am Tag etwas zu reduzieren (damit man wieder aut 360° pro Tag kommt).
Kann man das so umsetzen, bzw. wie müsste das aussehn? Oder geht es mit einer Sinus-Kurve einfacher?

 

 

Gruß




 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 6 Stunden schrieb Shalafi:

Kann man das so umsetzen

Wenn, dann nur in (einem) FixedUpdate, sonst wird's framerateabhängig und komische Dinge können passieren.

So als Beispiel für eine Sinuskurve, grob aus den Fingern gesaugt:

private float linearDayTime = 0.4f; // 0f bis 1f

public float secondsPerDay = 60f;
[Range(-1f, 1f)]
public float dayEnhancementAmount = 1f;

private void Update()
{
  linearDayTime += Time.deltaTime / secondsPerDay;
  linearDayTime = Mathf.Repeat(linearDayTime, 1f);
  
  var offset = Mathf.Sin(linearDayTime * 2f * Mathf.PI) * 0.5f * dayEnhancementAmount * 0.25f;
  var manipulatedDayTime = linearDayTime + offset;
  
  Apply(manipulatedDayTime);
}

// Und so als Beispiel...
private void Apply(float time)
{
  time -= 0.25f;
  transform.localRotation = Quaternion.Euler(time * 360f, 0f, 0f);
}

Wenn wir jetzt mal davon ausgehen, dass das Licht so eingerichtet ist, dass wir zwischen time=0.25 und time=0.75 Tag haben, dann wollen wir früher bei 0.25 ankommen und später bei 0.75, damit der Tag länger ist.

Die obige Formel sieht geplottet so aus:

grafik.png

https://www.wolframalpha.com/input/?i=x+%2B+sin(x+*+2+*+pi)+*+0.5+*+0.25+from+0+to+1

Die Kurve "beeilt" sich, in den Tagbereich zu kommen und bleibt dann da eine Weile länger. Mal mit Überlagerung:

grafik.png

Der gelbe Bereich ist die Tagzeit, und statt zwischen 0.25 und 0.75 sind wir zwischen etwa 0.15 und 0.85 drin. Der Tag macht also 70% des Zyklus aus statt 50%. Man sieht aber auch schon, dass bei einem Wert von 1 für dayEnhancementAmount die Sonne gegen Mittag einfach fast stillsteht. Das könnten Spieler natürlich wahrnehmen, auch durch die Schatten.

Bei einem negativen Wert für dayEnhancementAmount haben wir übrigens längere Nächte. Da sieht die Kurve so aus:

grafik.png

https://www.wolframalpha.com/input/?i=x+%2B+sin(x+*+2+*+pi)+*+0.5+*+-0.25+from+0+to+1

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmmm... Also ich hab mir das mal ganz einfach gemacht...

Ich hab schlicht und ergreifend das Direct-Licht sich um den Unity-Mittelpunkt drehen lassen. Einfach so, wie sich die Sonne in "echt" eben auch bewegen würde (und ja, ich weiß, dass sich eigentlich die Erde um die Sonne dreht, nicht umgekehrt :) ). Auf die Rotationszeit angepasst habe ich dann eine Animation erstellt, bei der sich die Lichtfarbe und Intensivität verändert (bläulicher und schwächer in der Nacht, rötlicher am Abend usw. (Fast) kein Code und, für mich, absolut ausreichende Ergebnisse. Mein 24 Stunden-Zyklus dauert dabei 2 Minuten.

Unbenannt3.JPG

Unbenannt4.JPG

Unbenannt2.JPG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...