Ist der Zufallszahlengenerator von Unity 2017 für alle Plattformen deterministisch, wenn der Ausgangswert identisch ist?


17

Ist der Zufallszahlengenerator von Unity Engines bei gleichem Ausgangswert plattformübergreifend deterministisch, oder sollte ich meinen eigenen implementieren?

Ich weiß, dass in letzter Zeit einige Änderungen am Zufallszahlengenerator vorgenommen wurden.

Antworten sind erwünscht, ich habe keine Geräte zur Verfügung, um Tests durchzuführen, und ich habe noch keine direkte Aussage zu diesem Thema gefunden.


11
Gute Frage. Wenn Ihr Spiel jedoch von der Generierung deterministischer Prozeduren abhängt, möchten Sie möglicherweise trotzdem Ihr eigenes PRNG programmieren, falls Unity jemals beschließt, den Algorithmus zu ändern. Die Dokumentation dokumentiert den Algorithmus nicht, daher sollten Sie keine Garantien übernehmen.
Philipp

1
Ich verstehe Ihren Standpunkt, aber es gibt genug Arbeit, um damit fortzufahren. Ich möchte lieber erfahren, in welchem ​​Zustand sich PRNG von State Unity gerade befindet, und eine zukunftssichere Version bereitstellen, die später veröffentlicht wird. Das Verwenden ohne es zu wissen, könnte zu einigen wirklich frustrierenden Fehlern führen. Danke für deinen Rat.
eternalNoob

2
Ich gebe @ Philipps Rat. Wenn Sie ein deterministisches RNG benötigen, sollten Sie in das Schreiben Ihres eigenen investieren (und es testen). Sie werden in einer Welt voller Verletzungen sein, wenn Sie jemals eine neue Unity-Version benötigen und das RNG erneut geändert wird. In diesem Fall ist es nahezu unmöglich, dasselbe RNG erneut zu erstellen und die Kompatibilität mit früheren Speicherungen / Welten zu wahren.
Stephane Hockenhull

5
Ich denke, der Rat wäre es wert, als Antwort geschrieben zu werden: "Ob er jetzt deterministisch ist oder nicht, rechne nicht damit, dass er immer gleich ist" (Wenn einer von euch so geneigt wäre - ich will nicht stehlen Sie Ihren Donner). Einige angeblich ja oder nein Fragen werden besser mit "Option C: andere" beantwortet;)
DMGregory

Antworten:



7

Thomas beantwortete die Frage wie gestellt. Die wichtigere Frage lautet wie folgt:

Wird mit dem Zufallszahlengenerator von Unity 2017 garantiert, dass er auf allen aktuellen und zukünftigen Plattformen die gleichen Zahlen liefert, und wird auch garantiert, dass er die gleichen Zahlen liefert wie zukünftige Versionen von Unity?

Es ist sehr wahrscheinlich, dass dies der Fall ist, aber dies ist nicht gleichbedeutend mit einer Garantie. Die Antwort lautet also leider " nein, das ist es nicht ". Eine Garantie müsste explizit in der Dokumentation von Random angegeben werden , aber derzeit gibt es keine solche.

Selbst wenn es eine solche Garantie geben würde, würde ich empfehlen, ihr nicht zu vertrauen - selbst bei einer Garantie besteht immer noch die Möglichkeit, dass die Implementierung versehentlich geändert wird (ein Fehler) oder einfach veraltet und später entfernt wird. Irgendwann möchten Sie den Generator möglicherweise auch außerhalb des Unity-Frameworks wiederverwenden. Anstatt sich auf Unity zu verlassen, kopieren Sie einfach einen Zufallszahlengenerator , den eine andere Person geschrieben hat (stellen Sie sicher, dass Sie den Code verwenden dürfen), und schreiben Sie einen Test, um zu überprüfen, ob er Ihren Anforderungen an die Zufälligkeit entspricht.


4

Bei Verwendung von Unity 2017.2.0f3 scheint UnityEngine.Random auf mehreren Plattformen die gleichen Ergebnisse zu liefern. Getestet unter Windows 10, macOS 10.12 Sierra und Android 7.

Zum Testen habe ich eine von mir erstellte SeedFactory-Klasse verkleinert:

using UnityEngine;

public class SeedFactory {

    private Random.State state;

    public SeedFactory (int seed) {
        Random.InitState(seed);
        state = Random.state;
    }

    // Set Unity's global Random state with this SeedFactory's state, get a random int,
    // then set our SeedFactory's state with the new state.
    // (this allows us to use multiple SeedFactories for multiple paths of determinism
    // if desired)
    public int GetRandomInt (int minInclusive, int maxExclusive) {
        Random.state = state;
        int randomInt = Random.Range(minInclusive, maxExclusive);
        state = Random.state;
        return randomInt;
    }

}

Und ein MonoBehaviour, um den Test durchzuführen:

public class SeedTest : MonoBehaviour {

    void Start () {
        SeedFactory seedFactory = new SeedFactory(123456789);
        string result = "";
        for (int i = 0; i < 20; i++) {
            result += seedFactory.GetRandomInt(int.MinValue, int.MaxValue) + ", ";
        }
        Debug.Log(result);
    }

}

Und die Ergebnisse waren alle gleich:

Windows Editor:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178, 

Windows Standalone:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,

macOS Standalone:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,

Android:
217814258, 711215697, 1793372675, -1318111305, -513578644, 1776128467, -1503243711, -285471819, -1800526065, -1845985472, -2061970588, 188207569, 1858341351, -1139513088, 2136219157, 1255727479, -2070068486, 459175680, 1151694536, 1232856178,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.