World3DModel.setAlpha(float) nach Player.addWorldElement(WorldElement) ohne Wirkung - (GELÖST! Java-Version)

  • Hi Red,


    mir ist aufgefallen das setAlpha nach dem anzeigen für den Spieler, keine Auswirkung mehr auf das WorldElement hat. Bei der Position und Rotation ist das nicht so.

    Ist das für den Alpha Wert nicht so vorgesehen?


    Ich kann das umgehen, indem ich das Model erst wieder vom Player entferne und dann ihm mit neuem Alpha wider hinzufüge.:/


    Wenn ich jetzt aber mal ein Fade-Out oder Fade-In machen möchte und vielleicht noch für mehrere Spieler anzeigen will, ist das doch recht Ressourcen lastig, denke ich:thinking:

    Java
    for (float a=1f;a<0f;a-=0.1f){
    world3DModel.setAlpha(a);
    plugin.getServer().getAllPlayers().forEach((player) -> {
    player.removeWorldElement(world3DModel);
    player.addWorldElement(world3DModel);
    });
    }


    Gibt es einen direkten Weg, den ich noch nicht gefunden habe;)


    Für die neue Version Wünsche ich mir das:D

  • Das ist tatsächlich ein Bug :thinking: Beim Aufruf von setAlpha() wird der neue Alpha-Wert zwar gesetzt, aber das Objekt nicht mit den Clients synchronisiert. Erst bei der nächsten "Änderung" am Objekt (zB Position ändern, oder eben erneut zum Spieler hinzufügen) wird der neue Alpha-Wert übernommen. Wir werden das mit dem nächsten Update beheben, leider steht noch nicht fest, wann es das nächste Update für die Java-Version geben wird...


    Es gibt aber einen Workaround: Via Reflection kannst du die Update-Methode des 3D Modells manuell aufrufen. Die Methode heißt "updateElement" und nimmt zwei boolean-Werte entgegen (diese bestimmen, ob gleichzeitig auch die Kollision [teuer] und die Interaction-Daten geupdated werden sollen - können in dem Fall also false sein). Du könntest in deinem Plugin zB so eine Funktion einrichten:

    Java
    public static void refreshWorld3DModel(World3DModel model){
    try{
    Method method = World3DModel.class.getDeclaredMethod("updateElement", boolean.class, boolean.class);
    method.setAccessible(true);
    method.invoke(model, false, false);
    }
    catch(Exception e){
    e.printStackTrace();
    }
    }


    Wenn du nun den Alpha-Wert änderst, kannst du anschließend diese Funktion aufrufen um das Objekt zu synchronisieren. Das könnte dann so aussehen:

    Java
    World3DModel myModel = ...;
    //Update alpha
    myModel.setAlpha(0.5f);
    //Refresh
    refreshWorld3DModel(myModel);


    Wenn sowas extrem häufig gemacht wird, könntest du ggf. die Referenz auf "method" auch nur einmal auslesen und dann zwischenspeichern. Wobei das nicht unbedingt nötig ist, da Reflection in Java schon recht schnell ist ;)



    Ein Fade-Effekt ist aber eine etwas heiklere Sache: Mit dem Code, den du gepostet hast, würde das leider nicht klappen. Denn du musst bedenken, dass die Schleife ja sofort abgearbeitet wird, d.h. diese ~10 Iterationen werden in weniger als 1 ms durchgeführt. Sprich in weniger als einer tausendstel Sekunde wird der Alpha-Wert 10x geändert - das nimmt man als Spieler natürlich gar nicht wahr, d.h. das Modell ist sofort unsichtbar. Streng genommen würde die obige Schleife sogar gar nichts bewirken, da die Schleifenbedingung (a < 0) niemals erfüllt ist.


    Um einen sichtbaren Fade-Effekt zu erzeugen, muss zwischen den Aufrufen eine kleine Pause sein. Die Schleife kannst du leider nicht verlangsamen, daher wäre hier die sinnvollste Lösung ein Timer. Das nächste Problem ist aber, dass 10 Schritte (also Alpha-Wert jedes Mal um 0.1 reduzieren) zu wenig sind, also die Abstufungen deutlich sichtbar wären (sprich der Fade-Effekt wäre relativ "hakelig"). Um einen weichen Übergang zu haben, bräuchte man wesentlich mehr Übergänge, mindestens 100 oder sogar noch mehr. Das verursacht schon eine Menge Traffic, wenn das aber nicht zu exzessiv eingesetzt wird, ist das vmtl. vertretbar :nerd:

  • mit refreshWorld3DModel(World3DModel model) klappt es wunder bar.:thumbup:


    Streng genommen würde die obige Schleife sogar gar nichts bewirken, da die Schleifenbedingung (a < 0) niemals erfüllt ist.

    Hatte Fade-Effekt nur als beispiel genommen und der Code war "quik and dirty" :|

    Aber ja, du hast recht der Fade-Effekt wehre etwas Aufwändiger^^


    Arbeite erstmal an einer World3DModel-Platzierungs-Methode die eine Durchsichtige Vorschau zeigt bis es Platziert wird und dabei ist es mir aufgefallen:D



    Wir werden das mit dem nächsten Update beheben, leider steht noch nicht fest, wann es das nächste Update für die Java-Version geben wird...

    Alles gut, richtet eure Aufmerksamkeit lieber auf die neue Version! Der Workaround reicht vorerst vollkommen aus.


    P.S. Mein Plugin wartet eh auf die neue Version mit den GUI Änderungen und so:wow:

  • noci

    Changed the title of the thread from “World3DModel.setAlpha(float) nach Player.addWorldElement(WorldElement) ohne Wirkung” to “World3DModel.setAlpha(float) nach Player.addWorldElement(WorldElement) ohne Wirkung - (GELÖST! Java-Version)”.

Participate now!

Don’t have an account yet? Create a new account now and be part of our community!