Jump to content
Unity Insider Forum

Dynamisch erzeugte HerzContainer bauen sich unterhalb des Bildschirms auf


Garzec

Recommended Posts

Hallo, 

Ich versuche das HerzContainer-System von Zelda zu kopieren. Das Updaten der Healthbar und das Aufbauen der Healthbar funktioniert auch wunderbar. Es gibt aber noch ein Problem bei der Platzierung der HerzContainer auf der Canvas.

Hier zuerst mal ein kleiner Ausschnitt des Codes, die Herzen werden korrekt erzeugt (Ich hoffe es ist ausreichend gut kommentiert).

Debugging bei der Positionsberechnung passt auch alles.

    private Transform healthBar = GameObject.FindGameObjectWithTag("HealthController").transform; // der Container für die "Herzen"

    private GameObject healthWrapperObject = Resources.Load("HealthContainer") as GameObject; // Das übergeordnete Hintergrundbild, das das eigentliche "Herz" beinhaltet

    private List<Image> healthContainers = new List<Image>(); // Liste aller "Herzen" für spätere Health Updates etc.

    private int maxHealth = 12;
    private int currentHealth;

    private int healthPerHealthContainer = 4; // 4 Leben pro "Herz"
    private int healthContainersPerRow = 5; // 5 "Herzen" pro Reihe

    private int healthContainerStartPositionX = 0; // Healthbar beginnt bei 0 auf x
    private int healthContainerStartPositionY = 0; // Healthbar beginnt bei 0 auf y

    private int healthContainerSpacingX = 10; // horizontaler Abstand
    private int healthContainerSpacingY = -10; // vertikaler Abstand

    private void Start()
    {
        currentHealth = maxHealth;
        InitializeHealthBar();
    }

    public void InitializeHealthBar()
    {
        int neededHealthContainers = maxHealth % healthPerHealthContainer == 0 ? maxHealth / healthPerHealthContainer : maxHealth / healthPerHealthContainer + 1; // Benötigte Container ermitteln
        int counter = 0; // Zählt die Herzen pro Reihe für den nächsten Umbruch
        int x = healthContainerStartPositionX; // Horizontale Position des Containers
        int y = healthContainerStartPositionY; // vertikale Position des Containers

        for (int i = 0; i < neededHealthContainers; i++)
        {
            counter++;

            if (counter >= healthContainersPerRow) // Umbruch nach 5 Herzen
            {
                x = healthContainerStartPositionX; // Wieder ganz links anfangen
                y += healthContainerSpacingY; // 1 Zeile tiefer
                counter = 0; // Zähler Reset
            }
            else
                x += healthContainerSpacingX; // nächsten Container weiterschieben

            Transform newHealthContainerTransform = Instantiate(healthWrapperObject, new Vector2(x, y), healthWrapperObject.transform.rotation).transform; // Das übergeordnete Hintergrundbild erzeugen
            newHealthContainerTransform.SetParent(healthBar); // Das übergeordnete Hintergrundbild der Healthbar hinzufügen
            healthContainers.Add(newHealthContainerTransform.GetChild(0).GetComponent<Image>()); // Das eigentliche Herz ermitteln und der Liste hinzufügen für weitere Aktionen
        }
    }

So, nun befinden sich die Herzen bei Spielstart unterhalb der Canvas (Bild). Beigefügt habe ich noch die Transform Einstellungen der Healthbar, des Herzen("HealthContainer" Container als Hintergrund) und des eigentlichen Herzen ("HealthFill"), also dem Bild, das sich verändert. Bei allen 3 Transform Einstellungen habe ich Strg+Shift+Alt gedrückt, also Position, Verankerung etc. gesetzt. 

Der Healthbar soll der erzeugte HerzContainer (verankert oben links) hinzugefügt werden und diesem dann das Herzobjekt (stretch, soll genauso groß sein, wie der HerzContainer).

Innerhalb der Schleife im Code wird x und y korrekt berechnet, aber bei Spielstart haben sie auf der y-Achse dann eine falsche Position, also außerhalb der Canvas.

Könnte mir jemand bei der GUI einen Tipp geben :)

Healthbar.png

HerzContainer.png

HerzObjekt.png

Ingame.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn ich das richtig verstehe: Du berechnest die Position der Herzen manuell?

Ich würde dir empfehlen https://docs.unity3d.com/Manual/script-HorizontalLayoutGroup.html zu nutzen. Der arrangiert dir die Elemente schön in eine Reihe und du kannst auch einstellen wieviel Abstand zwischen den einzelnen Elementen sein soll etc.

Für Zeilenumbrüche muss man da vielleicht noch etwas tricksen, weil dazu habe ich nichts gefunden. Aber das erspaart dir das errechnen von den Koordinaten

 

Edit: Für Zeilenumbrüche könnte https://docs.unity3d.com/Manual/script-GridLayoutGroup.html besser geeignet sein als HorizontalLayoutGroup.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich will nicht bestreiten das deine Berechnung korrekt sind. Nur sollte dein Code nicht vorgeben wie die GUI aussieht.

Einfaches Beispiel: Du willst nun das der Herzcontainer nicht mehr oben links sondern in der Mitte des Bildschirms ist. Nun müsstest du deinen Sourcecode anpassen / Hardcoded Werte anpassen.

Wenn du stattdessen ein Element zum ausrichten der Herzen benutzt, musst du nur das Element im Editor verschieben.

 

Ehrlich gesagt ich habe keine Ahnung warum deine Herzen an der falschen Stelle sind. Ich weiß nur das es viel leichter wäre auch die von Unity gegebenen Features zu nutzen, anstatt alles selbst zu implementieren.

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Für die Position der Herzen hatte ich ja aus diesem Grund die "HealthBar" genommen, als Parent der einzelnen HerzContainer.

Also ich verstehe was du meinst, ich würde aktuell aber gerne darauf hoffen, dass jemand eine Lösung für den Code hat, weil ich gerne unabhängiger von der Engine bin. Ich persönlich fühle mich wohler, wenn ich weiß, der Code würde mit ein paar kleinen Anpassungen auch ohne Unity funktioniere :)

- Solange der Code sauber bleibt -

Link zu diesem Kommentar
Auf anderen Seiten teilen

Je nachdem welchen Canvas Mode du ausgewählt hast wird das Canvas deine Koordinaten passend transformieren, deshalb sitzen die wohl nicht an deiner erwarteten Position. Anchors & Canvas Scaler tragen auch noch dazu bei. 

Wenn du dir also unnötiges Kopfzerbrechen ersparen willst, hör auf Djeurissen :)

Edit:

Dein Parent bringt da auch nochmal eine andere Dynamik rein, dann müssen zusätzlich dessen Anchors betrachtet werden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Canvas steht auf "Scale with ScreenSize". Aber gut, dann werde ich mir mal die "Grid Layout Group" anschauen. Ich hatte nur gehofft es wäre ein kleiner Fehler bzw. noch ein Einzeiler, den man im Code nachtragen müsste :/ Also sowas hier 

 

            Transform newHealthContainerTransform = Instantiate(healthWrapperObject, new Vector2(x, y), healthWrapperObject.transform.rotation).transform;

            newHealthContainerTransform.SetParent(healthBar);

	// richte dich richtig aus

            healthContainers.Add(newHealthContainerTransform.GetChild(0).GetComponent<Image>());

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nachtrag: Die Grid Layout Group sieht glaube ich passend aus, aber diese besitzt doch auch nur eine feste Größe, sprich sobald ich 3 Reihen mit jeweils 7 Herzen habe und das Grid voll ist, müsste dieses sich ja selbständig nach unten hin erweitern. Hoffen wir mal, dass sowas möglich ist :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hm also ohne die Grid Layout Group: Die Container kommen interessanterweise nur nicht in das Canvas rein... sie sind zwar Kinder der Healthbar und diese ist das Kind der Canvas, aber sie werden quasi ausgesperrt, deshalb sind sie unten angedockt. 

Ich habe jetzt verschiedene Möglichkeiten ausprobiert, die Container werden immer unter der Canvas erzeugt. egal ob mit Parent, ohne Parent oder sonst was.

Nachträglich kann ich im Inspektor aber ihre berechnete Position eingeben, das stimmt und funktioniert dann. Im Script kann ich aber nicht in der allerletzten Zeile sagen, 

containerTransform.position = new Vector2(x,y);


das wäre anscheinend wieder zu einfach, da bleibt der "Bug" noch bestehen ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...