Jump to content
Unity Insider Forum

Thariel

Members
  • Content Count

    454
  • Joined

  • Last visited

  • Days Won

    16

Thariel last won the day on November 2

Thariel had the most liked content!

Community Reputation

92 Excellent

About Thariel

  • Rank
    Advanced Member
  • Birthday 11/30/1988

Contact Methods

  • Website URL
    http://www.lost-in-nature.com

Profile Information

  • Gender
    Male
  • Location
    Bern
  • Interests
    Krafttraining, Spieleentwicklung, Studio Fotografie

Recent Profile Visitors

9,370 profile views
  1. Das ist nicht skalieren was du da machst Du erstellst lediglich ein neues kleineres Bild mit dem Ausschnitt eines grösseren. Schau dir mal Texture2D.Resize an, war aber mit dem Ergebnis nie wirklich zufrieden. Wenn du etwas recherchierst findest du auch viele Snippets die du nutzen kannst. Aber eigentlich brauchst du das Bild ja nicht zu skalieren, du kannst es einfach im Image kleiner darstellen und wenn du ein Aspect Ratio Fitter hinzufügst, hast du alles was du brauchst
  2. Warum skalieren? Weil du ein paar KB sparen willst? 😁 Ich speichere es einfach ab und stelle es verkleinert dar (Image). Dann geht das Speichern auch etwas schneller. Du kannst dir ja mal dieses Asset anschauen. Ist kostenlos und hab ich mir auch gerade geholt zum testen. Scheint nice zu sein. Kannst du auch extrem hochauflösende Screenshots machen (4K, 8K, ...). https://assetstore.unity.com/packages/tools/instant-screenshot-24122
  3. Achso, stimmt. Ich packe meine immer in den Streaming Assets Ordner, damit sie offen liegen
  4. Doch, aber das ist ein grosser Vorteil. So kann die Community selbst Übersetzungen erstellen und das Spiel wird so modifizierbar. Du kannst auch viel einfacher Fehler korrigieren ohne gleich das Spiel neu zu builden (wie @MaZy oben erwähnt hat).
  5. Nunja, im Endeffekt macht sein script nichts anderes als einfach linear Text auszugeben. Da kann ich auch einfach ein Textfile erstellen und abwechselnd in einem Fenster anzeigen. Mein System kann verschiedene Positionen im Gespräch zwischenspeichern, Optionen nach Bedingungen anzeigen und ein völlig freier Gesprächsverlauf ausgeben. Ist nur mühsam das File zu schreiben. Wenn du mal dem Gesprächsverlauf folgst, dann siehst du, dass es ein ganzer Dialog mit einer Quest ist, die man abschliessen kann. Genau so könnte es auch in einem RPG wie Gothic ablaufen. In den nächsten Tagen wird das Tema für mich sehr aktuell, sobald ich die NPC AI fertig habe. Dann werde ich schauen, wie ich es diesmal angehen werde. Die Herausforderung ist vor allem: Die Gespräche laufen nicht linear ab, sondern in Schlaufen mit verschiedenen "Levels". Das geht fast nur mit einem Node-Basiertem System. Aber ich brauche die Dialoge eigentlich nur für die Intro Sequenz, deshalb werde ich da was einfaches bauen. Es gibt auch Dialog Editore. Vielleicht findest du ja einen guten und man könnte das exportierte XML File einfach in Unity interpretieren
  6. Thariel

    Fight!

    Ob ein Angriff statt findet, weiss das Enemy erst, wenn Schaden ausgeteilt wird. Der Spieler könnte sich ja kurz vor dem Hit noch wegdrehen. Aber du könntest auch ein "Kampfmodus" machen: Der Spieler wechselt in den Kampfmodus mit [TAB] und kann mit Maustasten angreifen. Andere Tiere erkennen von weitem, dass eine Bedrohung auftaucht. Der Spieler (ist ja ein Tier), bewegt sich vielleicht anders und knurrt bisschen. Der Vorteil ist, dass der Spieler wieder den Kampfmodus verlassen kann und die Maustasten kannst du dann für andere Aktionen brauchen wie Sammeln, Buddeln, Looten etc...
  7. Thariel

    Fight!

    Ich mache das immer mit Raycasts. Wenn ein Angriff gestartet wird, starte ich ein Timer, der den Schadens-Raycast genau dann startet, wenn die Hit Animation ihren Höhepunkt hat. Ich sorge immer dafür, dass die Angriffs-Animationen (First Person) immer direkt durch die Mitte des Bildschirms (Fadenkreuz) gehen und auch der Raycast geht einfach von der Kamera richtung Vector3.forward. Die glaube die Collider-Idee ist etwas umständlicher. Da musst du auf viel mehr achten. Beim Raycast machst einfach eine simple, Zeit verzögerte abfrage. Ich hab dann ein Damage-Interface gemacht. Wenn der Hit Collider ein GetCompont<IDamage>() hat, einfach Damage austeilen. PS: Da hat Sascha recht, meistens wird da von Anfänger völlig übertrieben mit "Realismus". Der Spieler erwartet kein echter Realismus und wirklich realistische Spiele wären total Langweilig.
  8. Jetzt hab ichs raus gefunden! Type[] arguments = prop.GetValue(obj).GetType().GetGenericArguments(); Type keyType = arguments[0]; Type valueType = arguments[1]; Type dictType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); var dict = Activator.CreateInstance(dictType);
  9. Bei mir hat das immer funktioniert. Ich schätze mal, dass etwas in deinem Script oder so nicht funktioniert. Ich rate dir mal ein ganz neues Projekt zu erstellen und es einfach zu testen. Hilfreich wäre es, wenn du etwas mehr Infos gibst, zum Beispiel bisschen Code. Lädst du kurz vorher die Szene neu?
  10. Hi Ich entwickle gerade eine Klasse, um beliebige Objekte in XML und wieder zurück zu konvertieren. Ist alles ziemlich schwierig 😮 Jetzt versuche ich gerade, aus dem XML das Dictionary "stats" wiederherzustellen. <?xml version="1.0" encoding="utf-8"?> <XmlTest> <health>10</health> <speed>3.5</speed> <isDeath>false</isDeath> <stats> <!--Dictionary--> <row> <key>strength</key> <value>5</value> </row> <row> <key>armor</key> <value>0</value> </row> </stats> </XmlTest> Das XElement "stats" übergebe ich also meiner Funktion: public static void GetDictionaryFromXElement(XElement elDictionary, object obj, PropertyInfo prop) { var dict = (IDictionary)Activator.CreateInstance(prop.GetType()); foreach (XElement elRow in elDictionary.Elements()) { object key; if (dict.Keys.GetType() == typeof(int)) { string sValue = elRow.Element("key").Value; int i = 0; int.TryParse(sValue, out i); key = i; } else Debug.LogError("Variable type not handled: " + prop.PropertyType); /// hier ein teil ausgeschnitten um das script kürzer zu halten dict.Add(key, value); } prop.SetValue(obj, dict); } Jetzt habe ich das Problem, dass dict.Keys.GetType() nicht den typ des "Keys" zurück gibt, sondern "System.Collections.Generic.Dictionary`2[System.String,System.String]". Trotz Suche habe nicht nicht herausgefunden, wie ich das Dictionary füllen kann, ohne vorher den Datentyp zu kennen. Ich müsste einfach den Datentyp des "Key" und des "Value" Wertes wissen, damit ich das ganze abarbeiten kann. Wer kann mir da helfen?
  11. Hi Ich kenne mich mit ScriptableObjects nicht aus, aber ich habe ein einfaches Dialog System entwickelt. Dazu habe ich einfach ein LUA File (XML würde auch gehen) verwendet. Darin habe ich verschiedene "Stages" definiert. Jede stage enthält entweder Informationen, was der Npc sagt oder Auswahlmöglichkeiten, die der Spieler Antworten kann. Die Variable "nextStage" gibt an, welche Stage als nächstes kommt (wieder NPC sagt was oder Spieler antwortet was). Dazu habe ich noch eine "requirements" Variable bei den Antwortmöglichkeiten gemacht. Die Antwort erscheint also nur, wenn der Spieler die "requirements" erfüllt... zum Beispiel ein bestimmter Gegenstand im Inventar hat. Ist leider ziemlich kompliziert die Datei zu schreiben. Wenn du ein System entwickeln willst, um die Dialoge auf komfortable Art zu designen, wäre ich sehr interessiert 🙂 So sieht so eine Datei aus: defineDialog { id = "sailorfrank", name = "Frank", startStageId = "s0", autoStartRadius = 0, stages = { s0 = { say = { speaker = "npc", text = "Warum nur immer ich?", audio = "", actions = nil, nextStage = "s1" }, options = nil }, s1 = { say = nil, options = { option1 = { text = "Was ist los?", requirements = nil, actions = nil, nextStage = "s2" }, option2 = { text = "Ich muss weiter.", requirements = nil, actions = nil, nextStage = "" } } }, s2 = { say = { speaker = "npc", text = "Jemand hat meine Schuhe geklaut! Gestern hatte ich sie noch.", audio = "", actions = nil, nextStage = "s3" }, options = nil }, s3 = { say = { speaker = "npc", text = "Es sind ganz normale Schiffsstiefel.", audio = "", actions = nil, nextStage = "s4" }, options = nil }, s4 = { say = nil, options = { option1 = { text = "Wenn ich sie sehe, werde ich bescheid geben.", requirements = nil, actions = { SetStage = "s6" }, nextStage = "s5" }, option2 = { text = "Viel Glück!", requirements = nil, actions = nil, nextStage = "" } } }, s5 = { say = { speaker = "npc", text = "Das wäre super!", audio = "", actions = nil, nextStage = "" }, options = nil }, s6 = { say = nil, options = { option1 = { text = "Wegen deinen Stiefeln...", requirements = nil, actions = nil, nextStage = "s7" }, option2 = { text = "Ich gehe jetzt.", requirements = nil, actions = nil, nextStage = "" } } }, s7 = { say = { speaker = "npc", text = "Ja?", audio = "", actions = nil, nextStage = "s8" }, options = nil }, s8 = { say = nil, options = { option1 = { text = "Ich habe sie gefunden. Hier sind sie.", requirements = { InventoryContainsItem = "BOOTS=1" }, actions = nil, nextStage = "s10" }, option2 = { text = "Noch nichts neues.", requirements = { InventoryNotContainsItem = "BOOTS=1" }, actions = nil, nextStage = "s9" } } }, s9 = { say = { speaker = "npc", text = "Dann such weiter, ok?", audio = "", actions = nil, nextStage = "s6" }, options = nil }, s10 = { say = { speaker = "npc", text = "Das war echt nett von dir! Vielen Dank!", audio = "", actions = { SetStage = "s11" }, nextStage = "" }, options = nil }, s11 = { say = { speaker = "npc", text = "Hey! Danke nochmals, dass du meine Stiefel gefunden hast!", audio = "", actions = nil, nextStage = "" }, options = nil } } }
  12. Indem du die Ausgabe formatierst. Zum Beispiel so: string datum = dateTime.ToString("dd.MM.yyyy"); Da gibt es sehr viele Möglichkeiten.
  13. Thariel

    Iso Cammera.

    Ich würde es so machen: using UnityEngine; using System.Collections; public class CameraController : MonoBehaviour { public Transform player; public float speed = 5.0F; public Vector3 offset = new Vector3(0, 5, 0); void Update () { transform.position = Vector3.Lerp(transform.position, player.transform.position, speed * Time.deltaTime) + offset; } } Jetzt das Script auf die Kamera legen und den Player auf den Slot ziehen. Jetzt verfolgt die Kamera den Player in einer flüssigen Bewegung.
  14. Kannst du nicht das Datum als DateTime speichern und erst in ein string umwandeln, wenn das gefordert wird? Dies hat dann viele Vorteile. Falls das Datum nur als string vorliegt, würde ich beim einlesen die strings in DateTime umwandeln.
  15. Ich würde pro Gebiet ein GameObject (Spawner) erstellen und alle Npcs unterordnen (als childs). Dann immer bei Mitternacht (falls du Tag/Nacht Zyklus hast) der Spawnvorgang starten. Du kannst einfach im Spawner mit transform.childCount die aktuell vorhandenen Tiere zählen. //alle 300 sekunden spawnen float spawnTimer = 300; void Update() { if(spawnTimer > 0) { spawnTimer -= Time.deltaTime; if(spawnTimer <= 0) { Spawn(); spawnTimer = 300; } } } int desiredAnimalCount = 20; void Spawn() { int left = desiredAnimalCount-transform.childCount; for(int i=0;i<left;i++) { //Instantiate } } Du könntest auch anstatt tote Tiere zu Destroy'en, sie nur deaktivieren. Und wenn der Spawnvorgang läuft, suchst du für die deaktivierten Tiere ein neuer Spawnpoint und belebst sie wieder.
×
×
  • Create New...