Jump to content
Unity Insider Forum
Sign in to follow this  
  • entries
    14
  • comments
    32
  • views
    42,207

About this blog

Mein Gelerntes, Mein Erfolg, Meine Hilfe

Entries in this blog

 

Endlich! Master Server Framework im Asset Store!

[b][size=6]Master Server Framework (Beta $40 statt $50)[/size][/b]

Jungs und Mädels.
Ich habe schon länger auf diesen Moment gewartet. Endlich. Es gibt im Asset Store den "Master Server Framework" und gerade noch in Beta. Daher weiterhin im Entwicklung und könnt quasi eure Wünsche einbringen und sie wird vielleicht implementiert.

Allgemein ist das ein Framework, was sich erweitern lässt. Das Framework nimmt einige arbeiten der Entwickler zum Thema-Server backend ab. Quasi etwas für MMO? Oder Multiple Server? Verzicht auf Unity Service oder Photon Cloud Server und deren Gebühren?

[b][size=5]Warum begeistere ich mich aber für diesen Package?[/size][/b]
Was macht es (für mich) besonders?
Eigentlich ist das ein Framework. Das heißt, dass man immer noch selbst Coden müsste, um überhaupt Features zu haben, aber es wurden "Module" eingebaut.

Für mich ist das hier das wichtigste:[list]
[*]Es hat ein [b]Auto start / close Server[/b] Feature, dass heißt, wie bei Photon Cloud werden server gestartet. Damit kann ich auf Photon verzichten. Nicht nur das. Hier braucht man auch keine sorgen über NAT machen.
[/list]
Aber folgendes gibt es auch:[list]
[*]Authentication - Registration und Einloggsystem
[*]Spielerprofile
[*]Lobbysystem / Gameserver - Die Server werden also gelistet und man kann auch vorher sich in der lobby sehen. Auch shoppen und so weiter geht. Spielerprofile anschauen. Stell mir das ungefähr wie bei Dota 2 oder so vor.
[*]Spawner Servers: Das was ich oben schon sagte:
[*]Chat: Private Nachrichten oder Globale
[/list]
Das System ist so aufgebaut, dass man mit verschiedenen Network Solution arbeiten kann. Das heißt Bolt, Forge Networking, UNet usw.

Weiterhin sollen auch viele andere Dinge kommen:[list]
[*]Admin UI (to manage servers, connected users and etc.)
[*]MMO-like Instances module
[*]Matchmaker with Queues and automatic server starting [b](für mich sehr wichtig)[/b]
[*]Friends and Guilds / Clans
[*]Shop functionality
[*]Leaderboards
[*]Forums
[/list]
Diesen Queuesystem könnte ich noch selber kriegen, da ja schon server autostart und so gibt, aber warum nicht.

Hier zum Paket.
[url="https://www.assetstore.unity3d.com/en/#!/content/71391"]https://www.assetsto...!/content/71391[/url]


Hier zum Forum:
[url="https://forum.unity3d.com/threads/master-server-framework.430570/#post-2812490"]https://forum.unity3...0/#post-2812490[/url]

Falls euch das interessiert postet ruhig eure Vorschläge.

MaZy

MaZy

 

Motivation - Linksammlung, Unity WebGL Multiplayer

Hey,

das ist jetzt kein natürlicher Blogeintrag, wo ich meine Gedanken freilaufen lasse.
Ich werde hier mal ein paar Links listen (und weiter führen).
Diese Links beinhalten webgl Spiele mit Unity und sollen zur Motivation dienen. Sie wurden ca. so wie Agar.io oder Slither.io aufgebaut. Mich motiviert es auf jeden fall und hoffentlich euch auch.[list]
[*][b][url="http://PIRANH.IO"]PIRANH.IO[/url][/b] - WebGL, Photonnetwork
[*][b][url="http://GUNR.IO"]GUNR.IO[/url] (Beta)[/b] - WebGL, Websync (nicht sicher, was genau)
[/list]
Mir spezial macht [b]Gunr.io[/b] sehr spaß, aber ist nur am Laggen. Finde ich sehr schade. Soll aber beta sein.

MaZy

MaZy

 

Man, immer wieder wird Mikrofonlautstärke verstellt.

[center][size=6][font=lucida sans unicode,lucida grande,sans-serif][b]Heute mal nichts mit Unity[/b][/font][/size][/center]

[size=4][font=lucida sans unicode,lucida grande,sans-serif]Wer kennt das Problem nicht? Man startet ein Spiel, ein Programm oder sonst was, dass das Mikrofonlautstärke bei Windows-Aufnahmegeräten einfach umgestellt.[/font][/size]

[size=4][font=lucida sans unicode,lucida grande,sans-serif]Ich benutzt ein Standmikrofon. Das Mikrofon ist für Musik, oder Podcast aufnahmen gedacht. Daher reichen mir die 10% Einstellungen in der Aufnahmegeräte. Wird es ca. 20 ist es schon zu laut. Bei 100% ist es unmöglich laut. Da hört man auch die Leute aus der Nachbarschaft reden.[/font][/size]

[size=4][font=lucida sans unicode,lucida grande,sans-serif]Und das ist mein Problem. Warum müssen Entwickler immer so programmieren, dass ihre Programme die Mikrofonlaustärke ändern, obwohl man selber als Benutzer nicht da rumfummelt?[/font][/size]

[size=4][font=lucida sans unicode,lucida grande,sans-serif]Weil ich mich das tierisch genervt hat, habe ich in C# mein eigenes Programm entwickelt.[/font][/size]






[center][font=lucida sans unicode,lucida grande,sans-serif][b][size=6]Microphone Level Resetter[/size][/b][/font][/center]



[center][font=lucida sans unicode,lucida grande,sans-serif][img]http://i.imgur.com/oewkA9G.png[/img][/font][/center]

[font=lucida sans unicode,lucida grande,sans-serif]Dieses Programm kann Einstellung des Benutzers benutzen, um zu überprüfen, ob sich etwas verändert wurde. Man kann es zum Tray (unten rechts zu den Symbolen) minimieren und im Hintergrund laufen lassen. Somit verfliegen alle "meine" Sorgen über die Lautstärke, denn es setzt ja wieder zurück [/font]

[font=lucida sans unicode,lucida grande,sans-serif]Falls ihr sowas auch braucht. Der Download dazu: [/font][url="http://bit.ly/20Q7yTm"]http://bit.ly/20Q7yTm[/url]

[font=lucida sans unicode,lucida grande,sans-serif]Eine kleine Erklärung zu Microphone Level Resetter als Video.[/font]
[font=lucida sans unicode,lucida grande,sans-serif][media]http://www.youtube.com/watch?v=qcJC92G1wmc[/media][/font]

MaZy

MaZy

 

UNet, Photon, nein ich gehe zu Lidgren (oder alternativ zur Bolt)

[size=6][font=courier new,courier,monospace][i]Keine Zeit mehr zu warten.[/i][/font][/size]

(Der Text wurde sehr spät. bzw früh mit Müdigkeit und Mühe geschrieben. Eventuell gefundene Fehler werden bald mit einem Update gefixt )

[font=courier new,courier,monospace][size=6][b]UNet[/b][/size][/font]
[font=courier new,courier,monospace][size=1]-[/size][/font]
[font=courier new,courier,monospace]Ich habe mich mit UNet auch intensiv beschäftigt. Ich muss leider sagen, dass es nicht wirklich meine Wünsche befriedigt. Ist egal, ob es jetzt seine Endphase nicht erreicht hat, aber wie sich das entwickelt zeigt schon, dass ich doch bei der alten Network bleiben muss, oder meine eigene brauche.[/font]

[font=courier new,courier,monospace]UNet ist toll, wenn man diesen NetworkManager benutzt und seinen zwei Szenen klatscht. Was aber, wenn man mehrere hat? Steht nicht viel dazu. [/font]
[font=courier new,courier,monospace]UNet bietet auch Cloudserver an, was total schön ist für Spiele die sehr dynamisch aufgebaut sind (So wie bei LoL, Dota 2: Spiel / Match suchen / finden -> Server wird bereitgestellt -> Spiel beenden -> Server wird für die nächsten Matches verfügbar gemacht)[/font]

[font=courier new,courier,monospace]Doch was ich bei UNet bemerkt habe ist, entweder du hast es sehr simple oder sehr schwer. Das hat sogar ein Unity-Crew gesagt in einer Demonstration. Entweder leicht haben oder sich Schwer machen. So ähnlich wurde es gesagt. Ich muss sagen ich finde es schwerer als altes Netzwerksystem.[/font]

[font=courier new,courier,monospace]Warum?[/font][list=1]
[*][font=courier new,courier,monospace][b]PlayerController[/b]: Ist eine Klasse aus Networking. PlayerController ist quasi sowas wie NetworkPlayer. Hat eine Variable PlayerController.[b]gameObject[/b]. Da steht, dass es einen Player GameObject gibt. Was wenn wir RTS spiele machen und viele Einheiten steuern? Wo ist dann Player GameObject.[/font]
[*][font=courier new,courier,monospace]NetworkServer und NetworkClient ist zu kompliziert gemacht. Man weiß gar nicht, wann man was braucht. Ich habe echt lange gebraucht bis ich das hinbekommen habe.

[b]NetworkServer.Listen(port)[/b] und [b]NetworkClient client = new NetworkClient()[/b]
brauchen Konfigurationen bevor sie laufen. Das finde ich ja noch ok, weil man da vieles einstellen kann, aber mache Dinge machen keinen Sinn. Für beiden kannst du die Maximale Connection einstellen. Wieso? [/font]
[*][font=courier new,courier,monospace]Viele Namen werden komisch verwendet, die nicht das Aussagen, was eigentlich tut. AddPlayer ist jetzt zum Beispiel bedeutet, dass man einer Verbindung ein GameObject zuweist (Quasi sagen dieser Spieler darf diesen GameObject kontrollieren).[/font]
[*][font=courier new,courier,monospace]Zu sehr auf Lobby Spiele fixiert.. Spieler müssen sogar "ready" sein um weiter zu kommen.[/font]
[*][font=courier new,courier,monospace][b]Command[/b] und [b]RpcClient[/b] sind auch nette Attributen.[/font]
[font=courier new,courier,monospace]Command werden von Clients (Zitat: aus Spielerobjekten) an andere Spielerobjekte gesendet. Daher Server als Spielerobjekt kriegt es eventuell auch. [/font]
[font=courier new,courier,monospace]Z.B: CmdDoFire().[/font]

[font=courier new,courier,monospace]RpcClient sendet von Server Objekten an Objekten von Clients[/font]
[font=courier new,courier,monospace]RpcKill()[/font]

[font=courier new,courier,monospace]Beide Attributen zwingen entweder Cmd oder Rpc als Anfangsbuchstaben für eine Funktion zu benutzen. Gar nicht toll!!. Sieht Später richtig unübersichtlich aus.[/font]

[font=courier new,courier,monospace]CmdDoFire()[/font]
[font=courier new,courier,monospace]RpcKill()[/font]

[font=courier new,courier,monospace]Hier muss man kein networkview.RPC oder sowas ausführen. Hier kann man Direkt den Methoden Namen schreiben und es ist automatisch an andere versendet.[/font]

[font=courier new,courier,monospace]Vielleicht merkt ihr das Problem[/font]
[font=courier new,courier,monospace]Command: Client an Clients & Server[/font]
[font=courier new,courier,monospace]RpcClient: Server an Clients[/font]

[font=courier new,courier,monospace]Wo ist von Server an Server und Clients.. gibst nicht. Und das doofe ist, dass die Methoden RpcKill bei sich selber nicht funktioniert. Man ist also gezwungen noch eine Funktion Kill() zu schreiben, wo nochmal die gleichen Sachen stehen. Das ganze zwei Mal machen nein Danke.[/font]
[*][font=courier new,courier,monospace]Ist schwer zu beschreiben. Ich hatte eine Klasse wo ein NetworkView Component war. dort hatte ich auch ein Script wo viele Funktionen gab. Sowas wie ChangeName, Chat. So allgemein Dinge halt. Ich musste den Component nur linken. Dann hatte ich sowas wie GlobalNetworkview.RPC("methode, All, bla, bla). Das geht noch so mit UNet. Allerdings ist das Problem bei Playerobjekten. Die Skripte müssen quasi das gleiche seine um etwas Synchron zu machen.

Stellt vor. Mein GlobalNetworkview wäre für alles. Da bekomme ich die Position, die Rotation von Objekten, Chat nachrichten alles einfach.

Jetzt ist das nicht mehr möglich[/font]
[/list]
[font=courier new,courier,monospace]Wie man sieht [size=5][b]zwingt[/b][/size] mich UNet zu Dingen, die ich gar nicht möchte und vor allem nicht brauche, wie mit PlayerObjekten zuweisen.[/font]


[font=courier new,courier,monospace][size=6][b]Photon Cloud[/b][/size][/font]
[font=courier new,courier,monospace][size=1]-[/size][/font]
[font=courier new,courier,monospace][size=4]Photon ist gut. Leider aber können die Pings manchmal hoch sein 80-120. Gute Pings sind im Vergleich 10-40.[/size][/font]
[font=courier new,courier,monospace][size=4]Daher passieren auch doofe Lags und Verzögerungen im Spiel die man bisschen umgehen kann ( "visuelles Faken" nenne ich das )[/size][/font]

[font=courier new,courier,monospace]Photon Cloud kostet, aber bis 20 concur kostenlos, 100 ConCur einmalig 90$ glaub ich war das. Geht noch so.[/font]

[font=courier new,courier,monospace]Das Problem ist, dass ich schon mal geschafft habe, dass ich 90.000 Spieler gleichzeitig bei meinem App sich aufgehalten haben. Wie soll man Später sowas bei Photon Cloud finanzieren. Damit mach ich nicht das Geld, womit ich das finanzieren könnte.[/font]

[font=courier new,courier,monospace]Außerdem gibst hier riesen fetten Nachteil. Kein serverseitiges Programmieren. Alles läuft über ein Spieler (als hätte er das Spiel gehostet).[/font]
[font=courier new,courier,monospace]Ich will, aber auch das können.[/font]



[font=courier new,courier,monospace][size=6][b]Bolt[/b][/size][/font]
[font=courier new,courier,monospace][size=1]-[/size][/font]
[font=courier new,courier,monospace]Bolt wird jetzt auch von Exitgames entwickelt (von Photon Leuten). Leider weiß ich noch nicht viel darüber, aber anscheinend wollen die Matchmaking mit einplanen, die durch ihren Photon Cloud System laufen wird. Ob es auch nen Auto-Matchmaking haben wird ist ne andere Sache. Genau aber das werde ich brauchen.[/font]
[font=courier new,courier,monospace]Da ich wenig Zeit habe brauche ich eine Alternative.[/font]
[font=courier new,courier,monospace]Bolt ist eine Erleichterung was Programmierung an geht, wenn es um Networking geht. Viele Lösungen wie zum Beispiel Animation Synchronisierung wird da angeboten. Außerdem wird alles über Unity programmiert . Konsole sowie Dedicated soll auch geben.[/font]


[font=courier new,courier,monospace][size=6][b]Unity Networking (altes)[/b][/size][/font]
[font=courier new,courier,monospace][size=1]-[/size][/font]
[font=courier new,courier,monospace]Die besten Erfahrungen habe ich damit gemacht. Bietet nicht viel an, aber dafür hat man andere brauchbaren Dinge. Hier kann man schön eigenen Server programmieren. Ein Beispiel zu meinem Spiel. Ich habe ein Server programmiert, wo man die Welt aber nicht sieht (denn es war nicht autoritativer Server), jedoch sollte irgendwo konstant ein Server laufen, wenn man das wollte. Zack programmiert fertig.[/font]

[font=courier new,courier,monospace]Bei einem anderen Beispiel war alles auf dem Server. Kollisionen usw wurden da auch überprüft. Das geht mit Bolt auch, aber nicht mit Photon Cloud und eventuell mit Lidgren.[/font]

[font=courier new,courier,monospace]Leider lässt angeblich die Perfomanz bei vielen Spielern nach. Habe ich bis jetzt erlebt.[/font]

[font=courier new,courier,monospace]Großer Nachteil für mich. Kein auto-matchmaking.[/font]
[font=courier new,courier,monospace]Wer mein Blog verfolgt hatte, hatte gesehen, dass ich das damit am Lösen war. Das Problem ist, dass es etwas machbar war, aber es wäre auf deutsch gesagt "scheiße" gelaufen. Sehr viel Fummelarbeit.[/font]

[font=courier new,courier,monospace][b]Lidgren[/b][/font]

[font=courier new,courier,monospace][size=1]-[/size][/font]
[font=courier new,courier,monospace]Lidgren ist kein Service wie bei UNet, Photon und Bolt, sondern man muss echt von Null Anfangen. Lidgren ist ein Allgemeines Networking für C# .Net.[/font]
[font=courier new,courier,monospace]Das heißt man müsste erst mal Unity dazu bringen Lidgren zu verstehen und Lidgren dazu bringen Unity zu verstehen (Plugins, Coding usw).[/font]

[font=courier new,courier,monospace]Ich habe damit angefangen muss sagen, dass es mir bis jetzt Spaß macht. Endlich mal, wo ich weiß, dass ich alles mir erstellen könnte, was ich so brauche. Denn ich fange von Null an und kann meine Wünsche mit einbauen.[/font]
[font=courier new,courier,monospace]Wird vielleicht länger dauern, schwer sein, aber, wenn ich überlege werde ich mehr Zeit sparen als auf UNet zu warten, als über Photon kosten auf zu regen.[/font]
[font=courier new,courier,monospace]Man auch mal richtigen dedicated Server mit ner Konsole machen [/font]

[font=courier new,courier,monospace][size=5][b]Und was genau mach ich da? [/b][/size][/font]
[font=courier new,courier,monospace]Ich sage mal so. Bin ungefähr bei 40 %. Ich habe nun Lidgren und Unity kennenlernen lassen. Ich kann Server erstellen und kommunizieren lassen. Bis jetzt waren das nur Texte, aber vieles wurde vorbereitet. die ganzen Standard Sachen wie Vectoren, Quaternion, int, float habe ich eingebaut.[/font]

[font=courier new,courier,monospace]Vieles fehlt noch. Derzeit arbeite an einem System, wo man auch zukünftig, andere mit Leichtigkeit hosten lassen kann.[/font]

[font=courier new,courier,monospace]Eventuell werde ich meinen eigenen Auto-Matchmaking schreiben. Wir gucken mal weiter.[/font]

[font=courier new,courier,monospace]Der Anfang[/font]
[font=courier new,courier,monospace][img]http://puu.sh/jRd9u/286bfeb13a.png[/img][/font]
[font=courier new,courier,monospace]Wie man auf dem Bild sieht hoste ich mit ner Konsole. Und da ist auch ein Message von einem Client angekommen als "Broadcast" mit "this is a test"[/font]
[font=courier new,courier,monospace]Und in der Unity Console sihet man, dass der Server auch was zurück geschrieben hat.[/font]

[font=courier new,courier,monospace]Und dazu hab ich ne eine DemoKlasse gemacht:[/font]
[font=courier new,courier,monospace][img]http://puu.sh/jRgV6/3abae0ae7a.png[/img][/font]

[font=courier new,courier,monospace]Wie man hier sieht habe ich sowas änhnliches wie beim UNet "ULGNetworkbehavior". Dort wird Global eine Verbindung aufgebaut, sei es als Server oder Client. Gott sei Dank geben bei dir den Peer connection zurück, wobei ich dann nicht NetServer oder NetClient benutzen muss. Würde einfach doppel zu viel Arbeit machen.[/font]

[font=courier new,courier,monospace]Wenn man Connect macht (Eventuell, werden diese namen verändert).[/font]
[font=courier new,courier,monospace][img]http://puu.sh/jRgTX/b498c72601.png[/img][/font]
[font=courier new,courier,monospace]Dummerweise kann nicht wirklich FailConnection auswendig machen. Da kriegt man auch einfach Disconnectereignis. Vielleicht schicke ich bei der Disconnect Event noch eine Meldung (Grund Paramater) hinterher und die Entwickler können selbst entscheiden, obwohl sie danach überprüfen. Mal sehen.[/font]

[font=courier new,courier,monospace]Derzeit sieht der Ordner so aus:[/font]
[font=courier new,courier,monospace][img]http://puu.sh/jRhhp/6e3854da43.png[/img][/font]


[font=courier new,courier,monospace]NetMessage ist einfach eine Hilfe um die Unity-Typen besser zu senden. Mit nem[/font]
[font=courier new,courier,monospace]Netbuffer.WriteVector3(Playerpos) kann man seine Position über das Netzwerk senden.[/font]
[font=courier new,courier,monospace]mit NetBuffer.ReadVector3() kriegt man dann die Position wieder.[/font]

[font=courier new,courier,monospace]Falls ihr ideen habt immer her damit.[/font]
[font=courier new,courier,monospace]Ich habe extra nen Trello erstellt. Eigentlich für mich persönlich, aber auch falls ihr Ideen habt.[/font]

[font=courier new,courier,monospace]Der Text wurde sehr spät. bzw früh mit Müdigkeit und Mühe geschrieben. Eventuel gefundene Fehler werden bald mit einem Update gefixt [/font]

MaZy

MaZy

 

Easy-Doings: Debug.Log mal anders

[size=6][b]Worum geht es hier?[/b][/size]
Ihr benutzt wahrscheinlich wie ich immer wieder Debug.Log(""). Manchmal verwendet man einfach zu viele. Man vergisst auch manchmal sie zu entfernen oder man ist einfach viel zu faul dafür.
Daher kann man ja mal die Funktion etwas verbessern. So kann man mit einer Boolean die ganzen Logs ausschalten lassen. Ist praktisch, um die ganzen Debug.logs nicht zu löschen, falls man ja immer noch später Debuggen will.

Daher mal nen kleinen Code was ich mir geschrieben habe.

[CODE]
using UnityEngine;

public static class Logger
{
static bool ShowDebug = true;
public static void Print(string str)
{
if (!ShowDebug)
return;
Debug.Log(str);
}
}
[/CODE]

So, ich habe die Klasse Logger genannt. Wollte es simpel haben und auch mich schnell daran erinnern können, was Logger macht oder wie es heißt. Kommt von Log, loggen, daher kann man das kaum vergessen. Wie man hier sieht ist es eine statische Funktion und hat kein Monobehavior. Daher kann man diesen Script nicht als Component benutzen.

Die Klasse hat die ne static boolean und ne public static Funktion "Print", wo ihr dann den Log-Text als String übergeben könnt, welches wiederum zur Debug.Log() Funktion geht und dort ausgeführt wird. Jedoch wird mit boolean vorher überprüft ob wir Debug anzeigen wollen oder nicht.

Einfach auf falls, weils ihr einen Build starten wollt.

Nun könnte man eventuell das erweitern und Bespiel sowas wie Config.ShowDebug machen, aber das ist euch überlassen. . Sowas ist nützlich, falls ihr wollt, dass die Spieler eventuell Logs aktivieren können. Denn Unity erstellt immer eine Logdatei, wo alle Debug abgespeichert sind. Das kann uns mal die Entwicklung erleichtern.

[size=5][b]Wie wendet man das nun an?[/b][/size]
[CODE]
void Start()
{
Logger.Print("Start ausgeführt");
}
[/CODE]

Ist nun ShowDebug auf falls, so sollte nichts in der Konsole angezeigt werden.
Yow das wars

MaZy

MaZy

 

Auto-Matchmaking #4: Serverstart erleichtern.

[font=lucida sans unicode,lucida grande,sans-serif]Hallo Leute,

diesmal habe ich nicht viel machen können aus Zeitdruck.
Ich habe ja in der letzten Teil gesagt, dass ich zwei Projekte in einem Unity-Projekt mache. Den "Cloudserver" bzw "Gameserver" und den "Masterserver". Dazu hab ich logischerweise zwei Szenen erstellt wo jeweils die GameObjects mit Scripts darauf warten gestartet zu werden.

Das Problem wäre hier, dass ich beim Compilen immer die erste Szene verändern müsste, damit die Szene beim Start geladen wird. Außerdem hätte ich dann zwei verschiedene "Spiele" bzw. Server. Das mochte ich gar nicht.

Daher habe ich 3 Szenen erstellt wo ich quasi am Anfang was auswählen KÖNNTE. Jedoch gefiel mir dieser Gedanke auch nicht. Warum? Unity hat zum Beispiel "-background" als Commandline implementiert. Damit kann eine Unity-Instanz angeblich ohne 3D oberfläche gestartet werden. Das ist sehr gut als Serverinstanz benutzbar. Commandlines sind die man hinter jeder Ausführung anhängen kann. Damit kann man quasi beim Programmstart ein Befehl mit geben. Meistens macht das per Verknüpfung erstellen und in der Eigenschaft einstellen, aber man kann auch eine BATCH Datei erstellen oder in Linux eine Shell Datei erstellen und so die Parameter übergeben. Und genau diesen Background will ich später benutzen. Wieso soll das Spiel ganze Zeit geöffnet sein, wobei es so oder so nur als Server dient und sonst nichts?

Daher habe ich an einer Lösung gedacht. Eigene Commandlines erstellen. Habe dazu zwei batch Dateien erstellt.
Die in der selben Ordner wie die .exe Datei ist. So sieht das dann aus.

[CODE]Dateiname: start_gameserver.bat
Inhalt: Matchmaking.exe -port 23000 -startserver

Dateiname: start_matchmaker_server.bat
Inhalt: Matchmaking.exe -port 24130 -matchmakingserver[/CODE][/font]
[font=lucida sans unicode,lucida grande,sans-serif]Hier fehlt noch -background. Das habe ich erst mal weggelassen.[/font]
[font=lucida sans unicode,lucida grande,sans-serif]Demonstration mit Video
Klickt dazu auf das Bild.

[url="http://puu.sh/iB2jw/99d30cedf9.mp4"][img]http://puu.sh/iB2F0/2e33a78387.png[/img][/url][/font]

[font=lucida sans unicode,lucida grande,sans-serif]Der Vorteil hierbei ist, dass der Gameserver mit verschiedenen Ports gestartet werden kann, wenn mehrere Matches gibt.[/font]

[font=lucida sans unicode,lucida grande,sans-serif]Falls ihr das Video gesehen habt:
Die Konsole und das Spiel bleibt auch für immer geöffnet. Jetzt könnte man hinten und noch -background anhängen und schon wäre nur die Konsole da. Leider finde ich noch keine "gute" Lösung dafür, dass man per Konsole ins Spiel Befehle senden kann. Das wird aber erst mal auch nicht beachtet.[/font]


[font=lucida sans unicode,lucida grande,sans-serif][b]Part #5[/b] wird wohl der Gameserver und die Clients sein. Der Server macht nichts außer auf Connection hören. Wir wollen nun Parallel zu Client programmieren, dass sie miteinander kommunizieren können.[/font]

[font=lucida sans unicode,lucida grande,sans-serif]Natürlich wird der Teil nicht wie bei Photon sein. Photon hat eine universelle Lösung. Mein Vorhaben ist aber nur speziell für mich bzw. für ein Spiel gedacht. Entweder übernimmt man das beim nächsten Spiel oder man schreibt neue Logiken auf. (Ist doch fast jedes mal so, wenn man auch ein Spiel neu beginnt ). Der Vorteil trotzdem dabei ist, dass wir unsere eigene logischen Bedingungen auf dem Server ausführen können. Beispiel Punkte vergeben. Yay.[/font]

MaZy

MaZy

 

Auto-Matchmaking #3: Konzept und wie weit ich bin.

In diesem Blog geht es darum wie ich meinen eigenen Auto-Matchmaking-system schreibe (bin schon viel weiter). Hallo endlich kommen wir zum Konzept. Ihr fragt euch schon wie ich mir das ganze machen möchte bzw. bereits gemacht habe. Wie das wohl mit Unity Networking gehen soll? Vergisst nicht. Es geht mir ausschließlich um Auto-Matchmaking-System. [Erst mal was ich bis jetzt habe.
-
Ich habe einen Masterserver mit einer Szene, wo man die verbundenen Spieler sehen kann. Außerdem sollte der Server noch anzeigen, was sie machen, jedoch hab ich dort ein Problem. Unity Networking kann nicht mit zwei Servern verbunden werden. Masterserver enthält außerdem eine Playerklasse, wo nochmal die wichtigen Informationen enthalten sind. BILD DAZU http://i.imgur.com/Bj9VYPP.png In dem selben Projekt habe ich eine weitere Szene. Dort hab ich noch ein Server programmiert, welches als Gameserver benutzt wird. Wird so ähnlich wie Photon aufgebaut. Einfach nur Daten hin und her schicken. Das wars so weit. Vielleicht habt ihr bereits verstanden, was ich vorhabe. Das Konzept ist einfach. Ich brauche ein Gameserver, wo die Spieler beitreten und spielen und ein Masterserver, der die Spieler dazu verhelfen soll auf diese Gameserver zu kommen. Also ein Auto-Matchmaking.
Also wird ein System auf dem Masterserver entwickelt, wo Beispiel die Spieler auf ein Button klicken, wo dann dieser Spieler eine RPCall zum Serverschickt, dass er suchen möchte. Dazu schickt der Masterserver zurück "ok du kannst suchen". Wie gesagt. Autoritativer Server "beste" für mich . Auf jeden Fall läuft die Suche auf dem Masterserver. Darum brauchen wir ein Array und noch besser "List" oder so, um die Spieler in einer Queue zu setzen und zusammen zu picken. Da habe ich noch keine Erfahrung, aber ungefähr habe ich die genannte Vorstellung. Jetzt kommt noch ein Teil
Der Masterserver muss wissen, ob ein Gameserver gestartet wurde, läuft, oder beendet wurde. Denn er soll ja schließlich wissen, wann er nochmal diesen Server benutzen kann.
Der Gameserver läuft in meinem Beispiel auf dem selben IP, aber die PORTS variieren. Geht auch anders nicht . Dazu hab ich was simples gedacht. Der Gameserver startet und verbindet sich mit dem Master und sagt "Ich bin startklar, mein Prozess ID". Die ID brauch ich damit der Masterserver weiß, ob der Server abgestürzt ist. Wenn ja ist das Spiel automatisch vorbei und zählt nicht.
Danach wird die Verbindung zum Masterserver wieder getrennt und stellt sich als Server mit Network.InitializeServer() bereit. Ansonsten am Ende verbinden wir uns nochmal mit dem Masterserver und schicken, dass das Spiel erfolgreich beendet wurde. Das Problem könnte hier allerdings kleine Delays sein. Was wenn der Serverstart also Network.InitializeServer() plötzlich 10 Sekunden dauert, weil es gerade Performanz-Probleme gibt? Weiß nicht, ob das überhaupt möglich ist. So mehr fällt mir gerade nicht ein. Im nächsten Teil zeige ich die Fortschritte

MaZy

MaZy

 

Auto-Matchmaking #2: Natürlich selber schreiben! Aber mit Unity Networking?

[size=5][font=lucida sans unicode,lucida grande,sans-serif]In diesem Blog geht es darum wie ich meinen eigenen Auto-Matchmaking-system schreibe (bin schon viel weiter).[/font][/size]

[font=lucida sans unicode,lucida grande,sans-serif]Hallo,

so da ich unbedingt Fan von Unity Networking bin habe ich auch damit angefangen. Viele finden den Unity Networking "schlecht", aber es liegt teilweise an der Programmierung. Ich habe ca. 90 Spieler auf einem Server simuliert und da fing erst an leicht zu ruckeln. Aber es war klar. Denn es war eine Loop schleife mit ein paar Berechnungen. Wie dem auch sei.


[size=5]Es gibt jede Menge tricks wie man ein Server optimieren kann[/size]

Ich bin zum Beispiel bin Fan von RPC. Mit RPC habe ich die ideale Möglichkeit auszusuchen, wohin meine Daten senden möchte. Ich baue auch dazu meisten einen autoritativer Server.
Das Bild soll zeigen wie ich das meine:

[img]http://www.gabrielgambetta.com/img/fpm1-01.png[/img]

Quelle: [url="http://www.gabrielgambetta.com/fpm1.html"]http://www.gabrielga...a.com/fpm1.html[/url]

Wir ihr sieht sendet ihr nur, dass ihr euch bewegen WOLLT und schickt quasi ein Request zum Server. Der Server sagt danach ja du hast dich erfolgreich bewegen können bzw. darfst dich dahin bewegen und dann bewegt ihr euch dahin. In anderen Worten. Der Server weißt immer besser ob du das kannst.

Der Vorteil ist. Du brauchst nicht immer deine Position senden sondern sagst einmalig wohin du bewegst. Es kann einfach eine Taste W sein für vorne. Ein riesen vorteil ist auch hier, dass du hier kein Lerp oder sonst was brauchst, da man sich exakt gleich bewegt. Aus Sicherheitsgründen überprüft man trotzdem, ob man sich doch zu weit bewegt hat oder nicht. Dann setzt man quasi das Objekt zu der richtigen Position. [/font]
[font=lucida sans unicode,lucida grande,sans-serif]Noch habe ich dazu keine bessere Idee gefunden.

Weiter mit RPC. Mit den Verfahren könnte ich quasi dann per Server steuern wohin, welche Daten geschickt werden soll. Wenn sich jetzt zwei Spieler von ein ander entfernen, sagen wir mall 500 Meter und sie brauchen dann nichts mehr von einander wissen, dann braucht der Server dann das auch nicht schicken. Schon spart man Messages und es wird auch weniger Laggs verursacht . [/font]Zusätzlich gibt es auch in RPC Gruppen, wo man nochmal etwas unterteilen kann.

[font=lucida sans unicode,lucida grande,sans-serif]Mit OnNetworkViewSerialize wird nicht so klappen, da man Daten nicht auslassen kann. Falls ich mich irre dann korrigiert mich [/font]

[b]Mal kleinen Hinweis[/b]: Ich vermute, dass viele Spiele aus so ähnliches Gründen in Multiplayer laggen. Z.B. Arma 3, Space Engineers. Wobei zu Arma 3 nicht viel sagen kann, da ich lange nicht mehr anprobiert habe, aber Space Engineers war am Anfang nicht toll in Multiplayer zu spielen. Irgendwann update zu update wurde das so gut optimiert, dass es fast laggfrei spielbar war. Nun stellt euch vor das Ganze wäre in Unity Networking. Natürlich würden am Anfang die Spieler sagen "ja Unity halt" oder die Entwickler "Ja Unity Networking halt". Aber, wenn man es optimiert läuft es halt . Deswegen sucht man schnell alternativen.
Dummerweise wird in Tutorials-Videos gesagt, dass es Unity Networking schlecht sei, oder peer2peer (was nicht stimmt!), MMO ist unmöglich. Doch klar ist es möglich.

[font=lucida sans unicode,lucida grande,sans-serif]Im nächsten Blogeintrag geht es um das Konzept.[/font]

MaZy

MaZy

 

Auto-Matchmaking #1: Photon PUN oder selber ähnliches schreiben?

[font=lucida sans unicode,lucida grande,sans-serif][size=5]In diesem Blog geht es darum wie ich meinen eigenen Auto-Matchmaking-system schreibe (bin schon viel weiter).[/size][/font]

[font=lucida sans unicode,lucida grande,sans-serif]Hallo

viele kennen das von euch. Ihr wollt ein Spiel programmieren und möglichst in Multiplayer, damit die Interesse bei Spielern größer ist oder einfach damit ihr mit euren Freunden euer Spiel zocken könnt. Dabei fragt ihr euch NOCH NICHT, welches Networking-System ihr dafür benutzen wollt, bis ihr ein Tutorial sieht, dass euch zeigt wie "toll" Photon PUN doch so ist.

Photon von exitgames.com ist wirklich toll. Es nimmt viel Arbeit ab und was am meisten Reiz ist, dass man überhaupt keinen Server braucht, da Photon PUN über ihren eigenen Cloudserver läuft. Das heißt, ihr erstellt einen "Room" und gleichzeitig, wenn nötig ist, wird bei Photon Cloudserver aktiviert/deaktiviert. Zusätzlich dazu freut sich der Entwickler, dass man kaum auf der Serverseite programmieren muss. Denn sie kümmern sich nur darum, was der Spieler machen KANN. Vergessen hierbei wird, was der Spieler noch machen KÖNNTE. Dazu gleich mehr.

Auf jeden Fall bietet Photon sehr viele Dinge. Auto-Matchmaking, Lobbies & Räume, Kleines Freundesliste-System, das sogar mit anderen Platformen verbunden werden kann z.B.: Facebook.
Damit lässt sich schnell schöne Dinge entwickeln.

Das ganze hat zwei riesen Nachteile, wobei eins davon relativ ist.
Erstens: Man kann unmöglich Serverseitig programmieren. Irgendein Spieler kann Master werden und der kann die Serverseitige Logik übernehmen, jedoch finde ich, dass man da cheaten könnte. Ist nicht ganz sicher. Dabei kommen dann zusätzlich viele andere Nachteile. Keine Serverseitige Mods. Keine Configdateien, Keine Dedicated bzw. Listenserver für die Spieler. Sie können also keine Server erstellen wie bei den Spielen wie: Counter-Strike, Rust, Garry's Mod, Arma 2 - 3, DayZ usw. Wenn man diese Spiele anguckt, hat man da die Freiheiten. Keine Server von Spielern wo sie selbst Administrieren können, Spieler bannen können usw. Oder vielleicht auch Modden.

Warum ist das nicht möglich? Photon PUN bietet Cloudserver an. Diese Cloudserver sind quasi wie ein Telefonanbieter. Nehmen wir mal an Telekom ist ein Cloudserver. Ist nur ein Beispiel. Willst du mit jemanden telefonieren, geht deine Leitung über das Telekom und wirst dann zum Ziel weitergeleitet.
So kann man sich Photon's Cloudserver vorstellen. Jeder verbindet sich mit dem Cloudserver und tauscht einfach die Daten aus, was sie hin und her schicken. Mit einem selbst erstellen Server könnte man viele andere Dinge machen. Beispiel, wer überhaupt verbinden darf. Config-Dateien erstellen und Admins zuweisen. Oder noch Komplexer: Dinge validieren, ob sie überhaupt gültig sind. Beispiel ob der Spiele wirklich Gold gedroppt hat und aufheben darf. In anderen Worten mehr Sachen programmieren, wo der Server mehr zu tun als, als nur einfach Daten empfangen und schicken.

Zweitens: Es kostet Geld je nach wie viel Slot ihr braucht.
Bis 20 CCU kostenlos.
100 CCU | 40k Monthly Actives | CCU Burst not included | $95 einmalig

500 CCU | 200k Monthly Actives | CCU Burst is included | $950 / jährlich oder $95 /monatlich
10,000 CCU | 4,000k Monthly Actives CCU Burst is included | $18,500 /jährlich oder $1,850 /monatlich

Kurz erläutern. CCU soll einfach heißen gleichzeitig verbundene Spieler. Man spricht extra von CCU da man davon ausgeht, dass es NIEMALS alle Spiele die dein Spiel haben gleichzeitig online sind. Nehmen wir das obrige Beispiel mit 100 CCU. Dort steht, wenn man 40.000 Spieler im Monat hat, so werden geschätzt 100 Leute gleichzeitig online sein. Natürlich kann es stark variieren, ob das Spiel neu draußen ist oder keiner spielen möchte. Tageszeiten... nachts weniger online als am Tag usw.
Ich finde es macht ein wenig sind aber habe jedoch bedenken.

Ich schreibe gerne Apps und kostenlose Apps, wenn sie gut sind, werden auch sehr gerne runter geladen. Ich habe eine App, die 900.000 mal runtergeladen wurde und am Tag ca 50.000 - 90.000 Leute online gehen. Davon sind, aber nicht 200-300 gleichzeitig online sondern viel mehr.

Jetzt zurück zu Kosten. Diese Kosten sind nicht hoch und ist denke ich mal bezahlbar. Jedoch nicht für Leute die fast gar nichts dabei verdienen. Für die sind es teuer. Da reicht wohl die einmalige Bezahlung.


Ich habe mir daher die Frage gestellt, warum nicht eigenen schreiben?

Mehr dazu in Teil #2 [/font]

MaZy

MaZy

 

GUISystem Tagebuch #1

Hallo,

ich habe angefangen eigenes GUI System zu schreiben. Ich wollte vieles automatisieren und erleichtern. Kleines Beispiel. Ich möchte nicht jedes mal selbst rechnen, um alles zu zentrieren oder ich möchte nicht so viele if Bedingungen mit Buttons haben.

Darum habe ich ein Anlass gehabt um sowas zu machen um dann für meine Projekte das zu verwenden.

Ein Bespiel. Ich redete von Buttons.
So sieht das aus zur Zeit aus

[img]http://puu.sh/aUU8U/b74342c5d5.png[/img]
(Menü-Skripte)

[img]http://puu.sh/aURfV/7a1bc7cfe9.jpg[/img]

Kleines Beispiel mit einem Video
[url="http://garrysmod.zulu907.server4you.de/sharex/imgs/2014-08-16_15-57-01.mp4"]http://garrysmod.zul...16_15-57-01.mp4[/url]

Aufgebaut ist dieser Code nur so (Der Rest kommt vom GUISystem selbst):

[img]http://puu.sh/aURwB/c93243a057.png[/img]

[color=#0000ff]CreateVerticalButtons(bool center, float space, Rect r, params string[] buttons)[/color]

Wie man hier sieht erstelle ich hier automatisch Buttons durch eine Funktion. 3 Items Play, Option, Und Quit wurde erstellt.
Sie alle geben ein ID zurück wenn was geklickt wurde. Ansonsten ist es immer -1.

Außerdem lasse ich mit Open oder Close die Menüs anzeigen oder verstecken.

So wenn ich in Option Menü bin.


[img]http://puu.sh/aUTPg/037c4ed754.png[/img]

Schaut euch die markierte Zeile an. Ein Extension erlaubt mir die Rect-Klasse mit Methoden zu erweitern. Und das schöne ist halt, dass ich jedes mal mit einem "." eine weitere Methode dranhängen kann. Ich zentriere es vertical und lasse es dann nach unten Andocken. Da ich aber sage -10f hoch (man muss das als Ursprungspunkt beachten, darum - 10 hoch) wirds etwas nach oben verschoben.

Man kann es getrennt schreiben aber zur Zeit hab ich damit ein Bug. Lösung wird gesucht.

Ergebnis:

[img]http://puu.sh/aUTYr/15e3596847.jpg[/img]

Schön oder?

Schlusssatz. Ein bissel Zeit sollte man schon opfern, bevor man das eigentliche Anfängt

(Da das eine Anfangsphase ist, kann es natürlich in den nächsten Blogeinträgen zu Veränderungen kommen bzw. kann bereits in den Screenshots eine Abweichungen vorhanden sein..).

NACHTRAG: Besseres Video
[url="http://garrysmod.zulu907.server4you.de/sharex/imgs/2014-08-16_16-53-32.mp4"]http://garrysmod.zulu907.server4you.de/sharex/imgs/2014-08-16_16-53-32.mp4[/url]

MaZy

MaZy

 

Nervig! Der Nullpunkt ist nicht in der Mitte vom Model. Lösung!

Ich hatte mal lust ein "Demo" zu machen, wo man einfach mit ner Flugzeug rumfliegen kann. Ich habe dazu einen kostenlosen Flugzeugmodel runtergeladen.

Ich habe aber gemerkt, dass viele Nullpunkte nicht mittig sind. Sie sind sogar manchmal außerhalb. Zum Beispiel: Die Turbinen können nicht rotiert werden. Warum? Da der Nullpunkt nicht in der Mitte sind könnte sie falsch rotiert werden oder in einer Eierorbit oder so.

Jetzt könnte ich das Problem lösen, in dem ich neues GameObject nehme und sie dann in die Mitte schiebe. Und dann schiebe ich die Turbine in das GameObject. Sagen wir es heißt TurbinenRotierer. Jetzt sagen wir mal ich habe, aber 10-100 kleine Models die sowas benötigen. Man hätte kein bock darauf alles zu machen. Tatsächlich war es wirklich so, dass da jede Menge dinge waren die mich gestört haben. Also habe ich einen kleinen Script geschrieben.

[b]Collider [/b]und [b]Renderer [/b]haben eine coole Funktionen die sich [b]Bounds [/b]nennt. Dadurch kann man nämlich die Mitte herauskriegen in dem man [b]center [/b]benutzt. Und die habe ich genutzt.

[CODE]
void RotateCenter(GameObject rotatingObject, Vector3 eulerAngle) {
if(!rotatingObject.renderer) {
return;
}

GameObject theRotator = GameObject.Find("Center_" + rotatingObject.gameObject.name);

if(!theRotator) {
theRotator = new GameObject();
theRotator.name = "Center_" + rotatingObject.name;
theRotator.transform.position = rotatingObject.renderer.bounds.center;
theRotator.transform.parent = rotatingObject.transform.parent;
rotatingObject.transform.parent = theRotator.transform;
}

theRotator.transform.Rotate(eulerAngle);
}
[/CODE]

Hier rufe ich einfach die Methode [b]RotateCenter [/b]aufund gibt an welchen GameObject man rotieren will und dazu die eulerAngle , um die Turbinen zu rotieren. Also funktioniert eigentlich wie Rotate(). Der Script lässt einfach einen GameObject erstellen falls es noch nicht existiert und benennt sie um und parented das auch um.

[CODE]
RotateCenter(TurbineLeft,new Vector3(0,0,-throttle));
RotateCenter(TurbineRight,new Vector3(0,0,throttle));
[/CODE]

Joa das wars erst mal

[b]NACHTRAG (13.08.2014):[/b]
[b]NACHTRAG #2:[/b] Paar Fehler behoben.

Ein Hinweis von Sascha. Man kann das natürlich als Extension machen.
Ein Beispiel wie es es aussehen könnte[CODE]
using UnityEngine;
using System.Collections;
// Das hier sollte static sein.
public static class TransformExtensions {

/*
Was tut sie?
Wenn ein Model mal nicht mittig ist, kann man die Funktion verwenden.
Im Endeffekt wird ein Hilfsobjekt erstellt und zentriert. Das alte Objekt wird dann zu ihm parented.
Danach rotieren wir eigentlich nur den Hilfsobjekt. Je nach Situation kann das behilflich sein.
*/
public static void RotateCenter(this Transform t, Vector3 eulerAngle) {

// Hat as render (mesh?)
if(!t.renderer) {
// Wenn nicht, abbrechen.
return;
}

// Den "Hilfsobjekt" bzw. den "Drehobjekt" ermitteln
GameObject theRotator = GameObject.Find("Center_" + t.gameObject.name);

// Existiert dieses Hilfsobjekt?
if(!theRotator) {

// Wenn nein dann erstellen wir sie.
theRotator = new GameObject();
theRotator.name = "Center_" + t.name;

// Ermittle die Mitte
theRotator.transform.position = t.renderer.bounds.center;

// Diesen Objekt den gleichen Parent zuweisen
theRotator.transform.parent = t.transform.parent;

// Nun den alten Objekt parent durch "Hilfsobjekt" zuweisen.
t.transform.parent = theRotator.transform;

}

// schließlich den Rotor drehen.
theRotator.transform.Rotate(eulerAngle);
}

}
[/CODE]
Nun sollte man sie so verwenden können: transform.RotateCenter(new Vector3(0,0,1));
Hab leider jetzt nicht testen können, aber sollte eigentlich funktionieren.

MaZy

MaZy

 

Unbedingt lesen!: GUI positionieren, oder programmieren? Natürlich positionieren!

Hallo,

ihr kennt das bestimmt. Man hatte eine Vorstellung wohin dieser Button hin soll. Dann programmieren wir es und setzen die Werte ein. Doch dann passt es nicht. Oder man will es doch etwas verschieben. Jedoch kann es auf dauer nervig sein. Was tun wir da? Natürlich! Wir setzen alle Variablen Public damit wir nicht immer die Datei verändern brauchen.

Doch, was, wenn da eine bessere Methode gibt? Wo man überhaupt keine Zahlen eintragen muss? Genau! Du hast es erfasst. Wir nehmen einfach ein GameObject .

GameObjects liefern einige Informationen um so etwas zu realisieren. Wir können sie verschieben, skalieren und rotieren. Doch lass mal erst überlegen wie wir vor gehen wollen.
Bestimmt habt ihr schon mal gewollt, dass die Position des Mauses in Weltkoordination angegeben wird. Und das tut man in dem man mit Hilfe von Kamera sie berechnen lässt. Das können wir auch für die GUIs verwenden. Jedoch andersherum. Wir nehmen die Weltkoordinaten um dann daraus Screenkoordinaten zu machen. So da ich euch dies angedeutet habe nun ein bissel Code.

[CODE]
public class IngameElements : MonoBehaviour {
public Transform restartButton;
private Rect restartButtonRect;

void Start() {
if(restartButton != null) {
// Die Screenkoordinaten herauskriegen
Vector3 restartButtonWorld = Camera.main.WorldToScreenPoint (new Vector3(restartButton.position.x,
-restartButton.position.y,
restartButton.position.z));

// Die Screenkoordinaten verwenden um neuen Rect zu erstellen. Wir benutzen den localscale als breite und länge.
restartButtonRect = new Rect (restartButtonWorld.x,
restartButtonWorld.y,
restartButton.localScale.x,
restartButton.localScale.y);
}
}

// Nun "malen" wir es in OnGUI
void OnGUI () {
if (GUI.Button (restartButtonRect, "Restart Game")) {
RestartGame();
}
}
}
[/CODE]

Jetzt müsst ihr nur noch ein Gameobjects erstellen und zuweisen. Fertig.
Am Besten macht ihr es präziser.
--InGameMenu
---Panel(Bsp: Obenrechts)
----RestartButton
----SoundToggleButton

Damit könnt ihr die Gruppen besser an- und ausschalten oder verschieben usw.

Jetzt kann man dies noch mit einer Funktion erweitern, so dass er nicht immer alles schreiben musst. Oder am besten nen Library, aber ich belasse simpel bei dem selben Beispiel:
[CODE]
public class IngameElements : MonoBehaviour {
public Transform restartButton;
public Transform exitGameButton;

void OnGUI () {
if (DrawButton("Restart Game", restartButton) {
RestartGame();
}

if (DrawButton("Exit Game", exitGameButton) {
ExitGame();
}
}

bool DrawButton(string name, Transform t) {
return GUI.Button(transfomElementToScreen(t), name);
}

Rect transformElementToScreen(Transform t) {
Vector3 world = Camera.main.WorldToScreenPoint (new Vector3(t.position.x, -t.position.y, t.position.z));
return new Rect (restartButtonWorld.x, restartButtonWorld.y, restartButton.localScale.x, restartButton.localScale.y);
}
}
[/CODE]

Probiert es aus und liiiiiiiiiiiiiiiiken

MaZy

MaZy

 

Eine "kurze" Erläuterung, warum ich doch NGUI oder DF vermieden habe zu kaufen.

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Herzlich Willkommen zu meinen ersten Blogeintrag überhaupt. Als erstes möchte ich mich für mein Deutsch entschuldigen. Ich bin hier in Deutschland zwar groß geworden, jedoch bei den Leuten, die einen Migrationshintergrund haben und selbst kaum die deutsche Sprache beherrschten. Das hatte natürlich ein wenig Einfluss auf mich. Jedoch bemühe ich mich verständlich zu gestalten. Zum Glück habe ich fast keine Rechtschreibfehler, aber grammatikalischen Fehler werdet ihr viele finden ^^. Auch begrüße ich sehr herzlich, wenn ihr euch ein Fehler auffällt irgendwie zu benachrichtigen, da ich dadurch lernen kann.[/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ich habe schon mich oft gefragt, ob ich irgend ein System wie NGUI oder DF benutzen muss und kaufen müsste. Ich habe schließlich gemerkt. Ich brauche das gar nicht. Wie ich meine GUIs nun zusammen stelle zeige ich euch.[/size][/font][/color]


[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=5][b]Wie ich meinen GUI selbst zusammen stelle[/b][/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ich habe neulich meinen System was GUIs angeht verändert. Ich programmiere fast die GUIs nicht mehr sondern stelle sie zusammen. Na klar ohne Scripts kommt man nicht drum rum, aber diesmal habe ich etwas entdeckt, was mir gefällt.[/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Bei meinem neuen Spiel lerne ich erste mal neue Seiten was GUIs angeht.[/size][/font][/color]

[b]1. GUI Elemente[/b]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ein Beispiel dafür wie sich ein "Levelbox" entwickelt habe.[/size][/font][/color]
[img]http://puu.sh/8w5hI.jpg[/img]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Hier sieht die Entwicklung eines "Levelboxes" von Links nach Rechts als Level_Done und Level_Locked.[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]In diesem Beispiel verwende ich dafür die Assets von JNA Mobile[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Quelle: [/size][/font][/color][url="https://www.assetstore.unity3d.com/#/content/7987"]https://www.assetsto.../#/content/7987[/url]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ebenfalls verwende ich ein Textmesh für die Texte (logisch ) mit anderem Schriftart als Arial.[/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Die Komponenten[/size][/font][/color]
[img]http://puu.sh/8w4BW.png[/img]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Wie ihr sieht bestehen die Objekte aus Sprites. Man sieht auch, dass ein [b]BoxCollider2D [/b]eingefügt wurde. Damit kann ich mit [b]OnMouseDown() [/b]events abfangen. Das Schöne daran ist, dass es auch für [b]Touchsysteme [/b]funktioniert. Somit hätte ich schon ein Button für Levelauswahl fertig. [/size][/font][/color][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Alles wurde dann als Prefab gespeichert. [/size][/font][/color][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ebenfalls habe ich ein Script eingefügt. [/size][/font][/color]

[font=tahoma, helvetica, arial, sans-serif][color=#666666][size=3]Der Script ist geschrieben in C# hilft mir die Texte zu verändern. Es gibt noch einen Script der mir verhelft, die Objekte zu spawnen angepasst an den Levelanzahl. Kommen gleich dazu.[/size][/color][/font]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ein bissel Code:[/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3][CODE]
public class LevelboxBase : MonoBehaviour {
public TextMesh levelname;
public TextMesh levelnumber;

public void ChangeProperties(string lvlname, string lvlnumber) {
levelname.text = lvlname;
levelnumber.text = lvlnumber;
}

}

public class LevelboxDone : LevelboxBase {
public GameObject star;

public void SetDone(bool leveldone) {
if(star) {
star.SetActive(leveldone);
}
}

void OnMouseDown() {
Application.LoadLevel("lvl" + levelnumber.text);
}
}
[/CODE][/size][/font][/color]

[font=tahoma, helvetica, arial, sans-serif][color=#666666][size=3]Es ist nicht perfekt gelöst jedoch funktioniert es . [b]LevelboxBase [/b]hat die Standardeigenschaften für ein Levelbox. Diese wird erweitert mit einem neuen Script [b]LevelBoxDone[/b]. In anderen Worten: Er wurde speziell für [b]LevelBoxDone-Prefabs[/b] gemacht, da dort ein Stern dazu kommt. mit [b]SetDone(bool leveldone) [/b]kann ich später den Stern nämlich anzeigen oder auch ausblenden. Die Sterne stehen dafür, ob man diesen Level geschafft hat oder noch zu machen hat. Bei meinem Spiel wäre das eigentlich nicht nötig, da man eigentlich immer schaffen muss um den nächsten Level freizuschalten. [/size][/color][/font][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Beim [b]Levelbox_Locked[/b] benutze ich einfach den [b]LevelboxBase[/b]. Da bauche ich kein Stern .[/size][/font][/color]



[b]2. GUI Elemente anzeigen.[/b]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]So jetzt kommen wir zu einem Teil, was auch wichtig ist .[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Ich habe um die GUI Elemente anzuzeigen ein Script geschrieben. Damit lass ich diese Elemente spawnen.[/size][/font][/color][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3] Ich werde nicht alles frei wild posten, sondern, versuche mit ein bissel Code einfache Gedankenanstoße zu abzugeben. [/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Hierbei habe ich einen GameObject genommen und ihn ein Script verpasst. Die Prefabs habe ich ja bereits erledigt.[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]So sieht es nun aus.[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3][img]http://puu.sh/8w6qe.png[/img][/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Und genau diesen LavalMainMenu erkläre ich gerade. Dort ist einfach folgendes enthalten.[/size][/font][/color]
[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3][img]http://puu.sh/8w6qG.png[/img][/size][/font][/color]

[color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Hier merke ich gerade, dass ich start offset gar nicht benutze . Nur so nebenbei. Wichtig ist einfach nur die ersten 3 (nach Debugging On). [/size][/font][/color][list]
[*][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Levels Count: Dort haben wir stehen wie viele Levels überhaupt wir habe[/size][/font][/color]
[*][color=#666666][font=tahoma, helvetica, arial, sans-serif][size=3]Level Open GO und Level Closed Go: Hie tun wir einfach die jeweiligen Prefabs rein.[/size][/font][/color]
[/list]
Der Rest sind einfache Berechnungen zum Zentrieren und Größeneinstellungen. Man kann etwas vorgeben oder es wird automatisch berechnet ( Je nach angaben. Eingabe x > Eingabe y dann berechne automatisch oder nehme Eingabe X als Wert)

Ein bissel Code?

[CODE]
void InitializeGuiElements() {
levelsCount = Mathf.Clamp(levelsCount, 1,99999);
spawnedLevelbox = new GameObject[levelsCount];
spawnLevelboxCounter = 0;
for(int i = 0; i < levelsCount; i++) {
int levelno = (i+1);
Debug.Log(levelno);

if(IsLevelDone(levelno)) {

instantiateLevelbox(2, "Level", levelno.ToString());

} else if( IsLevelOpen(levelno) ) {

instantiateLevelbox(1, "Level", levelno.ToString());

} else {

instantiateLevelbox(0, "Level", levelno.ToString());
}
} // position update
UpdatePosGuiElements();
}
[/CODE]

Dieser Teil erstellt die ganzen GUI Elements. Es wird gecheckt, ob man diesen Levelteil schon abgeschlossen hat, noch zu machen hat oder gar nicht freigeschaltet hat. Je nach dem wird ausgewählt welcher GUI Element gespawnt wird.
UPdatePosGUIElements(): Damit positioniere ich sie noch einmal. Ich habe es extra getrennt gemacht, da ich eine Funktion habe die sich OnPropertiesChange() Event habe. Damit kann ich dann später im Inspector etwas herumspielen und gucken ob es so gut aussieht.

So der Teil hier spawnt sozusagen die richtigen Prefabs
[CODE]
/// <summary>
/// Instantiates the levelbox.
/// </summary>
/// <param name="boxtype">Boxtype 0 = closed, 1 = open, 2 = done</param>
void instantiateLevelbox(int boxtype, string name, string number) {

GameObject levelPrefab;
if(boxtype > 0) {
levelPrefab = levelOpenGO;
} else {
levelPrefab = levelClosedGO;
}

GameObject levelGO = (GameObject)Instantiate(levelPrefab, Vector3.zero, Quaternion.identity);
levelGO.name = (1+spawnLevelboxCounter).ToString();
spawnedLevelbox[spawnLevelboxCounter] = levelGO;
spawnLevelboxCounter++;

levelGO.transform.parent = transform;

if(boxtype > 0) {
LevelboxDone levelproperties = levelGO.GetComponent<LevelboxDone>();
levelproperties.ChangeProperties(name, number);
levelproperties.SetDone(boxtype == 2);
} else {
LevelboxBase levelproperties = levelGO.GetComponent<LevelboxBase>();
levelproperties.ChangeProperties(name, number);
}
}
[/CODE]
Hier lasse die richtigen Prefabs spwnen und packe es in eine liste rein. Damit kann ich später etwas anfangen, aber fürs Debuggen reicht das erst mal ^^. Das ganze sieht dann so aus.

[b]VIDEO Demonstration[/b]: [url="http://puu.sh/8w8pH.mp4"]http://puu.sh/8w8pH.mp4[/url]

Und ein Bild :[img]http://puu.sh/8w8pP.jpg[/img]

[b]Fazit:[/b]
Natürlich ist das hier nicht mit NGUI vergleichbar, aber warum gleich soviel Geld ausgeben, wenn man das selbst machen kann. Gut keine Animationen zur Zeit da. Keine Progression Bar. Aber diese Dinge kann man langsam und langsam dazu machen. Irgendwann hat man seine Scripte zusammen, wo man fast eigentlich immer wieder die selben Sachen verwendet. Vorhin habe ich zum Beispiel Buttons erstellt. Als Prefab gespeichert. Nun ziehe ich es raus und ändere nur den Text. Dazu kommt noch ein Script.

Ein EventSender mach ich noch aber muss nicht sein. Hauptsache ein Event wie OnMouseClick() ist dabei .

Ich hoffe dieser Blogeintrag hat euch Spaß gemacht zu lesen

EDIT: Nachtrag wie das nun mit GameOver Dialog aussieht (außerdem habe ich doch die Farben verändert.) Knapp 10-20 Minuten arbeit (hab nach fonts gesucht ).

[img]http://puu.sh/8wgbn.jpg[/img]

[img]http://puu.sh/8wglV.png[/img]
Achtet hier auf die Prefabs. Kann man imme wieder Verwenden. Buttonprefab ist in DialogboxGameover auch enthalten. Der einzige Nachteil ist, dass ich "5 of 10" in einem Text habe. Ich wollte es jetzt getrennt machen, da ja vielleicht dazu kommt dass da 5 of 100 steht. Dann müsste man ja "5 of" mit verschieben. Als einzelne Objekte wäre das schwerer. Aber man hat ja viel Platz. könnte ja alles etwas verschieben

MaZy

MaZy

Sign in to follow this  
×