

MaZy
Members-
Posts
706 -
Joined
-
Last visited
-
Days Won
35
Content Type
Profiles
Forums
Calendar
Blogs
Everything posted by MaZy
-
Spieler Geschwindigkeiten synchronisieren (Netcode)?
MaZy replied to Lightstorm's topic in Multiplayer und Networking
Also ich sehe hier mehrere kritische Fehler. Erst mal: Du solltest nicht jedes Update den RPC call machen. Das nicht gut, außer willst nur weniger Spieler supporten und du denkst nicht so an Performance. Check vorher mal den Delta Wert bzw, ob die neuen und alten Werte nicht dasselbe sind (z.b. oldHorizontal != horizontal), dann MovementServerRpc ausführen. Zweitens: Also MovementServerRpc, gerade sieht es noch ok aus, aber ich würde NIEMALS die Werte was der Client schicken kann, weiter verwenden. Da könnte theoretisch auch 1000f stehen statt 1f, wenn man das gehackt bekommt. Da du das in Vector3 packst könnte da halt ungewollte Werte stehen. Ich wette mit dir, dass ich bei dir bereits Cheat Engine verwenden könnte ^^. Am besten tut man das so. Du schaust ob horizontal / vertical inputs -1 oder 1 sind. Erstens sendest du hier einmal über das Netzwerk und nicht mehrmals. Spart man schonmal minimal Performance. Beim GetAxis steigt ja float von 0 auf 1 also wird mehrmals gesendet. Das ist aber jetzt optional udn nicht so wichtig. Ist nur ein Tip am Rande. Zweitens dann noch clampen auf -1 und 1 auf dem Server. Von da aus kannst du sagen ja möchte nach vorn oder nach hinten. Was auch immer. Den Rest hast schonmal gut gemacht. Das mit nextMove ist schon mal eine simple Lösung kann man machen. Ich benutze das auch so ähnlich, wenn ich lerpe oder smoothe Bewegung einbaue (z.B. schwebende Autos, Raumschiffe usw.). Allerdings reicht das ja noch nicht aus. Die Bewegung muss solange ausgeführt werden bis neue Inputs reinkommen. Also ruhig nextMove = Vector3.zero; raus nehmen. Bei Source Engine z.B. hab ich gemerkt, dass die Spieler sich auch solange bewegen bis neue Inputs kommen. Sollte das Spiel mal einfrieren für paar Sekunden und du hast in der Zeit bereits losgelassen, läuft man aber im Spiel (auf dem Server) dennoch immer weiter. Ich denke mal das ist bei vielen Spielen so. FixedUpdate sollte in dem Fall nur auf dem Server möglich sein. Wie wird es denn auf dem Clients synchronisiert? -
Hättest einfach auch link senden können: Klick here. Einfacher um mal direkt zu testen :). Muss sagen finde auch mega interessant. Allerdings um schnell mal jemanden das zu zeigen dauert es für mich als Textform doch zu lange. da hätte ich doch eher Drag and Drop benutzt. Ansonsten Top was so alles da möglich ist.
-
Also ist ja fast wie meine beschriebene #2. Dann kannst du ja direkt den Prefabwert wieder überschrieben, wenn es erstellt wurde. Für mich ist das immer noch logischer, wenn es auf sich selbst zeigt, wie ich schon oben beschrieben habe. Wie gesagt: Im Prefab alles was auf sich selbst, drüber oder drunter (parent, child) zeigt, wird automatisch zum den Instanzen zeigen. Daran ist nichts unlogisch finde ich.
-
Ich bin der Meinung, dass es kein Bug ist. Für mich ist das eher logisch, auch wenn es ärgerlich ist, weil man vllt das mal so brauchen könnte ^^. Alle Referenzen die zu dem selben Objekt zeigen und darunter liegenden (Childs) werden ja beim Erstellen, auf das erstellte Objekt zeigen . Beispiel: TankGo [TankScript] -> TurretGo Nun hast du in Tankscript ein Verweis auf TurretGo, weil du den ja steuern willst. Wie sollte sich nun es in Runtime verhalten? Auf den Child TurretGo verweisen oder den im Assetordner? Logischerweise auf dem erstellten im Runtime bzw. wenn man selber in die Scenen reinschiebt. Jetzt willst du ja nicht, wenn du diesen Tank prefab rein draggst oder erstellst, dass es auf diesen Turret im Assetordner zeigt, sondern bei den erstellten Sceneobjekt. Und das selbe gilt auch beim Root-Gameobject -> TankGo. Ist also ein völlig normales Verhalten. Daher finde ich, dass es kein Bug ist. Dennoch finde ich, dass irgendwie ne Möglichkeit geben sollte z.B. mit Attributen oder so, dass erkennen zu lassen, dass man es den Asset meint. Meine Idee - Workaround #1 Wenn es unbedingt im Script selbst sein muss Quasi: TankScript.prefab Ein Scriptableobject mit einer Liste erstellen. Den gleichen Prefab da reinpacken. Danach einfach durch loopen bis die Namen passen und dann holst du den Prefab daraus. TankScript.Prefabs.GetPrefab(TankScript.prefab.name). Kombiniert mit OnEnable oder OnValidate müsste sogar beim Reinziehen funktionieren. Man kann ScriptableObject auch als Singleton machen, wenn es sein muss. Man kann natürlich pro prefab auch ein ScriptableObject erstellen, aber da hat man bestimmt irgendwann einfach haufenweise davon. #2 In Spawnscript schreiben (was ja meist so üblich ist) und nachdem es erstellen wurde man Prefabwert wieder neu setzen. #3 - Ungetestet Customeditor schreiben bissel rumfummeln und gucken was so möglich ist ^^.
-
Also erst mal die Grundlagen lernen und dann Projekte angehen und "VERSAGEN". Will ehrlich sein. Dafür reichen bereits die Youtubevideos heutzutage. Bücher sind eher fürs Nachschlagen gut. Durch Versagen habe ich mehr gelernt und bin da wo ich heute bin. Beispiel, hätte ich kaum Performanceprobleme, hätte ich nie erfahren, was Performanceprobleme verursacht. Probleme beim Skalieren. Also mein Code war so schlecht, dass ich nicht erweitern konnte. Daher rate ich auch vielen ab gleich mit großen Spielen anzufangen. Immer kleines bissel anfangen und Features einbauen. Und, irgendwann merkt man schon bei Kleinigkeiten, dass es nicht so schön ist und man versucht das besser zu machen. Und auf Dauer wird man immer und immer besser darin. Beispiel was klein ist. Ein Spiel wie Mario. Space Invaders. Breakout. Solche Spiele sind sehr simple, aber haben potenzial sehr coole Features zu bekommen. Beispiel Mario Mehrere Levels Speicherpunkte Gegner Bosse Punkte Leben und Respawnsystem Missionen und Events Procedurales Level System (eher nicht für Anfänger gut, aber man würde viel lernen) Space Invaders Gegnergruppen Bosse Events Waffenupgrades / Powerups Inventarsystem Coolere Effekte und Design Levels Breakout Bewegende Blöcke Mehrere Bälle Powerups Und generell jeder könnte Multiplayer bekommen. Multiplayer ist nicht immer einfach :D. Es kommt drauf an. Ich kann ja dazu meine Erfahrung sagen. Ich habe nie Studiert (außer 2-3 Monate ^^ und dann abgebrochen) und sogar keine Ausbildung gemacht. Ich habe mit Programmierung ca. in 2004 angefangen und mir selbst beigebracht und damals gab es keine Tutorials wie heute. Kaum Youtube Videos (glaub youtube gab es damals nicht mal). Damals musstest du VIEL Geld ausgeben um zu lernen. Ich hab dennoch geschafft kostenlos zu lernen. Mein großes Projekt begann damit, als ich eine Webseite in PHP schrieb, was wie Facebook ähnlich aufgebaut war. (Ja.. zeitlich wurde tatsächlich (The)Facebook entwickelt und wir beide hatten die selbe Idee. Ich hab ne Seite geschrieben für Schüler und meine Umgebung, die sich dort finden und sich anschreiben können. So ne Art Social Media / Single Börse. Hätte ich nur gewusst, dass man damit Geld machen kann xD.) Also programmieren konnte ich dann schon so langsam bereits gut, aber immer noch fehlte strukturiertes Vorgehensweise. Falls das interessiert, so sahen sie aus: https://myworks.hardcoded.mywire.org/statics/images/php/fd_1.png https://myworks.hardcoded.mywire.org/statics/images/php/fd_2.png https://myworks.hardcoded.mywire.org/statics/images/php/fd_3.png Durch das Projekt habe ich viel dazu gelernt, wie man es nicht machen sollte, wo meine Sicherheitslücken waren usw., denn die Seite war definitiv hackbar, hehe. Irgendwann begann ich mich fürs Hacken in Spielen zu interessieren. Fing mit AutoIT und C++ an. Ich habe tatsächlich für Counter-Strike Wallhacks geschrieben, aber nur für mich persönlich ab und zu verwendet. Mir ging nur ums lernen. Tatsächlich funktionierte es nach Jahren immer noch. Ich riskierte, aber hab kein Bann bekommen. Vielleicht, weil ich ganz kurz benutzt habe. Hier, muss man gesagt haben, war ich immer noch Anfänger. Ich konnte kaum ohne nachzulesen weiterkommen. Ebenfalls wuchs dadurch meine Interesse für Bots und Automation. Mochte immer mehr alles zu automatisieren. Egal am PC oder in Spielen (auch, wenn es laut AGB nicht darf). Das tat ich meistens mit AutoIt https://i.imgur.com/2MoD3rZ.png <- bei dem Bild sieht man sogar wie ich beschreibe, dass ich ich Captcha Codes automatisch löse (hier war ich aber bereits in Pro ^^). Nach der Webseite Sache in der schulischen Ausbildung war ich damals in der Programmierstunden der "Beste", weil ich einfach zu Fortgeschritten war. Das war 2011 oder so. Trotz des "schwänzens" hat mir der Lehrer eine 1 gegeben, weil er einfach gemerkt hat, dass ich mich zu sehr langweile. Nebenbei liebte ich in Garrysmod mit Expression 2 zu programmieren, weil du in einem Spiel, Multiplayer programmiert hast und gleichzeitig Visual gesehen hast. Beispiel eine Autosteuerung, Flugzeug oder visuelle Effekte, Physik, Züge, Ampel, Simulationen usw. War mega nice. Mein "richtiges" Lernen kam mit C#, denn vorher hab ich kaum über Architektur und andere Dinge bedenken müssen. Kann nicht sagen, wann genau ich C# anschaute, aber ich interessierte mich für Spieleentwicklung, aber mit C++ fand ich das irgendwie nicht so geil. Entdeckte irgendwann XNA was in C# war damit fing es an. Ich mochte direkt C# und wusste, dass diese Sprache mein Mainsprache sein wird. Entdeckte dann Unity ca. in 2012-2013. Nebenbei programmierte ich noch in Lua und habe sogar Aufträge aus dem Internet angenommen. Nach Studiumabbruch ab 2014 war ich selbstständig, denn ich konnte hier bereits richtig gut programmieren, aber Vorgehensweise war noch nicht gut. Sprich, wie sollte alles aufgebaut werden. Skalierbarer usw. Ab hier wurde es aber ernst, weil ich unternehmerisch vorging. 2016 wurde ich dann professionell mit C#, weil ich nun fast alles beherrschte, wie man auch als Developer sein muss, weil ich so viel ausprobiert habe und immer wieder neu und neues angefangen habe und so viel dazu gelernt habe. Das war eigentlich Mega boost kann man sagen und hab mich sehr viel für Dinge interessiert, wie man etwas Aufbaut und Techniken ausprobiert. In Discord sieht man dazu oft was von mir. Theoretisch kann man sagen bin sogar Software Ingenieur. Das heißt, war bereits in dem Level, wo ich Leute sogar beraten kann und sagen kann wie etwas aufgebaut werden muss. Heutzutage könnte ich ein Unternehmen beraten, wenn es in Unity . Naja bissel tue ich das ja tatsächlich. Fazit Was ich damit sagen möchte ist, dass man selbstständig auch gut werden kann. Man muss oft versagen und aus den Fehler lernen, dass macht dich zum "pro". Zum Beispiel hab ich neulich mit Teilzeit angefangen, weil ich unternehmerisch mir neue Erfahrung aneignen wollte. Dort arbeiten Leute die aus dem Studium kommen oder noch Studenten sind. Der Code ist in der Qualität, wo ich 2013/2014 programmiert haben. Also Grotten schlecht. Überall Singletons, Manager und andere Dinge. Vieles in eine Klasse reingepackt. Und sie selbst erkennen bereits, dass nun bald "neu" programmieren müssen, aber geht nicht. Es ist bissel "zuspät". Also das Lernen wie man programmiert ist einfach, aber die Umsetzung von Ideen dafür braucht man etwas länger. Man muss tatsächlich viele praktische Erfahrung haben und sehr oft erkennen, dass hier und da was falsch läuft um nächstes mal das zu vermeiden. Disclaimer: Kann sein, dass nicht alle Jahreszahlen stimmen. Ist einfach zulange her.
-
1. Basiskartenwerte einfach als Scriptableobject machen. Beispiel: Bild, Attackvalue, Defencevalue und dazu vllt die Animationen. Liste für SO oder Component zum Laden -> Schritt 2. 2. Fürs Ausführen, dann würde ich dafür selbst als eigenen Component machen oder vllt wieder ScriptableObject. Beides gehen. Wichtig ist da zu gucken, ob du mit Interfaces oder Baseklassen oder beide gemischt arbeiten willst, damit man gucken kann, was man ausführen kann. Bei Components kannst du dann quasi dann so ne Art Loader beim ScriptableObject reinpacken bei der Karte. Heißt: Werden die Karten geladen, werden automatisch mit dem Components befüllt. Das Ding ist, wieso ich eher ScriptableObject vermeiden wollen würde ist, falls ja Modifikationen im Laufzeit gibt. Sprich ein Component halt Mana-Shield und den kannst du aber pro Attack reduzieren. Das wäre bei ScriptableObject nicht so toll. Vllt ist auch die Kombinationen machbar? Beispiel ManaShieldSO -> packst Autoloader rein für Components wie ManaShieldBehaviour -> füllst die Basiswerte aus dem SO da rein in Laufzeit nach dem dieser Component hinzugefügt wurde. Könnte eigentlich auch gehen und, wenn ich überlege ist es sogar besser so. Gibt halt viele Möglichkeiten. So hätte man auch nur ein Prefab. Beispiel für Interface oder so Beispiel PSEUDO-Code: public class MegaAOEPunchAttack : MonoBehaviour, IAttack // oder AttackAOEBehaviour { Card card; public void Attack() { // Punch to all cards // Dein code, nehme alle gegner karte aus der liste. Führe animation aus. card.AttackTotalValue usw. } } // get component funktioniert mit Interface. var canAttack = TryGetComponent(out IAttack attack) if (canAttack) { // Wenn angreifen kann und kein Buff, Passiv, Konsumkarte ist, dann erlaube gegner karte anzugreifen attackUI.Show(); } 3. Beispiel: Du legst ne Karte, plötzlich alle kriegen ein Buff 5+ HP oder sowas. Bei sowas würde ich eine Art Modifiersystem bauen. Buffs oder Debuffs werden dann zu den Karten zugewiesen und dann werden sie automatisch berechnet. Ob man jetzt alle Karten Buff gibt oder nur einen zuweisen kann, ist halt abhängig von der Karte. Da würden sogar reine C# Klassen ausreichen. Beispiel: public class TeamworkClass : AttackModifier { public int overrride AttackModifier {get;} = 5 } Meiner Meinung nach ist sowas zu schreiben leicht. Was ich überhaupt nicht nachvollziehen kann ist Deck in der Hand. Wie sie von der Hand nehmen, einordnen, auf den Tisch legen. Du muss doch beim aus dem UI rausziehen in die Welt transformiert werden oder nicht?.
-
Singleton kurz und knapp bedeutet, dass man SICHER stellt, dass ein Objekt nur EINMAL existiert. Dabei ist egal, ob du das selber erstellt hast oder direkt eine Funktion aufrufst. In Unity mit GameObject bedeutet das, dass dein Monobehaviour überprüft, ob überhaupt eine Instanz existiert. Wenn nicht, wird dann ein GameObject erstellt, dann Component hinzugefügt und nun ist es verfügbar. Die Frage ist, wie kannst du das überprüfen? Dazu wird static variable verwendet. Der übliche (simple) Weg wurde schon durch @Singular gezeigt. Ein Singleton kann, aber muss nicht von außen erreichbar sein. Beispiel Playerlist.Instance.Players wäre von außen. Nun kann man das anders machen. Playerlist.Players. Jetzt greifst du auf etwas zu, aber lässt die Instance raus, sonst könnte man auch auf Member zugreifen. Vllt will man ja damit nur intern arbeiten. Meine Empfehlung bei sowas ist, dass man den selbst initialisieren sollte. Beispiel AudioPlayer.Init(). Nun AudioPlayer.Clips. Allerdings ist das bei Unity natürlich problematisch. Was wenn man eine Scene testen möchte, aber AudioPlayer.Init() erst im Hauptmenu aufgerufen wird? Schon kommen die erste Problem (aber dafür gibt es einige Lösungen.. Gott sei Dank :D) WANN sollte man das verwenden? Ein Beispiel wo es sinn macht. AudioPlayer.Play("pfad/zu/mein/sound.wav", volume, pitch, isLoop). Das ist ein gutes Beispiel. Mein ParticleSpawn System funktioniert so ähnlich. Ein besseres Beispiel wäre, wenn es überhaupt kein GameObject oder so erstellen muss. Beispiel Steamworks von Facepunch funktioniert ohne GameObject und ist von überall zugreifbar. WANN sollte man das NICHT verwenden? Ein Beispiel Player Klassen um da auf Variable zuzugreifen. PlayerHealthComponent.instance.Health. Ich benutze selbst sehr selten Singletons, aber ich habe auch dafür eine Technik entworfen, welches mir gewährleistet, dass es überall, egal in welcher Scene ich bin auch funktioniert. Leider brauche ich dafür ScriptableObject (geht auch ohne, aber finde ich unschön).
-
Also wenn du z.B. sowas ähnliches hast so könntest du machen: // Das beim Spieler script ausführen void KickPlayer(PhotonView playerView) { // Überprüfen ob es der MasterClient ist (also den Room erstellt hat - auch "host" oft genannt (was aber falsch ist) ). // Wenn nicht, dann abbrechen if(!PhotonNetwork.IsMasterClient) return; // Setze die Nachricht InfoBox infoBox = playerView.GetComponent<InfoBox>(); infoBox.SetMessage("You have been kicked out from the room/server"); // ODER InfoBox.SetMessage("You have been kicked out from the room/server"); // Das kann nur der Masterclient.. braucht man nicht überprüfen. PhotonNetwork.CloseConnection(playerView.Owner) } Dein InfoBox müsste dann natürlich die Funktion SetMessage haben. player.GetComponent<InfoBox>() das hier kann eigentlich nicht funktioniert, weil wenn man aus dem rausgeschmissen wird, dann werden auch Spieler objekte gelöscht und somit kannst du nicht es nicht anzeigen. Daran hab ich erst nicht gedacht. Deswegen würde ich InfoBox als static Klasse machen und einfach direkt den Text setzen und im Hauptmenü dann diesen Text anzeigen. Gibt aber noch komplizierteren Weg und den finde ich auch richtiger. Müsstest dafür PhotonNetwork.RaiseEvent und in irgendein Script OnEvent verwenden. Dazu unbedingt das hier lesen: https://doc.photonengine.com/en-us/pun/current/gameplay/rpcsandraiseevent#raiseevent. Da wird mit einem Beispiel gezeigt. Mich hat das selber interessiert und hab mal den Code analysiert und nachgelesen und es gibt keine KICK Funktion allgemein in Photon. Was im Hintergrund passiert ist eigentlich du sendest ein Spieler sowas wie "Kannst du aus dem Raum gehen" also Forderung natürlich und der Client sagt dann "ok" und führt PhotonNetwork.LeaveRoom(false). Also theoretisch verlässt man selbst den Raum. Deswegen mit Event kann man also seine eigene Kickevent schreiben und auch die Nachricht anzeigen. Gibt halt verschiedene Möglichkeiten. Das oben das Beispiel mit InforBox und statische Funktion usw ist glaub am leichtesten
-
Wenn du mit Player Object den von Photon meinst geht das nicht so oder ist die Player Klasse von dir selber geschrieben und ist ein Component? Wenn je dann einfach ein Verweis bzw Variable erstellen Z.B. public class Player { public InfoBox infoBox; } Aber das sind doch basics von C# oder meinst du was anderes?
-
Soweit ich weiß gibt es dafür kein Event mit Messages. Vielleicht gibt es ein Event, dass er aber keine Verbindung mehr hat oder aus dem Raum raus ist. Was du dann machen kannst ist, dass du bevor ein Spieler kickst bei ihm eine Nachricht zuweist. Das würde mit PunRPC gehen. Simple würde ich einfach eine Klasse mit static Variablen nehmen und dann diese Variable nachdem kick anzeigen.
-
Ein Smartphone selbst kann keine Videos aufzeichnen, sondern die Apps tun das in dem sie auf das Bild und Ton zugreifen. Das heißt du musst selber schreiben, wie du ein Video aufnehmen willst. Dafür gibt es bestimmt Libraries. Z.B. AVPro Movie Capture, aber kostet 200 Euro und ist für mehr komplexere Sachen gedacht.Das einzige was Unity tatsächlich eingebaut hat sind Screenshots. Wenn du selber wagen willst kannst du Mit Texture die Pixel form screen lesen. Das tust du ganz Zeit und packst dann in eine Liste. Ab da musst du mal schauen, was so man so benutzen kann um daraus ein Video zu machen. Mir fällt da spontan nichts ein.
- 1 reply
-
- 1
-
-
Hallo im Inspector lasse ich mir ein ObjectField anzeigen. So sieht das in OnInspectorGUI(). SerializedProperty textComponentProperty = serializedObject.FindProperty("m_textComponent"); EditorGUILayout.ObjectField(textComponentProperty); if (GUI.changed) { Debug.Log(textComponentProperty.objectReferenceValue); serializedObject.ApplyModifiedProperties(); EditorUtility.SetDirty(target); } Dort kann ich ein text component reinwerfen. Wenn ich nun ein Text component drag and drop mache, wird beim Debug.Log auch kein null angezeigt. Heißt, dass es funktioniert hat mit drag and drop, doch danach ist es sofort wieder null. Ich weiß gar nicht mehr was ich machen soll. Im selben component ist string dabei und das lässt sich speichern. Benutze 2020.2.3f1 Hab es doch heraus gefunden: Ich hab zwei Types die Text heißen und hat nach falschen Text gesucht. Unity hat mir aber keine Fehlermeldung gezeigt, dass die Types nicht passen, sondern machte daraus direkt null. Zweites Type ist ein Child von UI.Text.
-
Ist bissel her, aber ich würde es übers Netzwerk machen. Also einfach eine Konsolenanwendung schreiben, welches auch als Server dient. Wenn man Unity startet sollte es damit verbinden und die Daten runterladen.
-
Wenn irgendwo "Draw" steht, geht es meistens um eine Zeichnung in einem Frame. Leider kenn ich mich da nicht aus, aber bei 100.000 Meshs kann ich auch verstehen, dass man da hohe GPU Auslastung hat. Sieht man die 100.000 wirklich gleichzeitig. Du kannst nämmlich vllt sowas wie Culling machen und nicht zeichnen, wenn man sie nicht sieht. Ansonsten nimm doch einfach gameObjects mit Meshs. Da macht das Unity bissel automatisch.
-
Nicht direkt UI Tutorial, aber es wird gezeigt in einem Beispiel wie sowas aufgebaut werden kann bzw. sollte. Als Beispiel wird ein Inventar gezeigt, wie man Inventar UI-Scripte aufbauen kann ohne, dass die Scripte mit einander verbunden werden müssen. Eigentlich wirklich gutes Beispiel. Ich selbst verwende es mal so wie im Video und mal nicht so. Ich mag eher selber Coden und wahrscheinlich mag ich es deswegen manchmal anders, aber wenn es eher um Designer-fragen und Handhabung geht, dann ist das im Video echt gut, denn wenn du was ändern willst, dann kannst du das ohne im Code was zu ändern tun.
-
Hast du die Beschreibung gelesen? Es steht da deutlich, dass VTRK SteamVR ab version 2 nicht unterstützt. https://assetstore.unity.com/packages/tools/integration/vrtk-virtual-reality-toolkit-vr-toolkit-64131
-
Das Forum lebt auf jeden Fall. Eventuell gibt es kein Rat zu manchen Fragen oder, wenn manche Fragen (sorry, wenn das zu hart klingt) zu dämlich klingen, möchte man manchmal (zu Mindest bei mir so) nicht die Zeit da rein investieren. Ich mein jetzt nicht damit, dass die Frage selbst doof ist oder sondern, um den Inhalt bzw. Kontext. Wenn jemand fragt "Wie lösche im Multiplayer etwas", das ist einfach zu Allgemein. Was benutzt du (der die Frage stellte)? Pun, Mirror, Lidgren oder eigenes? Steht nichts davon und lässt sich daher nicht wirklich beantworten und auch eine Frage, was man schnell mit Google raus findet. Aber wer eine Antwort will, der strengt sich schon beim Schreiben an. Wenn man so umguckt da, sieht man auch, dass einige viel schwierigeres versuchen zu lösen und die verdienen meiner Meinung nach mehr Aufmerksamkeit, da dies nicht so mit "googlen" beantworten lässt. Zusätzlich dazu, ich besuche einmal pro Tag bis alle paar Tage das Forum. Wenn man schneller Antworten haben will zu kleinen Fragen, kann man ja sowas wie Discord benutzen. Das hier gehört zum Beispiel zu den Posts, wo ich ungern Lust habe. Du hast es "nicht gebacken" bekommen, aber was hast du versucht zu backen? Hast du zum Beispiel NetworkManager.onlineScene angewendet? Ich muss hier rumrätseln. Und ja mit OnServerAddPlayer kann man arbeiten, aber muss nicht sein, wenn man AutoCreate Player (oder wie das auch heißt) aktiviert hat. Für OnServerAddPlayer muss aber der Spieler ClientScene.AddPlayer ausführen, sonst wird OnServerAddPlayer nicht ausgeführt. Übrigens würde ich Mirror empfehlen. Es ist die weiter Entwicklung von UNet, da ja UNet nicht weiter entwickelt wird. Bis heute wird Mirror noch weiter entwickelt und bin sogar bei den in Discord ein bisschen aktiv.
-
Bill Gates sagte eins: "I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.". Ich lebe tatsächlich nach dieser Prinzip. Ich versuche immer alles schneller und leichter zu machen. Und darum hier mal ein kleiner Code von mir, welches ihr wahrscheinlich auch ab und zu brauchen könntet. Hier ist ein Script welches OverlapCircle etwas erweitert. Öfters habe ich das Problem gehabt, dass ich OverlapCircle einsetze, aber dann nochmal durch loopen muss um zu schauen, ob ich die richtigen Collider2D überhaupt gefunden habe. Aber warum das nicht so bauen, dass ich direkt die Richtigen bekomme? https://gist.github.com/MaZyGer/b4c45395bd6a5d06722a0eecf71c850e Beispiel wenn du eine Granate wirfst und beim Aufprall noch Monster suchen willst, die aber auch noch am Leben sind (um denen Schaden hinzuzufügen): List<Monster> monsters = new List<Monster>(); int count = OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { }, monsters, m => !m.IsDead ); // Andere Möglichkeiten int count = OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { }, monsters); int count = OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { }, monsters, c => c.GetComponentInChildren<Monster>()); int count = OverlapCircle<Monster>(Vector2.zero, 10f, new ContactFilter2D() { }, monsters, c => c.GetComponentInChildren<Monster>(), m => !m.IsDead); Der Code im Link wird vllt in der Zukunft erweitert. Je nachdem was ich brauche werde ich hinzufügen.
-
Wahrscheinlich Mono selbst ist nichts anders um die Möglichkeit zu geben Plattform unabhängig zu programmieren, das mit C#. Ein Beispiel, ich habe ein Server programmiert, welches mit C# geschrieben wurde und welches sogar einen .exe beinhaltet. Das Programm läuft sowohl in Linux aber auch im Windows. Mittlerweile kann man sogar die Datei direkt starten. Früher musste ich noch mono zusätzlich ausführen. Früher war mono nicht für Systeme gedacht. Eigentlich nur windows. Kurz: Mono hilft die diese Programme die programmiert wurde auszuführen, zu compilen (ja auch in Linux kann man sie compilen und ausführen). Net Standard definiert, welche Libraries in der Programmierung benutzt werden können. Beispiel Netstandard 2 die framework 4.6.1 und die netstanard 1 wäre framework 4.5. Da sind auch aber andere Pakete dabei. Nicht nur Framework. Z.B. Core. Net Framework waren nicht beabsichtigt auf anderen Projekten zu funktionieren. Durch Xamarin und Mono wurde was neues erschaffen, wo man dann für anderen Plattformen erweitern konnte. Net Core benutzt KEIN mono. Wurde bewusst so vom Libraries aufgebaut, dass man auch für andere Plattformen verwenden kann. Ich habe jetzt nicht selbst benutzt, aber ich vermute mal, dass da sowas gibt wie if application is linux then usw. So wie ich auch verstanden habe hat Core auch keine libraries für Interfaces. Sprich kein Fenster wo man navigieren kann (Windows forms, WPF usw). Es ist der originale Mono zu mindest in der API Bereich. Zu modifizieren und zu ändern wäre nicht gut, dann müssten wir auch die Libraries dafür runterladen. Z.B. müsste ich irgendwas zusätzlich auf meinem Linux installieren, damit auch Unitys Version funktionieren soll. Aber der Standard Mono läuft. Unity ist ein Editor. Unity benutzt mono vom Microsoft. Natürlich! Man kann derzeit zwischen net 2.0 standard under net 4.x auswählen. Das sind eigentlich keine Versionen sondern Paketzustellungen. Früher konnte man auch Net 3.5 auswählen. Wichtig ist hier zu unterscheiden, dass wenn dahinter standard steht, dass es nicht das gleiche ist wie, ohne Standard. Standard heißt, dass da bis zu bestimmte libraries, versionen usw enthalten sind. beispiel Framework, Core, Mono usw. Die Schreibweise ist um das zu erkennen ist: Net 4.x bedeutet, dass höchst mögliche soll erlaubt werden beim Programmieren. z.B. .Net Framework 4.7.2 usw. Unity Editor natürlich muss das unterstützen. Sonst geht es nicht. Siehe oben Unity hat ist noch nicht bei der Framework Version. Deswegen geht es noch nicht. Ich glaube standard 2.1 wird das nicht werden. Wird eher immer noch net 4.x sein, da wie ich oben schrieb standard auch viele Sachen hat die wir aber nicht in Unity brauchen. Net 4.x sollte nur die Framework Version sein.
- 1 reply
-
- 1
-
-
Was Namensfindung angeht kann ich euch Tipps geben. Dies bezieht aber auf Spiele, die tatsächlich Erfolg haben sollen z.B. durch Steam. Man muss sich die Fragen erst mal stellen. 1. Hat das Spiel was einzigartiges? Wenn ja, dann auf keinen Fall so leichte Namen nehmen, wo man bei der Suche zisch andere Spiele findet oder ihr nimmt explizit den Namen, was das Besondere hervorhebt. Beispiele: Titanfall - Weil titane aus dem Himmel fallen Dota (Defense of the Ancients) - Weil man die Ancients verteidigen muss.. ist es zerstört, verliert das Team. Payday - Weil es darum geht, dass man im Spiel immer mehr Geld anhäuft. Portal - Weil man fast nur Portale benutzen muss um voranzukommen (hier also auch das Gameplay). Squad - Weil das Spiel hauptsächlich ohen Kommunkation nicht geht. Squadsmitglieder und Leaeder müssen untereinander kommunizieren sonst ist es verloren (wie in Reallife halt^^). Space Engineers 2. Irgendein "dummen" oder "lustigen" Namen Es gibt Spiele (oder auch Filme usw), die bewusst etwas Dummes oder Lustiges als Name nehmen, weil sowas wie Ohrwurm ist und auf den Ohren bleibt. Beispiel: Garry's Mod (weil der Entwickler Garry ist und die Firma heißt Facepunch). Pavlov VR Mehr fallen mir da gerade nicht ein. Aber bei Apps gibt es jede Menge sowas. 3. Einen einzigartigen Namen geben, aber nichts zum Content aussagt oder sehr sehr gering etwas aussagt. Sowas ist finde ich immer wieder toll, wenn es Namen erfunden werden, die gar nicht existieren. Und das macht das Spiel dann sehr besonders. Jeder von uns kennt z.B. Half-Life. Beispiele: Half-Life Rust Counter-Strike Stellaris (Das Wort aber bezieht sich aber auf Stellar und ist ne Mischung aus Latein) - Ist ein Weltraumspiel Just Cause Gothic Fortnite - Wobei hier der Name von Fortnight kommt und um Four Nights (also 14 Tage und Nächte) geht. Max Payne - Kann man auch zu Punkt 1 zuordnen, aber da geht es echt um diesen Charakter selbst und seine Story. Über Content wird hier nichts gesagt. Die Besonderheiten des Spiels ist ja nicht Max Payne selbst sondern die schönen Bullettimes. ANNO XXX - Die ganzen Anno reihen ^^. 4. Namen die einfach gefunden werden sollen. Manchmal nimmt auch Namen bewusst, dass man bei der Suche finden soll. Sowas empfehle ich nicht, weil man da schon sehr oft Namensverletzung hat. Ein Beispiel von mir. The revenge of the Space Invaders. - Geschützter Name Space Invaders. Auch wenn im Spiel um Invader und Space geht, darf man es nicht so verwenden. Was aber geht ist: Invaders from Space: The Revenge. Dot Color Switch - Color Switch geschützt. Dot switch color oder Switch dot color würde gehen. Oder ganz anderen Namen wie Dot color swap. Persönliche Meinung. Ich mag es gar nicht, wenn der Titel eines Spiels so bestimmt wird, was auch Gameplay / Content aussagt. Beispiel: Back to earth: Ist nicht interessant genug. Warum? Ich weiß ok sie waren von der Erde weg und wollen zur Erde zurück. Das war es auch. Anders wäre es aber mit einen interessanten Namen davor (einfach so mal spontan, auch wenn es sich kacke anhört). Hitstrikes: Back to earth - Hier würde man sich fragen, was sind Hitstrikes. Wieso wird das so genannt. Gibt es noch andere Spielreihen davon?. Ein Schluss Wort Garry Newman sagte: Was wenn "Mario" das Spiel einfach nur "Coin Grab" hieße. Niemand würde an das Spiel sich später erinnern.
-
Soda - ScriptableObject Dependency Architecture
MaZy replied to Sascha's topic in Assets, Prefabs und Tools
Nein kein Odin. Also mein Beispiel zeigt auch keine Werte an. War auch für mich nicht wichtig. Könnte es eventuell mit Custom Inspector anzeigen lassen, aber hab sowas für ScriptableObjects nie gemacht. -
Soda - ScriptableObject Dependency Architecture
MaZy replied to Sascha's topic in Assets, Prefabs und Tools
Glückwunsch für den neuen AssetStore Packet. Ich persönlich bin nicht so der Fan davon (bezogen auf das Video) und ich meine das gab es frei zu downloaden. Aber wenn ich mal sowas brauche mache ich passend zum Objekt. Beispiel passend zu meinem Projekt, Health, Shield.. (siehe unten) alles in einem ScriptableObject und das benutze ich das als Kommunikations (Ja Events gibt es da auch). Ich benutze sehr selten mittlerweile Singletons. Nur bei Komplexen ein System Sachen die einmal da sind (Beispiel mein InputReader Klasse) oder Kleinigkeiten wie (public static) Player.localPlayer. Bei komplizierteren Sachen stell ich mir das aber harter vor. Ich frage mich zum Beispiel, wie man das verwenden könnte, wenn man jetzt kleinere Minibosse hat, die ab und zu da sind dann im HUD einen Healthbar anzeigen möchte. Muss ich für jeden SO Asset erstellen? Gut es könnten ja alle, den einen Asset teilen, aber was wenn mal zwei Minibosse gleichzeitig gibt und ich will beide Healthbars anzeigen lassen.. Dann lässt sich das nicht so leicht teilen. Ein Beispiel wie ich zum Beispiel mein Health und Shield UI update. [CreateAssetMenu] public class DamageEventSO : ScriptableObject { public EventValue<float> Health; public EventValue<float> Shield; } public struct EventValue<T> { public UnityAction<T> OnValueChanged; T value; public T Value { get => value; set { this.value = value; OnValueChanged?.Invoke((T)(object)this.value); } } } So wie man sieht, ist das hier generic und brauche da nicht floats, ints oder sonst ähnliches. -
Unity mit einem node.js TCP Server verbinden?
MaZy replied to Lightstorm's topic in Multiplayer und Networking
Das dürfte nicht gehen, da ja ein Handshake oder so aufgebaut wird und die sind höchstwahrscheinlich unterschiedlich, aber man kann den node.js client in Unity benutzen und damit verbinden. -
GameObjects die per script geändert wurden sind nicht persistent
MaZy replied to MaZy's topic in Allgemeine Hilfe
Ok hat lange gedauert, aber man muss mit serializeObject arbeiten. Man muss also in meinem fall das hier machen SerializedObject scenenObjectSO = new SerializedObject(scenenObjects); var scenenNetId = scenenObjectSO.FindProperty("scenenNetId"); scenenNetId.intValue = i; scenenObjectSO.ApplyModifiedProperties(); SerializedObject netObjectSO = new SerializedObject(netObject); var netIdProp = netObjectSO.FindProperty("netId"); netIdProp.intValue = i; netObjectSO.ApplyModifiedProperties();- 1 reply
-
- 1
-
-
Hallo, ich habe einen Script welches im Editor automatisch läuft. Der überwacht, ob sich in der Hierarchy was geändert hat. Wenn ja sucht es nach bestimmten Components und setzt dann die Werte (einfach jeden eine bestimmte Zahl zuweisen). Doch sobald man von ein anderen Scenen in die Scene in Playmode wechselst sind die Werte plötzlich wieder zurück gesetzt zu den Wert, den ich per Hand eingegeben habe ODER es nimmt den Standardwert von Prefab oder so. Ich vermute mal, dass mir irgendwas wie speichern fehl, aber finde dazu kaum was. Es hat was zwar mit Editor zu tun, aber erbt den Editor Script nicht. Auch was mir eingefallen ist, dass normaleweise ja wenn man in der Scene im Inspector vom Prefab Werte ändert, dass es in Fettschrift angezeigt wird. Das passiert beim Script auch nicht. using Maz.Network.UnityEngine; using System.Linq; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; [InitializeOnLoad] public static class NetworkSceneObjectEditor { static NetworkSceneObjectEditor() { if(!EditorApplication.isPlaying) EditorApplication.hierarchyChanged += OnHierarchyChanged; } static void OnHierarchyChanged() { if (EditorApplication.isPlaying) return; var all = Resources.FindObjectsOfTypeAll<NetworkSceneObject>(); var networkSceneObjects = all.Where(obj => (obj.hideFlags & HideFlags.HideInHierarchy) != HideFlags.HideInHierarchy); //Debug.LogFormat("There are currently {0} GameObjects visible in the hierarchy.", networkSceneObjects.Count()); int i = 0; foreach (var o in networkSceneObjects) { var netObject = o.GetComponent<NetworkObject>(); if (netObject == null) { Debug.Log("NetworkObject is missing! NetworkSceneObject will not work"); continue; } o.scenenNetId = i; netObject.NetId = i; //EditorUtility.SetDirty(o); //EditorUtility.SetDirty(netObject); //EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); i++; } Debug.Log($"Hiearchy changed"); } } Hab paar Dinge versucht mit speichern der Scene oder SetDirty, aber da merke ich, dass dann dieser Event gespamt wird. Hab keine weiteren Ideen mehr.