Jump to content
Unity Insider Forum

Codeüberprüfung und Feedback gesucht!


Kokujou

Recommended Posts

Also vielleicht sag ich es nochmal überdeutlich:

Ich hatte eine Card-Klasse, die ich in der Awake durch ihren Konstruktor gesetzt habe, typisch indem ich gesagt habe Eigenschaft A = x, B = y ...

Dann hab ich ja den lieben Tipp bekommen ScriptableObjects zu nehmen. Also schreib ich in der klasse das ScriptableObject hintendran. Jetzt ist ja nix mehr bei Konstruktoren. Es sind 48 Karten, es war mir also zu blöd jede einzeln neu zu schreiben, ich hab gesehen das geht auch im Skript also ich ganz clever, den Konstruktor einfach umbenannt und umgebastelt mit nem bisl Textediting. Sodass der Konstruktor jetzt das SO erzeugt und dei Variablen setzt. Allerdings war dann der Name des Assets auch der Name der Karte in einer eigenschaft.

Dann hab ich getestet und plötzlich so einen krankhaften grundbösen Fehler bekommen "GetName kann nur innerhalb des MainThreads aufgerufen werden" oder so. Also hab ich nach einer endlosen Kaskade an Flüchen und "wtf"s einfach ne neue Eigenschaft "Name" hinzugefügt. Dann hab ich die konstruktoren selbstverständlich alle gelöscht und musste nur in der ersten Awake aufrufen "foreach Cards in AllCards Name = name".

Und danach stand überhaupt gar nichts mehr über dieses ScriptableObject, dessen Beschreibung oder sonst irgendein Zugriff in meinem Code. Stattdessen Lade ich sie indem ich sie alle in eine öffentliche Variable gepackt habe und dann nochmal in eine statische Variable geschrieben habe zwecks Zugriff. Das siehst du in der Global.cs

Es wäre echt praktisch wenn ich die Card-Klasse auch direkt als Komponente hinzufügen könnte, aber so nice ist man dann wohl nicht bei Unity ^^ Darum hab ich diesen blöden Schnipsel CardRef. Schade dass man nicht von SO und MonoBehaviour erben kann

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • Antworten 78
  • Created
  • Letzte Antwort

Tipp: Liegt nicht an Unity. Du machst irgendetwas falsch :)

Diese Sache mit dem programmatischen Erstellen von Assets ist einfach nicht, wie man das macht. Wenn du dein ScriptableObject einfach so erstellst und da etwas einträgst, dann bleibt das auch. Du überschreibst den Titel locker irgendwo in deinem Code. Oder du überschreibst das ganze Objekt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Und ganz nebenbei: einmal habich sogar einfach alles aus dem Git da wieder reingepastet. Auch das hat er ja wieder gelöscht. Ich garantiere dafür dass der Title nirgends im Code beschrieben wird. Ich hab es ja mal readonly gemacht. Im code hat er da nie gemeckert, was heißt: Keine Schreibbefehle. nur Unity hat es dann halt aus dem Asset ausgeschlossen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Minute schrieb Kokujou:

Es liegt NICHT in meinem Code.

Und das weißt du woher?

vor 2 Minuten schrieb Kokujou:

darum hab ich nach Speichermethoden gesucht.

Ja, aber du hast dich offenbar nicht informiert, wozu diese Sachen gut sind und wann man sie benutzt.

Ist vermutlich untergegangen, daher nochmal die Frage:

vor 6 Minuten schrieb Sascha:

Wo hast du denn überhaupt AssetDatabase.Blub und ApplyModifiedProperties eingebaut?

Ich bin mir ziemlich sicher, dass das Problem von der komischen Art kommt, wie du die Dinger erstellt hast.

Link zu diesem Kommentar
Auf anderen Seiten teilen

WEil es nunmal nicht bei Ausführung passiert sondern bei vom Skript unabhängigen Aktionen wie dem Laden einer Szene oder dem Schließen von unity

for (int i = 0; i < AllCards.Count; i++)
            {
                SerializedObject obj = new SerializedObject(allCards[i]);
                obj.Update();
                EditorUtility.SetDirty(allCards[i]);
                AllCards[i].Title = AllCards[i].name;
                obj.ApplyModifiedProperties();
            }
            for (int i = 0; i < allYaku.Count; i++)
            {
                SerializedObject obj = new SerializedObject(allYaku[i]);
                obj.Update();
                EditorUtility.SetDirty(allYaku[i]);
                allYaku[i].Title = allYaku[i].name;
                obj.ApplyModifiedProperties();
            }
            AssetDatabase.SaveAssets();

Also dass das Forum die VS Formate nicht unterstützt ist schon doof >.< keine Lust diese Leerzeichen einzeln zu löschen.

Das findet alles in der Awake()-Routine start... ja ich weiß es ist schrecklich aber ich hau jetzt alles rein da mir sonst nichts mehr einfällt XD

TATAAA ES HAT FUNKTIONIERT! Fürs erste zumindest >.< SetDirty war die Lösung. Weiß der Geier warum. Nagut n bisl nachvollziehen kann ichs. In meinem Code mach ich's nicht aber das SO soll wohl standardeinstellungen laden und dann für die Dauer eines Spiels gemoddet werden. Skripting als Massen-Text-Editing ist wohl nicht so das vordringliche Ziel XD

Link zu diesem Kommentar
Auf anderen Seiten teilen

So, da haben wir's doch. Warum zum Geier fummelst du da irgendwo in Awake herum? Die ScriptableObjects sollten zur Laufzeit bereits alle Informationen haben. Das SerializedObject ist auch völlig sinnlos.

Das "Title"-Feld ist dazu da, den Titel der Karte oder so einzutragen. Diese Verbindung zu .name sollte damit Vergangenheit sein, sonst nützt das überhaupt nix.

Link zu diesem Kommentar
Auf anderen Seiten teilen

kommt drauf an. Am Ende häätte es nicht funktioniert und alles umsonst. Denn wie gesagt ich hatte ja sogar mal die völlig korrekten Files da reingepackt und auch die hatte er wieder überschrieben^^ stell dir mal du müsstest die Fummelei jedes mal machen. Da wird man wahnsinnig

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Minute schrieb Kokujou:

Editor-Skript? erzähl mal was ist das wie sieht das aus?

Es gibt Editorskripte, welche den Unity Editor um eigene Werkzeuge erweitern und Custom Inspector, womit Du den Inspector eines Objektes beeinflussen kannst. Ein guter Einstieg ist denke ich diese Seite https://unity3d.com/de/learn/tutorials/topics/scripting/introduction-editor-scripting

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gibt verschiedene Sachen, die du im Editor machen kannst - von Scene View-Gizmos über eigene Inspektoren, PropertyDrawern und Editorfenstern zu ausführbaren Aktionen.

In deinem Fall ginge vermutlich sowas:

[MenuItem("Do Stuff/Set Yaku and Card Names")]
private static void SetYakuAndCardNames()
{
  // Do Stuff in Editor
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es ist nicht davon auszugehen, dass du bei zehn Karten mit aktivem Raycasting Performance-Probleme kriegst, aber die Frage ist: Warum?

Der Witz am Raycast ist ja, dass du einfach mal irgendwo hinzielst und schaust, was da ist. Das heißt, ein einzelner Raycast gibt dir schon die Karte zurück, auf die man klickt. Mehrere Raycasts zu machen, um das Ergebnis dann wiederum in "war das denn ich" umzubauen, um diese Ergebnisse aller Karten dann wiederum zusammenzusetzen, um zu erfahren, welche Karte ausgewählt wurde, ist ein unschöner Umweg.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja meine letzten Verbesserungen sind nur im Punkto Codequalität XD

Der schritt war weniger aufs Raycasting gemünzt aber es wäre halt cool wenn eine Karte die auf sie bezogenen Aktionen durchführen könnte.
Hovering, Klick-Aktionen und Skripte, Triggern anderer Events etc...

Schön wäre es ja wenn ich einfach n OnClick-Event einbauen könnte... Aber ich schätze mal ein Button-Skript kann ich nicht drauf legen oder? XD

Mir ging es halt größtenteils darum das alles aus der Hauptklasse rauszukriegen, denn wenn ich alles nur mehr oder weniger in eine Klasse schreibe dann ist das wohl irgendwie schlechter Stil und neher an imperativer Programmierung als an OOP, besonders wenn ich jetzt vorhabe zwei größere Klassen zusammenzufügen, weil ich gemerkt habe dass Klasse B zu 50% aus Verweisen an Klasse A besteht XD

Erst dachte ich daran ne Klasse für das ganze Input-Handling zu bauen aber auch das klingt nicht so prickelnd vor allem weil man halt wieder viele Verweise braucht.

aber wenn das scheiße ist dann überleg ich mir was besseres... mal gucken wie es wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 13 Stunden schrieb Kokujou:

Schön wäre es ja wenn ich einfach n OnClick-Event einbauen könnte...

Klar kannst du das!

vor 13 Stunden schrieb Kokujou:

Aber ich schätze mal ein Button-Skript kann ich nicht drauf legen oder? XD

...aber nicht so! :)

Packste das hier auf die Kamera:

using UnityEngine;

[RequireComponent(typeof(Camera))]
public class CardRaycaster : MonoBehaviour
{
  new private Camera camera;
  
  private void Awake()
  {
    camera = GetComponent<Camera>();
  }
  
  private void Update()
  {
    if (Input.GetMouseButtonDown(0))
    {
      var ray = camera.ScreenPointToRay(Input.mousePosition);
      RaycastHit hit;
      if (Physics.Raycst(ray, out hit))
      {
        var hitCard = hit.collider.GetComponent<InteractiveCard>();
        if (hitCard)
        {
          hitCard.Interact();
        }
      }
    }
  }
}

und das auf deine Karte, wo auch der Collider sitzt:

using UnityEngine;
using UnityEngine.Events;

[RequireComponent(typeof(Collider))]
public class InteractiveCard : MonoBehaviour
{
  [SerializeField]
  private UnityEvent onInteract;
  
  public void Interact()
  {
    onInteract.Invoke();
  }
}

Die Vorkommen von Collider und Physics kann man noch auf 2D umstellen, und statt des Mauszeugs kann man auch gut Touchzeugs machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

hey so ähnlich hab ichs tatsächlich gemacht :)
 

Ich musste etwas Fummeln, weil so viel Hintergrundwissen aus anderen Klassen benötigt wird... Aber am Ende liefs auf Kommandos hinaus.

In der Player-Klasse wird jetzt der Input gehandhabt. Da switche ich dann zwischen zwei Funktionen für die Update-Routine die ich durch Kommando einstellen kann.

In der Player-Klasse die direkten Zugriff auf die Hände hat wird das Hovern der Karte geregelt und dann in der Funktion der Spielfeld-Klasse mitgeteilt, welche Karte gehovert wurde damit sie die passenden Feldkarten highlighted. Und wenn man dann auf dem Feld auch noch aufrufen muss ruft die Spielfeld-Klasse RequestInput() auf und die Player-Klasse schaltet quasi auf die zweite Update-Routine.

Zu finden in meinem neusten GitHub Skript^^

Das alleinige Hovern liegt jetzt tatsächlich auf der Karten-Komponente die vorher völlig leer war aber die Koordinierung des Hovers (es muss ja auch das vorherige "geunhovert" werden XD) übernimmt wieder das Spielfeld etc... kannst ja mal bei allem drübergucken was ich heute committet habe... hab nen neuen Branch eingerichtet weil die Änderungen von den Grundfunktionen das ganze Spiel zurückwerfen XD

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

Ankündigungen


Hy, wir programmieren für dich Apps(Android & iOS):

Weiterleitung zum Entwickler "daubit"



×
×
  • Neu erstellen...