• Announcements

    • Lars

      Allgemeine Forenregeln   03/13/2017

      Forenregeln Nimm dir bitte einen Moment um die nachfolgenden Regeln durchzulesen. Wenn du diese Regeln akzeptierst und die Registration fortsetzen willst, klick einfach auf den "Mit der Registrierung fortfahren"-Button. Um diese Registration abzubrechen, klick bitte einfach auf den "Zurück" Button deines Browsers. Wir garantieren nicht für die Richtigkeit, Vollständigkeit und Brauchbarkeit der Nachrichten und sind auch nicht dafür verantwortlich. Die Beiträge drücken die Meinung des Autors des Beitrags aus, nicht zwangsläufig das, wofür die Forensoftware steht. Jeder Nutzer, der denkt, dass ein veröffentlichter Beitrag unzulässig bzw. störend ist, ist aufgefordert uns unverzüglich per E-Mail zu kontaktieren. Wir haben das Recht störende Beiträge zu löschen und bemühen uns, das in einem realistischem Zeitraum zu erledigen (sofern wir beschlossen haben, dass die Löschung notwendig ist). Du akzeptierst, durchgehend während der Nutzung dieses Services, dass du dieses Forum nicht dazu missbrauchen wirst, Inhalte zu veröffentlichen, welche bewusst falsch und/oder verleumderisch, ungenau, beleidigend, vulgär, hasserfüllt, belästigend, obszön, sexuell belästigend, bedrohlich, die Privatsphäre einer Person verletzend oder in irgend einer Art und Weise das Gesetz verletzen. Des Weiteren akzeptierst du, dass du keine urheberrechtlich geschützte Inhalte ohne Erlaubnis des Besitzers in diesem Forum veröffentlichst. Mit dem Klick auf den "Mit der Registrierung fortfahren"-Button, akzeptierst du zudem unsere Datenschutzerklärung und stimmst der Speicherung deiner IP-Adresse und personenbezogenen Daten zu, die dafür benötigt werden, um dich im Falle einer rechtswidrigen Tat zurückverfolgen zu können bzw. permanent oder temporär aus dem Forum ausschließen zu können. Es besteht keine Pflicht zur Abgabe der Einwilligung, dies erfolgt alles auf freiwilliger Basis.   Zusatzinformationen Der Forenbetreiber hat das Recht, Nutzer ohne Angabe von Gründen permanent aus dem Forum auszuschließen. Des Weiteren hat er das Recht, Beiträge, Dateianhänge, Umfrage, Blogeinträge, Galleriebilder oder Signaturen ohne Angabe von Gründen zu entfernen. Mit der Registrierung verzichtest du auf alle Rechte an den von dir erstellten Inhalten, bzw. treten diese an das Unity-Insider.de und Unity-Community.de ab. Dies bedeutet im Klartext, dass das Unity-Insider.de und Unity-Community.de frei über deine Texte verfügen kann, sofern diese nicht wiederum die Rechte anderer verletzen. Es besteht weiterhin kein Anspruch von registrierten Nutzern bzw. ehemaligen registrierten Nutzern darauf, dass erstellte Inhalte und/oder die Mitgliedschaft (User) wieder gelöscht werden (Erhaltung der Konsistenz dieses Forums).   Einwilligungserklärung Wenn du mit der Speicherung deiner personenbezogenen Daten sowie den vorstehenden Regeln und Bestimmungen einverstanden bist, kannst du mit einem Klick auf den Mit der Registrierung fortfahren-Button unten fortfahren. Ansonsten drücke bitte Zurück. Stand: 07.03.2011

Sascha

Administrators
  • Content count

    9,939
  • Joined

  • Last visited

  • Days Won

    397

Sascha last won the day on June 4

Sascha had the most liked content!

Community Reputation

1,951 Excellent

About Sascha

  • Rank
    Community Manager
  • Birthday 08/13/1990

Contact Methods

  • Website URL
    http://www.indiepowered.net

Profile Information

  • Gender
    Male
  • Location
    Hamburg
  • Interests
    Programmierung

Recent Profile Visitors

25,422 profile views
  1. Ach Quatsch, kann doch nicht jeder alles wissen php ist dafür da, mit HTTP angesprochen zu werden. Das ist das Protokoll, das dein Browser benutzt. Man schickt eine Anfrage hin und kriegt eine Antwort zurück. Diese Antwort kann z.B. HTML-Code sein, also eine Webseite, die angezeigt wird. Wenn dann in dem Code was von einem Bild steht, schickt der Browser gleich noch eine HTTP-Anfrage los und dieses Mal ist die Antwort die Bilddatei. Jedes Mal, wenn dein Browser etwas lädt, ist es mindestens eine HTTP-Abfrage. Du kannst aber auch ziemlich stumpfen plain text in einer HTTP-Antwort haben, oder XML, oder JSON, oder oder... Wenn dich das interessiert, kannst du dir mal Fiddler besorgen. Das zeigt dir systemweit alle HTTP-Anfragen und deren Antworten an. Da sieht man ganz gut, wie viel HTTP dein System den ganzen Tag spricht. In jedem Fall hat Unity dir für HTTP etwas bereit gelegt. Die klassische Variante ist die WWW-Klasse. Sie soll bald von UnityWebRequest abgelöst werden, ist aber noch nicht so weit. Du kannst also beruhigt WWW benutzen. Die Klasse funktioniert jedenfalls asynchron. Sie blockiert also nicht deinen Main Thread, was bedeutet: Das Spiel bleibt nicht stehen solange der HTTP-Verkehr läuft. Das ist auch gut so . Es bedeutet allerdings auch, dass du nicht einfach sagen kannst: var ergebnis = MachHTTP(); MachWasMit(ergebnis); Weil "MachHTTP" (heißt natürlich anders) nur ein Startschuss ist, und das Ergebnis erst später da ist, der Code aber weiterläuft. Eben damit dein Spiel nicht blockiert wird. Die übliche Lösung für das Problemchen ist, WWW in einer Coroutine zu benutzen. Ich weiß nicht, ob du Coroutines im Blick hast, aber ganz kurzgefasst: Eine Coroutine ist eine Methode, die unterbrochen und später weiter ausgeführt werden kann. Im Unity-Kontext kann eine Coroutine eine beliebige Anzahl von Frames warten. Zum Beispiel, bis ein WWW-Objekt fertig geworden ist. Der anschließende Code kann dann mit dem Ergebnis arbeiten. Coroutinen definiert und benutzt man so: void Start() // Oder irgendeine andere Methode { StartCoroutine(NameDerCoroutine()); } private IEnumerator NameDerCoroutine() { Debug.Log("Geht los."); yield return new WaitForSeconds(3); Debug.Log("Ist fertig."); } Kannst du so direkt testen. Um IEnumerator benutzen zu können, muss oben "System.Collections" in den using-Statements stehen. Deswegen steht das da übrigens auch standardmäßig in einem neuen Script. "yield return" ist hier das wichtige Keyword. Ein WaitForSeconds-Objekt wartet x Sekunden (offensichtlich), aber es gibt noch einiges andere, was da hin kommen kann. Z.B. bedeutet yield return null; dass genau einen Frame gewartet wird. Jetzt zu WWW. Das benutzt man so: public string url = "https://forum.unity-community.de/uploads/profile/photo-thumb-5586.jpg"; // Kerugals profile pic void Start() // Oder irgendeine andere Methode { StartCoroutine(DownloadTexture(url)); } private IEnumerator DownloadTexture(string url) { var www = new WWW(url); yield return www; // Wait for download if(string.IsNullOrEmpty(www.error)) { Debug.Log("Download successful."); renderer.material.mainTexture = www.texture; } else { Debug.LogError("Download Error: " + www.error); } } Wenn du keine WWWForm in dein WWW-Objekt packst, macht Unity eine sog. GET-Anfrage. Die schickt eine URL, die evtl Parameter enthält, und kriegt irgendetwas zurück. Das wird dann runtergeladen (in diesem Fall ein Bild) und du kannst damit machen, was du willst. Mit WWWForm erstellst du eine POST-Anfrage. Eine solche Anfrage ist dafür da, dem Server etwas mitzuteilen, statt etwas zu erfragen. Wann immer du hier im Forum einen Beitrag abschickst, ist das eine POST-Anfrage. Die Daten, die du abschickst (z.B. dein Beitragsinhalt), sind in der Abfage im POST-Dictionary enthalten. Auch das kann man übrigens mit Fiddler sehen. Dieses Dictionary, also diese Liste von "dies = das", so wie "beitrags-text = hallo leute, ...", wird von WWWForm gehandelt. Das funktioniert so: public string url = "link-zu-deinem-php-script"; // Kerugals profile pic public string player = "Hannes"; public int score = 10; void Start() // Oder irgendeine andere Methode { StartCoroutine(PostScore()); } private IEnumerator PostScore() // Dieses mal ohne Parameter, geht auch { var post = new WWWForm(); post.AddField("Player", player); post.AddField("Score", score + ""); var www = new WWW(url); yield return www; if(string.IsNullOrEmpty(www.error)) { Debug.Log("Posting successful."); Debug.Log(www.text); // Mal testweise die Antwort vom Server anzeigen } else { Debug.LogError("Posting Error: " + www.error); } } Dein php-Script auf dem Server muss jetzt die POST-Daten auslesen. Das geht so: <? $name = $_POST['Player']; $score = $_POST['Score']; // Nur mal testweise ausgeben echo $name.' hat '.$score.' Punkte.'; ?> Statt des echo musst du jetzt die Punkte in die Datenbank eintragen. Das führt hier natürlich zu weit, aber ich empfehle dieses Tutorial. PDO ist ganz gut zu lernen. Wenn das alles erstmal läuft, musst du dir noch Gedanken um die Sicherheit machen. Wenn du Fiddler tatsächlich mal ausprobierst wirst du merken, dass man damit auch selber HTTP-Anfragen machen kann. Dann baue ich mir fix eine Anfrage mit sehr vielen Punkten und nichts hindert mich daran. Hier kann man sich mal Hashing angucken, aber dazu kommen wir dann, wenn es soweit ist
  2. Projektile, die mit Rigidbodys modelliert sind, sind in meinen Augen nur dann sinnvoll, wenn sie beim Aufprall explodieren. Entweder das, oder das weggeschoben werden ist so gewollt. Bei allem darüber hinaus fängt es an, unsinnvoll zu werden, Rigidbodys zu benutzen.
  3. Liegt der Code auf dem Server? Wenn nein, ist da schonmal der Fehler. Man sollte niemals direkt von irgendwo eine Datenbankverbindung aufbauen. Stattdessen immer eine Schicht dazwischen packen. Darf mit einem kleinen php-Skript losgehen, das dafür sorgt, dass nur gültige Abfragen durchkommen. Auch wenn sich das Konnektivitätsproblem vielleicht lösen lässt, holst du dir mit einer direkten Verbindung vom Ccient zur Online-Datenbank nur Probleme ins Haus. Sobald du auf HTTP-Anfragen an deine Web-API umgestellt hast, werden sich die Probleme von alleine lösen.
  4. Eine 300 kilo schwere Glasscherbe? Denke daran, dass schwerere Objekte nicht schneller fallen. Transform.Translate ist, besonders mit Space.Self, keine gute Idee. Wenn sich eine Scherbe dreht, fleigt sie plötzlich nach oben? Und selbst mit Space.World hast du eine erhöhte Geschwindigkeit, aber realistisch wäre eine erhöhte Beschleunigung. Nimm lieber Rigidbody.AddForce. Nicht 29 Mal dasselbe Script auf lauter Objekte desselben Systems zu legen, ist aber eine gute Idee. Du kannst dir die Rigidbodys raussuchen und zentralisiert mit einer Schleife bei jedem davon AddForce aufrufen. Übrigens änderst du mit deinem Code den Prefab und nicht die Instanz: Instantiate(glasBruchObjekt, transform.position, transform.rotation); glasBruchObjekt.localScale = transform.localScale; Richtig wäre: var instance = Instantiate(glasBruchObjekt, transform.position, transform.rotation); instance.localScale = transform.localScale; Und dann im Anschluss kannst du machen: shards = instance.GetComponentsInChildren<Rigidbody>(); shards ist ein Array von Rigidbodys, das du außerhalb von Update definieren musst: private Rigidbody[] shards; Dann kannst du in FixedUpdate AddForce bei allen aufrufen: foreach(var shard in shards) { shard.AddForce(Vector3.down * extraGravity); } Jetzt ist aber noch eine Sache, die du machen solltest: Irgendwann aufhören. Die realistischste Lösung wäre, bei jedem Rigidbody regelmäßig zu checken, ob er "eingeschlafen" ist. Diesen Zustand hat er, wenn er liegengeblieben ist und sich nciht mehr bewegt. Die Methode, die dir das sagt, heißt Rigidbody.IsSleeping. Wenn der Rigidbody nun schläft, könntest du ihn löschen, damit er nicht mehr weiter Leistung frisst. Du musst dann natürlich auch aufhören zu versuchen, AddForce bei ihm aufzurufen. Sag bescheid, wenn du dabei Hilfe brauchst.
  5. Kleiner Zusatz zum Zerbrechen: Es gibt einige Möglichkeiten, die kleinen Glassplitter automatisiert zu erzeugen. Das macht man in der Regel vorher, also nicht direkt ingame, und tauscht dann zur Laufzeit die Scheibe mit den bereits kalkulierten Bruchstücken aus. Einige Pakete machen das auch zur Laufzeit, aber du musst für dich entscheiden, ob du das wirklich brauchst. Das Stichwort hier heißt in jedem Fall "Mesh Fracturing".
  6. Kurze Antwort: Ja, kann man vererben. Unity schaut per Reflection nach der Methode. Das heißt stumpf gesagt, dass in der Komponente, unabhängig davon, wovon sie erben, nach einer Methode mit einem bestimmten Namen gesucht wird. Vererbte Methoden können dabei auch gefunden werden.
  7. Das sind echt viel zu wenige Infos. Wie hast du den Nebel implementiert?
  8. Blau = Instanz eines Prefabs Rot = Instanz eines Prefabs, aber das Prefab wurde nicht gefunden (vermutlich gelöscht) Grau = keine Verbindung zu einem Prefab
  9. Deine Vorstellung klingt ganz richtig. Jede Komponente ist auch ein Objekt, genau wie jedes GameObject ein Objekt ist. Das, was du mit "eigenes Teleporterscript" meinst, ist also ein Objekt wie alles andere auch. Man könnte es auch "Instanz" der Scriptklasse nennen. Jedes Objekt hat nun seinen eigenen Zustand. Damit gemeint ist die Menge aller Werte, die das Objekt für die Variablen seiner Klasse hat. Bei der Light-Komponente ist die Eigenschaft "Color" eine dieser Variablen, und jede Light-Komponente hat dafür ihren eigenen Wert. Sonst würden ja alle Lichter mit derselben Farbe leuchten. Das Keyword "static" ist es, das diese Objektgebundenheit aufhebt. Statische Variablen gibt es pro Klasse nur einmal, und für alle Instanzen gilt derselbe Wert.
  10. Alles klar! Ich konnte nicht so ganz einschätzen, wie viel auf einmal ich dir entgegen schmeißen kann. Du definierst erst dein enum direkt in der Klasse: { // Öffnende Klammer der Klasse public enum Team { Friendly, Enemy } public Team team; // Anstatt "public int team;" // Dann die ganzen anderen Variablen und die Methoden Jetzt hast du im Editor eine Auswahlbox zwischen den beiden Begriffen im enum-Block. Der Rest des Codes kann so bleiben, da ja nur mit != geprüft wird, und Team.Friendly ist ungleich Team.Enemy. Erweitern geht sehr einfach, indem du mehr Begriffe in die Liste packst: public enum Team { GDI, Nod, Scrin }
  11. Du gibst deinem Script entsprechende Variablen: public int lives = 20; public int damage = 5; public int team; Die Werte, die da stehen, sind nur Defaultwerte. Sobald das Script kompiliert und auf ein GameObject gezogen ist, kannst du die Werte für dieses GameObject frei einstellen. Man beachte auch die team-Variable, die die Tags für dich ersetzt. Trage da einfach auf den GameObjects 0 für friendly ein und 1 für enemy. Wenn du irgendwann ein drittes Team hast, einfach eine 2 einsetzen. Dann brauchst du in deinem Code nur noch var otherFighter = collision.gameObject.GetComponent<NameDesScripts>(); if(otherFighter) // Nur wenn wir auch einen Kämpfer gefunden haben, also ein GO mit diesem Script { if(otherFighter.team != team) { lives -= otherFighter.damage; if(lives <= 0) { Die(); } } } Bemerke, wie viel kompakter und weniger fehleranfällig die if-Abfrage jetzt ist. Man kann das mit dem Team auch über ein enum regeln, dann trägt man das nicht über so eine abstrakte Zahl ein. Wenn das hier erstmal sitzt, sag bescheid, wenn dich das interessiert.
  12. Im Zweifelsfall unten rechts bei den kleinen Bildchen.
  13. Mal ne ganz blöde Frage. Hast du irgendwelche Programme laufen, die am Grafikkartentreiber rumpfuschen? NVidia ShadowPlay z.B.? Die machen gerne mal Ärger bei sowas.
  14. Man kann auch die Suppe mit einer Gabel essen. Nicht schön aber möglich.
  15. Gar nicht. Unity ist kein 3D-Modelling-Programm und entsprechend überhaupt nicht dafür geeignet, Modelle zu texturieren. Das musst du in Blender machen, oder in irgendeinem anderen Modellingprogramm.