Jump to content
Unity Insider Forum

MaZy

Members
  • Posts

    704
  • Joined

  • Last visited

  • Days Won

    34

MaZy last won the day on September 5 2022

MaZy had the most liked content!

About MaZy

  • Birthday 02/20/1988

Profile Information

  • Gender
    Male
  • Location
    Hannover

Recent Profile Visitors

35,824 profile views

MaZy's Achievements

Advanced Member

Advanced Member (3/3)

196

Reputation

  1. 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.
  2. 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 ^^.
  3. 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.
  4. 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?.
  5. 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).
  6. 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
  7. 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?
  8. 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.
  9. Schon etwas her mit Photon, dass ich mal benutzt habe, aber in PUN2 soweit ich weiß, gibt es keine serverseitigen Sachen, weil ja Cloudbasiert ist, allerdings gibt es ein MasterClient (der diesen Lobby/Raum erstellt hat). Kannst mich gerne besseres belehren, weil ist schon auch lange her. Wenn es nicht automatisch synchronisiert wird, bist du dafür zuständig. Man kann RPC Methoden verwenden oder die Serializationsysteme mal anschauen, ob auch andere Wege gibt. Dein Grundgedanke muss so sein, dass, wenn ein Spieler etwas SELBER tut, dass auch bei anderen, die wichtigen Sachen genauso passieren muss. Beispiel, wenn du z.B. ein Item zu einem Slot bewegst, dann könntest du sowas wie SetItemSlot(slotId, item) als RPC machen. Die Bewegung des Items ist ja egal, aber das Setzen des Slots ist ist wichtig. Ab da sollte meist für jeden Spieler gleich sein. Spieler weiß über den SlotId bescheid, weiß um welches Item es geht. Kann also bei sich im Spiel im SetSlot den Slot mit Item versehen. Und schon sollte bei jedem synchron ablaufen. Sollte es so sein, dass auch Spieler nachträglich dazu kommen, müssen nur einfach die aktuelle Liste mit den Informationen gesendet werden. Ich weiß jetzt nicht, ob bei Photon sowas automatisch gibt. Aber dies auf jeden Fall über den Masterclient tun.
  10. Also, wenn man das Bild analysiert sieht es tatsächlich so aus, als hätten sie selber den schwarzen Overlay erstellt. Das sieht man daran, dass manche Würfel unter den Overlay anfangen und manche nicht. Daher denke ich mal, für den Tutorial am Anfang haben die vllt ganz schnell simpel gehalten und selbst gemacht. Wenn man auch ne Maske benutzt denke ich mal ist es sogar nicht möglich wo anders zu drücken, aber auf die hellen Felder kann man drücken. Manchmal also einfach simpel halten und selber im Photoshop schneiden
  11. Ich bin kein fan von Tags bei solchen Dingen, deswegen hier mal Grob wie ich das machen würde. Wenn du die neue Kanone erstellst also mit newKanone, dann füge das doch in eine Liste hinzu. Beispiel List<Kanone> kanonenListe. Die Instanz kann auch eine ID beinhalten, wenn du wirklich unterscheiden musst und relevant ist. Beispiel ID 1. Jetzt kannst du Beispiel ne UI erstellen und siehst die Kanonen mit IDs und kannst sie auswählen. Oder per script auf die Liste zugreifen und durch loopen bis die ID == 1 ist. Bei sowas benutze ich gerne static Listen. Beispiel (in der Kanone Klasse): public static List<Kanone> kanonenListe = new List<Kanone>(). void Start() { this.Id = kanonenListe.Count; } void OnEnable() { kanonenListe.Add(this); } void OnDisable() { kanonenListe.Remove(this); } kanonenListe wird auch immer leer sein, wenn man eine Scene wechselt, da ja OnDisable aufgerufen wird, wenn der Component zerstört oder deaktiviert wird. Vllt dazu noch Find funktionen schreiben. public static bool TryFindById(int id, out Kanone kanone) { kanone = null; foreach(Kanone k in kanonenListe) { if(k.Id == id) { kanone = k; return true; } } return false; } jetzt kannst du einfach das machen if( Kanone.TryFindById(1, out var kanone) ) { Debug.Log("Kanone wurde gefunden: " + kanone.Id); } else { Debug.Log("Nicht gefunden"); }
  12. Also beim Addressables hast du das, aber hab noch nie verwendet. Eigentlich interessant. Ich habe tatsächlich nun die Lust bekommen, sowas zu simulieren. Man kann doch theoretisch die GameObjects nacheinander aktivieren damit es etwas "sanfter" rein lädt oder nicht? Btw reinschauen wie Addressables das macht. Wüsste nur nicht wie ich das testen könnte, ob es was bringt. Vllt 5000 cubes einbauen mit scripts oder so und gucken ob es jedes mal laggt.
  13. Benutzt du IAPListener mit dem OnPurchase Event? Ist das nicht nur wenn man etwas gekauft hat? Ansonsten laut doku sieht man das hier. /// <summary> /// Your IStoreListener implementation of OnInitialized. /// </summary> public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { extensions.GetExtension<IAppleExtensions> ().RestoreTransactions (result => { if (result) { // This does not mean anything was restored, // merely that the restoration process succeeded. } else { // Restoration failed. } }); } Bei result = true muss man wohl die Products durch loopen und schauen was man wohl besitzt. Ist leider sehr lange her, wo ich das mal gemacht habe und mittlerweile benutze ich auch aus dem AssetStore etwas, was beim HumbleBundle dazu bekommen habe.
  14. 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.
  15. Ich hab kein Test gemacht, aber ich weiß das MethodInfo zu Invoken ca. 100000x langsamer ist als ein Delegate. Mit System.Linq.Expressions kann man aber Delegates erstellen / "compilen", die sonst nicht möglich waren wegen den generic types. Somit werden die Serializer und Deserializer erstellt und für die RPCs die Delegates auch. Ist noch nicht perfekt und kam auch nicht mehr dazu weiter zu machen, aber hatte da noch ein paar Ideen es zu verbessern.
×
×
  • Create New...