Jump to content
Unity Insider Forum

Singular

Members
  • Posts

    103
  • Joined

  • Last visited

  • Days Won

    1

Singular last won the day on August 2

Singular had the most liked content!

About Singular

  • Birthday 12/08/1987

Profile Information

  • Gender
    Male
  • Location
    Königswinter

Recent Profile Visitors

359 profile views

Singular's Achievements

Advanced Member

Advanced Member (3/3)

2

Reputation

  1. Perfekt. So habe ich es mir gedacht. Jetzt habe ich allerdings das Problem, dass meine events nicht Triggern... Die Rewarded Ads funktionieren, die interstitial Ads aber nicht. public void Start(){ rewardedAd = new RewardedAd(rewardAdID); this.rewardedAd.OnAdLoaded += HandlerRewardLoaded; this.rewardedAd.OnAdFailedToLoad += HandlerRewardFailedToLoad; this.rewardedAd.OnAdOpening += HandlerRewardOpening; this.rewardedAd.OnAdClosed += HandlerRewardClosed; this.rewardedAd.OnAdFailedToShow += HandlerRewardFailedToShow; this.rewardedAd.OnUserEarnedReward += HandlerUserEarnedReward; /* wenn ich an dieser Stelle * interstitial = new InterstitialAd(intestitialAdID); * einsetze geht gar nichts mehr. Dann wirft mein GameManager plötzlich Fehler aus, * er würde das Material das meinem Spieler zugewiesen ist nicht mehr finden... Ich weiß nicht wo der Zusammenhang ist, aber egal*/ this.interstitial.OnAdLoaded += HandlerInterstitialLoaded; this.interstitial.OnAdFailedToLoad += HandlerInterstitialClosed; this.interstitial.OnAdOpening += HandlerInterstitialOpening; this.interstitial.OnAdClosed += HandlerInterstitialClosed; this.interstitial.OnAdFailedToShow += HandlerInterstitialClosed; } private AdRequest CreateAdRequest(){ return new AdRequest.Builder().Build(); } public void RequestRewarded(){ if (rewardedAd != null) rewardedAd.Destroy(); rewardedAd.LoadAd(CreateAdRequest()); } public void ShowRewarded(){ RequestRewarded(); if (rewardedAd.IsLoaded()){ rewardedAd.Show(); } } public void RequestInterstitial(){ if (interstitial != null) interstitial.Destroy(); interstitial = new InterstitialAd(intestitialAdID); interstitial.LoadAd(CreateAdRequest()); } public void ShowInterstitial(){ RequestInterstitial(); if (interstitial.IsLoaded()){ interstitial.Show(); } } //Handler Rewarded ADs [...] //Handler Interstitial ADs public void HandlerInterstitialLoaded(object sender, EventArgs args) { } public void HandlerInterstitialFailedToLoad(object sender, EventArgs args) { gm.LoadMainMenu(); } public void HandlerInterstitialOpening(object sender, EventArgs args) { ac.audioSource.mute = true; } public void HandlerInterstitialClosed(object sender, EventArgs args) { if (!ac.mute) { ac.audioSource.mute = false; } SceneManager.LoadScene("MainMenu"); }
  2. Hallo zusammen, ich möchte jetzt als letzten Schritt vor veröffentlichung Werbung in meinem Spiel einbinden. Nachdem ich mich da ein wenig schwer getan habe mit den RewardedVideoAds (vor allem weil ich mich mit dem EventSystem noch null auskenne [steht als nächstes auf meiner Agenda]) funktioniert es wiedererwarten doch ganz gut. Eine Sache habe ich allerdings noch nicht gefunden, ich gehe aber davon aus, dass auch das über Events gehandhabt wird. Sobald der Spieler entweder verloren hat oder sich entschieden hat das Spiel zu beenden und ins Hauptmenü wechseln will wird er nochmal mit einer Werbeanzeige belohnt also einer Interstitial Ad. Da diese beim wechsel ins Hauptmenü angezeigt werden soll sieht man diese Anzeige allerdings sage und schreibe eine halbe Sekunde und ist sofort im Hauptmenü. Wie kann ich es einbinden, dass der Spieler erst die Ad geschlossen haben muss bevor das Hauptmenü geladen wird? Bzw, sollte keine Ad geladen werden können, soll der Spieler trotzdem ins Hauptmenü gelangen können... Vielen Dank für eure Hilfe.
  3. Wobei... 🤔 Eine Frage habe ich da noch... Warum nicht? Das tue ich doch die ganze Zeit. Dinge, die während der Laufzeit passieren, speichere ich in einem SO. Beispiel wären da die Punkte meines Spielers. Die werden (zur Laufzeit) in einem SO abgelegt damit ich diese die Szenen hinweg über speichern und abrufen kann. Aber nicht nur Szenenübergreifend sondern sogar Spielübergreifend. Ich habe extra, damit ich die Punkte im SO zurück setzen kann einen Button eingebaut, damit diese Punkte wieder zurück gesezt werden um "ein neues Spiel zu starten". Die Punkte kommen auch aus der Laufzeit und werden immer von Spiel zu Spiel, von Neustart zu Neustart übernommen und gespeichert. Dann wäre meine Frage, WELCHE Daten können während der Laufzeit nicht gespeichert werden? liegt es an der größe, (Vektoren fressen wohl mehr speicher als ein int) oder ist das eher gut glück welche Daten drin liegen und welche nicht?
  4. Achso, fals die Frage kommt, warum ich das nicht direkt in Json oder in eine CSV Tabelle... Die Frage beantworte ich euch gerne: Keinen Plan wie das geht... 🤪
  5. Hallo zusammen, mein Spiel neigt sich so langsam dem Ende und ich bin bald fertig *freu* aber ich muss noch ein paar Level zusammen klicken. Um jetzt nicht pro Level 100 Vektoren setzen zu müssen oder alles händisch zu machen habe ich mir einen eigenen LevelEditor gebastelt. In dem Level Edito kann ich kurz zusammengefasst meine Blöcke setzen die dann von der Position auf einem Grid gesetzt werden: So ungefähr sieht das ganze aus. Die Blöcke oben habe ich durch einfaches klicken gesetzt. Unten habe ich ein paar andere einstellungen Farbe usw. Ich weiß nicht ob man es noch erkennen kann der Wichtige Button ist der in der Mitte. Der soll die Positionen der Blöcke in einem SO abspeichern. Das Funktioniert auf wunderbar. Wenn ich direkt danach mein SO nehme und in meine GameScene wechsle und dort das SO einsetze kann ich das gerade gebaute Level auch spielen. Jetzt kann es aber zwei verschiedene Dinge geben die alles gepeicherten Daten in meinem SO löscht. Entweder ich beende das Spiel weil ich das Level ausprobiert habe. Direkt danach ist alles weg, oder ich klicke eine zweites Level zusammen. Dann werden die Daten von dem Level davor gelöscht... (Also Level 1 wird gelöscht obwohl ich gerade Level 2 abgespeichert habe. Level 2 ist dann auch da in einem anderen SO) Es gibt in meinem Code nur eine einzige Stelle an denen solche Daten gelöscht werden das ist bei meinem Editor wenn das Level überschrieben werden soll (selbst wenn ich diese Zeilen auskomentiere werden die Daten gelöscht) Ich habe im Editorskript nur ein SO abgelegt. Das wechsle ich durch sobald ich das nächste Level anfange. Weiß jemand woran das liegen könnte? Sind SOs so Fehleranlällig, dass ich sie am besten direkt in Json oder in Text umwandeln sollte...? Hier der Code für den Editor: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LevelEditorManager : MonoBehaviour { [Header("Speicherort")] public LevelObject saveSpot; [Header("Voreinstellungen")] public Camera cam; public GameObject block; public Material[] mat; private int matColor = 0; private int lifes = 0; public List<Vector2> plannedPositions; public List<GameObject> plannedBlocks; public List<int> plannedMat; public List<int> plannedLifes; public bool doubleclick = false; [Header("UI")] public Text lifetext; public Image matImage; private void Start() { UIsinc(); } void Update() { if (Input.GetMouseButtonDown(0)) //Prüft Kontinuierlich wo auf dem Bildschirm geklickt wird { Ray ray = cam.ScreenPointToRay(Input.mousePosition); Vector3 v3 = ray.origin; Vector2 v2; v2.x = berechneX(v3.x); //Berechent die Koordinate X an der der Block gesetzt werden soll v2.y = berechneY(v3.y); //Berechent die Koordinate Y an der der Block gesetzt werden soll if (CheckPosition(v2)) //CheckPosition überprüft ob an der Stelle schon ein Block sitzt { //Wenn ja, wird der Block gelöscht ansonten geht es hier weiter: GameObject b = Instantiate(block, v2, Quaternion.identity); //setzt den Block an der berechneten Stelle b.GetComponent<Block>().mat = mat[matColor]; //übergibt dem Block die eingestellte Farbe plannedPositions.Add(v2); //speichert den Vektor des Blocks plannedBlocks.Add(b); //speichert den Block (wird später nicht mit abgespeichert plannedMat.Add(matColor); // speichert die Farbe als int plannedLifes.Add(lifes); //speichert die leben des Blocks ab } } } public void UIsinc() //Aktualisiert die UI { lifetext.text = (lifes +1).ToString(); matImage.material = mat[matColor]; } private float berechneX(float x) //berechnet das Grid für die X koordinate private float berechneY(float y) //berechnet das Grid für die Y koordinate public void lifePlusMinus(int i) //einstellung der Leben für den Block public void MatPlusMinus(int i) //einstellung der Farbe für den Block private bool CheckPosition(Vector2 v2) { if(v2.x == 88 || v2.y == 88) //Prüft ob der Spieler außerhalb des Spielfed geklickt hat { return false; //Es wird kein neuer Block gesetzt } for(int i = 0; i < plannedPositions.Count; i++) { if(v2 == plannedPositions[i]) { plannedPositions.RemoveAt(i); //löscht die Position des gepeicherten Blocks Destroy(plannedBlocks[i]); //Zerstört das Objekt plannedBlocks.RemoveAt(i); //löscht den Block aus der Liste plannedLifes.RemoveAt(i); //löscht die Leben aus der Liste plannedMat.RemoveAt(i); //löscht die Farbe aus der Liste return false; //Es wird kein neuer Block gesetzt } } return true; } public void Save() { bool g = false; if (saveSpot.blockPos.Count > 0 && doubleclick) //Es gibt bereits einen Speicherstand & Das war der zweite Klick auf den Button { Debug.LogWarning("Spielstand wird überschrieben!"); saveSpot.blockPos.Clear(); //löscht die Alten Daten saveSpot.blockMat.Clear(); //löscht die Alten Daten saveSpot.blockLifes.Clear(); //löscht die Alten Daten g = true; //Jetzt können die Daten gespeichert werden } else if (saveSpot.blockLifes.Count > 0 && !doubleclick) //Es gibt bereits einen Spielstand & Das war der erste Klick auf den Button { Debug.LogWarning("Soll überschrieben werden?"); StartCoroutine(Doppelklick()); //zählt einen Timer. In dieser Zeit muss nochmal geklickt werden damit gespeichert wird } else { g = true; } if (g) { //Speichert die zuvor geplanten Daten in dem Scriptable Object ab for (int i = 0; i < plannedPositions.Count; i++) { saveSpot.blockPos.Add(plannedPositions[i]); saveSpot.blockLifes.Add(plannedLifes[i]); saveSpot.blockMat.Add(plannedMat[i]); } Debug.Log("POSITIONEN GESPEICHERT!!!"); } } IEnumerator Doppelklick() { doubleclick = true; yield return new WaitForSecondsRealtime(1); doubleclick = false; } }
  6. Mein Spiel soll auf dem Handy laufen. Ich will da keine großen Spielereien haben sondern kurz und klaren Code, der nicht zuviel unnötigen Kram macht. (Ich haße es, wenn bei Spielen mein Handy zu heiß wird) Wie gesagt an die Clear Methode habe ich gar nicht mehr gedacht aber, da ich nochmal alle Bälle aufrufen muss um die Punkte einzusammeln, dann kann ich in dem Zug sie gleich aus der Liste austragen und sie danach zerstören. Ob ich das vorwärts oder Rückwärts tue ist den Bällen zum glück egal.^^ Okay, dann bringt es nichts auf diese Art und weise eine Liste zu Kompieren. Das müsste ich dann wohl auch wieder mit einer for-Schleife lösen und jeden einzelnen Wert in die neue Liste übertragen oder gibt es eine bereits implemetierte Methode eine Liste zu Kopieren?
  7. 🙄 Ja du hast was übersehen... DAS WÄRE JA ZU EINFACH...!!! 😄 tatsächlich wäre das jetzt sicherlich eine Laufzeitanalyse wert, zu schaunen was weniger Zeit frist... Die Bälle auf dem Spielfeld sammeln Punkte. Wenn der Spieler aber schon gewonnen hat, müssen diese Punkte noch eingesammelt werden --> daher die Methoder "resetMultipier()". Heißt also ich müsste dennoch eine foreach schleife machen um die Punkte einzusammeln und anschließend die Bälle zerstören um dann wieder die Liste zu leeren... wären also: - foreach um die Punkte einzusammeln und die Objekte zu zerstören - list.clear ist unterm strich wahrscheinlich auch nochmal eine fo Schleife... Wahrscheinlich auch eine Option, aber wenn ich das ganze mir einem Schleifendurchlauf mache, in dem ich eh die Objekte in der Hand habe, macht das am meisten Sinn denke ich. Aber unterm Strich hast du recht list.clear am ende würde auch gehen tatsächlich.
  8. Okay, aber genau deswegen erstelle ich ja eine Temporäre Liste, von deraus die Objekte aufgerufen und zerstört werden. Aus dieser Liste werden die Objekte nicht abgemeldet. Da fliegen mir dann (oder sollten eigentlich, wenn ich keinen Fehler bekommen würde) ein paar "Missing Objects" herum, die mir dann egal sein können, da die Liste am Ende eh wieder gelöscht wird... Bedeutet aber im Umkehrschluss, ich kann eine foreach Schleife einer Liste NICHT nutzen um Objekte aus einer Liste zu Zerstören, weil dann ein neues (in dem Fall dan ein Missing Object") auftaucht, über das er dann auch noch itterieren müsste? EDIT: Okay, Nein Zerstören geht, aber list.Remove geht nicht. Allerdings selbst mit der alten Liste: public class Test : MonoBehaviour { public List<GameObject> list; void Start() { List<GameObject> listTemp = list; foreach(GameObject g in listTemp) { list.Remove(g); //<-- Geht nicht Destroy(g); //<-- Geht } } } Wobei ich mich ein wenig wundere, weil ich in meinem Test die erste Liste nehme, die ich ja nicht in der foreach-schleife aufgerufen wird. Dann stellt sich für mich die Ftrage, was ist das für eine listTemp, die dort erstellt wird? Ist das nur ein Pointer, der dann doch nur auf list zeigt, bzw eine Liste von Pointern, die auf die GOs zeichen? Selbst wenn ich das ganze noch erweitere: [...] List<GameObject> listTemp = new List<GameObject>(); listTemp = list; foreach[...] tritt der Fehler auf. oder: public class Test : MonoBehaviour { public List<GameObject> list; List<GameObject> listTemp; void Start() { listTemp = list; foreach [...] Alle erzeugen den Fehler. Ich denke ich werde dann werde ich die erwähte for-schleife nehmen, die rückwärts durch meine Objekte geht. Danke euch.
  9. Hey Leute ich schon wieder, dieses mal habe ich Probleme mit einer meiner Listen. Ich habe eine Liste mit GameObjects, die am Ende des Levels zerstört werden sollen, damit das nächste Level geladen werden kann. (Die weiteren Level Befinden sich in der selben Scene, deswegen muss ich einmal aufräumen.^^ ) Dafür habe ich folgende Zeilen geschrieben: private void NextLevel() // Wird aufgerufen, um die Scene leer zu räumen { if (balls.Count > 0) // wird nur ausgeführt, wenn mindestens ein Ball auf dem Spielfeld ist { List<GameObject> ballsTemp = balls; // erstellt eine temporäre liste von balls foreach (GameObject ball in ballsTemp) // für jedes Objekt in der erstellten Liste { Ball b = ball.GetComponent<Ball>(); // hole dir das angehängte Script b.resetMultiplier(); // schreibt dem Spieler die Punkte gut, die der Ball noch hat. b.DestroyMe(1); // zerstört den Ball und löscht ihn aus der Liste "balls" } } } die Methode resetMultiplier() ist nicht von belang. hier aber noch die Methode DestroyMe() löscht lediglich den Ball aus der Liste balls, die ich zu beginn von NextLevel() kopiert habe. Es wird jedoch nur der erste Ball zerstört und danach bekomme ich folgenden Fehler: InvalidOperationException: Collection was modified; enumeration operation may not execute. System.ThrowHelper.ThrowInvalidOperationException (System.ExceptionResource resource) (at <eae584ce26bc40229c1b1aa476bfa589>:0) System.Collections.Generic.List`1+Enumerator[T].MoveNextRare () (at <eae584ce26bc40229c1b1aa476bfa589>:0) System.Collections.Generic.List`1+Enumerator[T].MoveNext () (at <eae584ce26bc40229c1b1aa476bfa589>:0) GameManager.NextLevel () (at Assets/Scripts/GameManager.cs:146) <-- Die oben erwähte foreach Schleife. GameManager.Update () (at Assets/Scripts/GameManager.cs:96) <-- Ruft NextLevel() auf Danke für eure Hilfe.
  10. Im Moment ist es noch der Grundstock des wissens, was jeder Informatiker lernt. Spieleprogramierung und Spielegrafik etc. kommen später dran. Jetzt ist es in erster Linie Algorithmen und Datenstrukturen, Mathe, und erste Einblicke in die Objektorrientierte Programmierung (Python und Java). Das ist das, was ich bisher im ersten Semester lerne.
  11. Okay, ist zwar etwas fummelig aber ich habe gerade den Edge Collider entdeckt... hat sich erledigt^^
  12. Hey Leute, ich möchte gerne meinen Schläger für mein pingpong Spiel mit einem Collider ausstatten, dessen oberfläche nicht gerade sein soll. Also der Spieler sieht ihn gerade aber der Ball soll, wenn er weiter rechts auftritt mehr nach rechts fliegen und links mehr nach... ehmm.. Achja, links... So hat der Spieler etwas mehr kontrolle über den Ball. Um diesen effekt zu erzielen, soll der Collider fast wie ein Halbfreis sein. Wie zerscheide ich einen Collider? So ungefähr soll es aussehen nur ohne den restlichen Kreis unten: Und falls ihr fragt: Capsule Collider sind mir noch zu flach...
  13. Übrigens kleine änderung bei mir, falls das hier jemals jemad liest : Ich habe mit einem Studium an der WBH im bereich Game Development begonnen. Bin jetzt seid ca 3 Monaten dabei. Also so ziemlich genau zwei Jahre nachdem ich mich hier im Forum vorgestellt habe. Mensch wie die Zeit vergeht... 🙃
  14. Problem ist leider noch ein anderes. Die Anzahl der Objekte ist nicht beliebig. Jede Farbe bekommt noch ein + und ein -. Damit nun jede Kombination von alles ist Minus über Rot ist + alles andere ist - bis hin zu alles ist +, muss ich leider zunächst Jede Kombination existieren und muss Binär berechnet werden. Eine stelle im binären mehr heißt um umkehrschluss die Anzahl der Objekte zu verdoppeln. Darum bin ich gezwungen eine Farbe mehr und 16 Objekte mehr zu nehmen. Aber ich bin gar nicht böse drum Mathematik kann trotzdem manchmal ein Arsch sein 😀
×
×
  • Create New...