Jump to content
Unity Insider Forum

Tacho mit GuiText - Probl. wegen versch. Auflösungen


Recommended Posts

Hallo,

 

ich bin neu hier und ich hoffe, ich werde für diese Frage nicht gleich zerfleischt, weil sie vielleicht schon x-mal in anderer/ähnlicher Form vorgekommen ist ;) Ich habe die Suchfunktion dieses Forums bemüht aber - genau wie bei meiner Suche im großen, weitem Internet - basieren sich alle Lösungsvorschläge auf GuiTexture oder GuiLabel usw. und ich würde irgendwo schon gerne bei meinen GuiText Objekten bleiben, da ich sonst einiges an Code umschreiben müsste. Ich befürchte zwar, dass mir am Ende nichts anderes übrig bleiben wird aber vielleicht kommt hier ja noch jemand mit einer überlegung, die ich selbst noch nicht gemacht habe.

 

Bevor ich zu meiner Frage komme, möchte ich - als Neuling hier - mich kurz vorstellen: ich bin 27 Jahre alt, männlich und lebe in Luxemburg. Ich bin auch gebürtiger Luxemburger und deshalb ist Deutsch - auch wenn ich es recht gut beherrsche - doch eine Fremdsprache für mich, weswegen ich gleich mal vorab um Entschuldigung bitte, sollten manche Sätze flapsig aufgebaut sein oder sich irgendwelche Schreibfehler in meinem Text finden lassen.

 

So, jetzt aber zu meinem Problem:

 

Ich beschäftige mich erst seit kurzem mit der Unity Engine - genauer gesagt sind's noch nicht mal zwei Wochen. Meine Programmiererfahrungen vorher waren Turbo Pascal, Delphi und dann viel später C#, als ich mit einem Kumpel anfing, ein XNA-Projekt für den Xbox Live Indie Games Channel zu entwickeln, welches aber leider nie das Licht der Welt erblickte.

Zwischen meiner letzten Programmierarbeit in Delphi und meinen ersten Schritten in XNA lagen einige Jahre und dass ich das letzte mal was in C#/XNA programmiert hatte, ist auch schon einige Monate her. Ich kann also programmieren, allerdings habe ich einiges an Rost angesetzt und bin teilweise sehr aus der übung.

 

Um mich daher mit der Unity Engine und deren Möglichkeiten vertrauter zu machen, wollte ich als Programmierübung und als Einführung in die Tools und Möglichkeiten von Unity ein Rennspiel programmieren, inspiriert von diesem Tutorial von Carsten Seifert.

Im Gegensatz zu ihm benutze ich aber kein grafisches Tacho mit Tachonadel, sondern wollte mit einem digitalen Tacho arbeiten.

 

Dafür habe ich zwei GuiText Objekte kreiert: Eines in dem lediglich "km/h" drinsteht, eines in dem ledigich "Gear:" drin steht und dann zwei weitere Objekte, die jeweils die Geschwindigkeit vor dem "km/h" Text anzeigen und eines, welches den aktuellen Gang hinter "Gears:" anzeigt.

 

Wer die überschrift dieses Topics gelesen hat, der weiß was jetzt kommt: In meinem Unity-Editor sowie wenn ich einen Build mit meiner Auflösung von 1920x1200 starte, sieht alles wie gewünscht aus. Starte ich aber testweise z.B. in 1024x768, so sind die GuiTexts ineinander verschoben.

 

Warum dies so ist, ist mir klar, da die Koordinaten der GuiText Objekte eben nicht relativ zur Auflösung angeordnet sind.

 

Nun dachte ich, ich könnte dies mit Scripting beheben, allerdings habe ich entweder einen Denkfehler gemacht oder ich verstehe die GuiText Komponente bzw. deren Eigenschaften wie z.B. PixelOffset falsch. Bei den GuiLabel etc. kann man ja recht einfach auf die Koordinaten der Label / Textures / whatever zugreifen, bei GuiText scheint dies nicht möglich zu sein.

 

Meine überlegung war folgende:

 

dies sind meine Script-Variablen für meine GuiText Elemente

//Speedometer GUI
var guiSpeed : GUIText;
var guiGear : GUIText;
var guiKmh : GUIText;
var guiGearNr : GUIText;

 

dann habe ich Variablen in meinem Script eingebaut, die die Default Auflösung (also die Auflösung, bei der bei mir alles gut ausschaut, in dem Falle also 1920x1200) festlegen sollen:

 

//default screen resolution
var defWidth : int = 1920;
var defHeight : int = 1200;

 

daraufhin wollte ich dann in der Funktion OnGUI mittels Variabeln ausrechnen, wie unterschiedlich das Scaling der effektiv benutzten Auflösung ist und um den Wert dann den PixelOffset der einzelnen GuiTexts erhöhen

 

function OnGUI () {
var widthScale = Screen.width/defWidth;
var heightScale = Screen.height/defHeight;

guiGear.pixelOffset.x = (guiGear.pixelOffset.x+widthScale);
guiGear.pixelOffset.y = (guiGear.pixelOffset.y+heightScale);

guiSpeed.pixelOffset.x = (guiGear.pixelOffset.x+widthScale);
guiSpeed.pixelOffset.y = (guiGear.pixelOffset.y+heightScale);


guiGearNr.pixelOffset.x = (guiGear.pixelOffset.x+widthScale);
guiGearNr.pixelOffset.y = (guiGear.pixelOffset.y+heightScale);


guiKmh.pixelOffset.x = (guiGear.pixelOffset.x+widthScale);
guiKmh.pixelOffset.y = (guiGear.pixelOffset.y+heightScale);
}

 

leider bringt dies genau ... nichts.

Auch eine Multiplikation statt einer Addition ändert genau gar nichts.

 

Hab' ich PixelOffset falsch verstanden? Ist diese überlegung von Grund auf falsch oder habe ich nur irgendwo einen kleinen Denkfehler begangen? Oder werde ich nicht drum herum kommen, auf Labels zurückgreifen zu müssen und dadurch im Code an einigen Stellen meine GuiText Variabeln auf Labels usw. umändern zu müssen?

 

Auf jedenfall schon mal Danke im Voraus für jeden, der sich diesen Roman durchgelesen hat und sich zudem zu einer (hoffentlich hilftreichen) Antwort durchringt :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo und willkommen im Forum!

 

Bevor ich jetzt auf GUIText eingehe, frage ich dich einfach mal, ob du dir OnGUI schon angesehen hast?

Mit den GUI-Methoden, die du in dieser Methode benutzen kannst, arbeitest du nicht im dreidimensionalen Raum. Das macht eben solche Sachen wie die Positionierung wesentlich einfacher.

Link zu diesem Kommentar
Auf anderen Seiten teilen

gibt es denn eine Methode, bei der ich einfach sagen kann "hey mein GuiText, beweg dich mal um x Pixel!"?

 

ich weiss dass es bei anderen Gui-Komponenten z.B. .position gibt oder dass man bei Texture z.B. mit dem Rect arbeiten kann und dort man auch Positionierungskoordinaten hat ... aber bei GuiText scheint's das nicht zu geben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gibt mal folgendes JS-Script irgendeinem GameObject:

var rect : Rect = Rect(20,20,400,400);
var texture : Texture2D;

function OnGUI()
{
   GUI.DrawTexture(rect, texture);
}

Dann noch eine Textur in die Eigenschaft "Texture" ziehen und das Spiel starten.

Nach belieben die Werte verstellen, während das Spiel läuft.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nichts für ungut, aber soweit war ich schon ;) sag ja im Posting über dir, dass ich weiss dass man bei einer Textur mit Rect arbeiten könnte.

Nur geht das halt so nicht mit GuiText, weil GuiText ja keine Textur ist, die ich einfach einem Rect zuweisen könnte. Ich will ja auch keine Textur malen, sondern den Wert einer sich stetig ändernden Variable anzeigen. (eben die Fahrgeschwindigkeit)

 

Was mich einfach nervt ist folgendes: im Inspector hat ein GuiText ja seine Koordinaten aber via Scripting scheint man nicht darauf zugreifen zu können ;) Ich kann nicht im OnGUI sagen z.B.

 

GuiText.position.x = irgendein Wert

 

sonst wäre das Problem schnell gelöst ...

 

im Internet haben ich Lösungen gefunden, wo ein Text z.B. in eine Gui.Box reingeschrieben wird usw. ... aber a) kann man da auch seine eigenen Fonts etc. wie bei GuiText zuweisen? und b ) müsste ich dann erstmal wieder alles umcoden ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

in unity sind positionen (sowie alle anderen Transformationen) im Transform Objekt enthalten und so auch beim GUI Text. D.h. du müsstest die Position eigentlich durch ändern des GuiText.transform.position ändern können. Wobei die Z-Positionskomponente zu vernachlässigen ist.

 

Die Koordinaten sind dort aber Auflösungsunabhängig, (0,5/0,5/0) ist in der Mitte...einfach mal etwas an den Werten herumspielen.

 

In Unity ist GUI aber sowieso eine Qual, ich würde da zur NGUI (kostenlos für nicht-kommerzielles) Bibliothek raten ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Kevin,

danke für den Tipp, scheint genau das zu sein, was ich gesucht habe. Ich werde morgen hoffentlich dann mal die Zeit finden, damit rumzuspielen und das hoffentlich gewünschte Ergebnis zu erzielen.

 

Bzw. GUI wird in diesem Rennspielchen jetzt erstmal sowieso nicht viel mehr als dieses Tacho angezeigt, von daher sollte es reichen. Sollte das Projekt irgendwann mal "mächtiger" werden, wird wohl eh die GUI komplett neu programmiert mit den verfügbaren Möglichkeiten die Unity so anbietet. Aber bis dahin will ich mich jetzt nicht mit dem "Kram" rumärgern sondern viel lieber an Fahrphysik und co. basteln, das ist interessanter ;) Daher wollte ich auch bei GuiText bleiben um es banal und spartanisch zu halten, bis dann vielleicht irgendwann mal eine "echte" GUI gemacht werden soll.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Howdi, ich hab nur den Startpost überflogen, daher mal ein Schuss ins Blaue.

 

Du versuchst ja deine Auflösungsunabhängigkeit dadurch zu erreichen indem du 2 Skalierungswerte berechnest, widthScale und heightScale. Ich weiß grade nicht wie es in UnityScript ist, aber in jeder andere Sprache ist es so, dass wenn du 2 Integer Werte miteinander dividierst, du auch einen Integer Wert wieder heraus bekommst.

 

1/2 = 0 (oder 1 je nach Rundungsverhalten, meist wird aber einfach abgerundet)

3/2 = 1

1024/1920 = 0 anstatt 0.53

etc.

 

Von daher würde dies hier nur ganze Zahlen generieren:

var widthScale = Screen.width/defWidth;
var heightScale = Screen.height/defHeight;

 

Da sowohl Screen.width, Screen.height, also auch defWidth und defHeight Integer sind.

 

Von daher versuche einfach das hier und es sollte funktionieren:

 

var widthScale = Screen.width/(float)defWidth;
var heightScale = Screen.height/(float)defHeight;

 

Alternativ kannst du auch defWidth und defHeight einfach als float definieren.

 

Dies hier ist auch falsch, da es bei jedem UI Durchgang (was mehrmals pro Frame passieren kann) ausgeführt wird und damit deine pixelOffsets immer weiter verändern wird.

 

guiGear.pixelOffset.x = (guiGear.pixelOffset.x+widthScale);

 

Du solltest solche Anpassungen also immer nur dann machen wenn es wirklich notwendig ist, zB in der Awake() oder Start() Methode deiner Komponente.

 

Auch würde ich es einfach so schreiben:

 

guiGear.pixelOffset.x *= widthScale;

 

Grüße

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Marrrk,

 

ja, das mit dem ständig verändern ist mir gestern Nacht noch aufgefallen, als ich bei einem weiteren Testlauf mein Tacho "weglaufen" sah :D

Ich hoffe heute abend nochmal Zeit zu finden mich dahinterzuklemmen und dann werde ich berichten, ob ich mein Problemchen gelöst bekommen habe :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...

Hi Sicho. für das Hud würde dir ich aber GuiText und GuiTexture empfehlen, weil das viel performanter ist. vorallem für bewegbare sachen. OnGui würde ich nur für komplezierte menüs benutzen.

 

kleines beispiel von mir

 

public GUITexture radarBg;
public Rect radarPos;
void Update(){
if("hier hab ich noch ne abfrage ob die auflösung sich geändert hat")
radarPos = new Rect(fromLeft + (Screen.width - radarWidth), fromTop + (Screen.height - radarHeight), radarWidth, radarHeight);
    radarBg.pixelInset = radarPos;
}

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...