Jump to content
Unity Insider Forum

MaZy

Members
  • Posts

    706
  • Joined

  • Last visited

  • Days Won

    35

MaZy last won the day on February 21

MaZy had the most liked content!

About MaZy

  • Birthday 02/20/1988

Profile Information

  • Gender
    Male
  • Location
    Hannover

Recent Profile Visitors

40,269 profile views

MaZy's Achievements

Advanced Member

Advanced Member (3/3)

197

Reputation

  1. 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?
  2. 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.
  3. 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.
  4. 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 ^^.
  5. 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.
  6. 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?.
  7. 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).
  8. 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
  9. 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?
  10. 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.
  11. 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.
  12. 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.
  13. 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.
  14. 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.
  15. 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.
×
×
  • Create New...