Jump to content
Unity Insider Forum
  • 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

Leaderboard


Popular Content

Showing most liked content since 01/18/2018 in all areas

  1. 3 points
    Es gibt jede menge Neuigkeiten! Leider hab ich es ein bisschen versäumt, mich hier öfter zu melden, aber dafür gibt's zumindest viele neue Dinge auf einmal zu sehen. Es folgen zahlreiche Bilder ... Der Hai Charakter ist inzwischen fertig modelliert, geriggt und einsatzbereit. Ihr könnt mir sogar zuschauen wie ich ihn zusammenbaue Es wurde mit Dialogboxen experimentiert: Neue Level Typen wurden ausprobiert: Einige Grafiken wurden überarbeitet. Vor allem das Piraten Tileset musste in neues Licht gerückt werden (im wahrsten Sinne), weil es doch sehr eintönig und schwer vom Hintergrund zu unterscheiden war. Ein neuer (alter) Charakter (Finn) wurde modelliert und ein paar ältere wurden aktualisiert. Der Level Editor hat ein großes Update bekommen. Baumenüs mit einer erquicklichen Auswahl an Tiles und verschiedener Skins. Außerdem wurde ein "Easy Build Mod" eingebaut, welcher alle Tiles als einfache Blöcke darstellt: Hier wird nochmal ausführlicher über die einzelnen Themen berichtet: Hai, Dialog, Levels: https://polywonk.wordpress.com/2017/09/27/a-little-bit-of-everything/ Grafik update, Leveleditor: https://polywonk.wordpress.com/2018/02/16/weihnachten-silvester-und-2018/
  2. 2 points
    Bin aktuell immer noch dabei einen Grashader zu schreiben. Im Zuge dessen bin ich nun so ziemlich alle Lösungen durchgegangen, wie man Grasdetails performant rendern kann: einzelner Mesh (Performance miserablel) kombinierter statischer Mesh (Performance überraschend schlecht) instanced Mesh (Performance geht so, aber man kann nur 1024 Meshes in einem Zug rendern) instanced indirect Mesh (Performance bislang die Beste / derzeit verfolgte Lösung) Geometry Shader Mesh (Performance leicht schlechter als instanced indirect) Zusätzlich zum Grasshader (instanced indirect) wird ein Compute-Shader verwendet, der berechnet, wo die Positionen die Grasdetails sind und "blendet" diese entsprechend aus, wenn sie nicht im Frustum der Kamera liegen. Der Render-Shader bekommt dann nur die Instanzen die der Compute-Shader ausgibt. Dabei hatte der Compute-Shader mir eine Menge Probleme bereitet.... Zum einen kann er nur exakt vordefinierte Happen verarbeiten, zum anderen verhaut man sich die gute Performance, wenn man bestimmte Dinge macht und nicht höllisch aufpasst (wie das Auslesen der zurückgegebenen Werte eines Buffers). Vermutlich wird hier C#-Code anders compiliert, wenn man bestimmte Zugriffe tätigt. Hier nun das Ergebnis. Man sieht wie die Grasdetails im Bereich außerhalb des Kamera-Frustum ausgeblendet werden: Video: https://streamable.com/lki7f
  3. 2 points
    Grashader die 2.: Ich habe keinen funktionierenden "Translucent Shader" für Unity gefunden. Ich hatte zwar gedacht das Lux-Shader-Team hätte einen entwickelt, aber der hat bei meinem Gras den Dienst verweigert, zudem kommt er mit etlichen Include-Files (nicht schön wenn man nur einen Shader haben möchte). Also wieder die brauchbaren Teile des Lux-shaders übernommen (Double Sided) und mit der Lightning-Funktion des "Unity Tree Leaf"-Shaders verbunden (dieser funktioniert mit einem normalem Mesh nur bedingt und ist auch nicht doppelseitig, Ursache unbekannt). Folgendes Ergebnis soweit: - Unity Surfaceshader (PBS) - Transluzentes Licht (Translucent Shader mit einigen Einstellmöglichkeiten) - animiert sich selbst ohne Windzone (keine Vertexfarben notwendig) - gängig mit einem beliebigen Mesh (muss kein Billboard sein) Video (Translucent Effect): https://streamable.com/j721g https://streamable.com/8inb9 Noch offen: - instanziierbarer Shader
  4. 2 points
    Namespaces sind dann sinnvoll, wenn du Pakete hast. Ich habe mir ein paar Sachen entwickelt, die ich in verschiedenen Projekten verwende. Wenn ich die importiere, will ich die nicht im Default-Namespace haben. Wenn deine Klasse einfach nur zum Projekt gehört, ist der Default-Namespace völlig ausreichend. Bis du den Punkt erreichst, dass deine Systeme so groß und komplex sind, dass du sie aufteilen willst. Zur zweiten: Kommt auf die Situation an. Für den richtigen Kontext die richtige Lösung.
  5. 2 points
    Testlauf mit einem Grasshader der nun endlich ohne Windzone und ohne Unityterrain funktioniert. Ich habe diesen Shader aus Teilen des Unity "Tree Creator Leaves" Shader und dem "Grass Billboard" Shader zusammengesetzt. Normal sollte er daher auch ein Translucent Shader sein, aber schwer zu sagen, ob ein wahrnehmbarer Effekt erreicht wird. Ich möchte diesen Shader nun weiter umarbeiten, damit er instanziiert werden kann und ich ihn dann massenhaft auf einem Mesh einsetzen kann. Das Mühsame dabei war, daß nirgend irgendwelche Informationen zu den Parameters dieser Shader zu bekommen sind. Zudem musste ich den Shader umschreiben, damit er ohne Vertexfarben klarkommt. Video: https://streamable.com/ulptf
  6. 2 points
    Seit dem @Zer0Cool hier im Forum herumgeistert kommt man nie dazu Themen zu beantworten, weil er immer schneller ist
  7. 2 points
    Seit gestern ist mein vierter Flipper der "Sheriff" draußen. Der ist schwer! Ich habe es selber noch nicht geschafft, alle Missionen am stück zu schaffen. Ich war aber wirklich ganz kurz davor! Wie immer alles selber gemacht, von den Modellen zu den Texturen, Sound, Musik und Animationen. Momentan gibt es 10% Rabatt auf den Tisch und 30% Rabatt wenn man alle 3 Tische zusammen kauft. Es ist aber auch kaufbar, wenn man schon einen Flipper gekauft hatte, Es werden nur die neuen Flipper berechnet. Die Rabatte werden aber addiert, somit bekommt man 40% auf den Sheriff! Dieses Bundle ist aber leider nur zu sehen, wenn man auf eins der DLC's klickt oder danach sucht, was MalzbieGames alles gemacht hat. Hier ein Bild vom Tisch:
  8. 2 points
    Hallo zusammen, da von Kojote mal eine Anfrage zu diesem Thema kam: und das Ganze programmiertechnisch nicht ohne ist, habe ich mich einmal hingesetzt und eine Klasse geschrieben, die die Settings des Unity-Launcher aus der Windows-Registry sowohl ausliest als auch schreibt. Das Ganze kann man nun mit dem eigenen Qualitysettings-Dialog in seinem eigenen Spiel verknüpfen. Ich hoffe die Methode sind soweit selbsterklärend. Die Klasse funktioniert aktuell nur unter Windows. Der Vollbildmodus wird ausgelesen und gesetzt, kann aber aktuell über die Demo-UI noch nicht gesetzt werden (vielleicht ergänze ich das nochspäter). Die Klasse ist auch noch ungetestet, es kann also noch zu Fehlern kommen. Companyname und Productname müssen dem Skript übergeben werden (siehe Projektsettings -> Player). using System.Collections; using System.Collections.Generic; using UnityEngine; using Microsoft.Win32; using System.Reflection; // Klasse zum Auslesen und Schreiben der "Launcher Settings Configuration" aus der Windows-Registry. // Plattform: Windows // (c) by Zer0Cool for the Unity Insider Forum (forum.unity-community.de) // Skype: zer0f0rce public class LauncherSettings : MonoBehaviour { /* Muster für ein Registryeintrag: [HKEY_CURRENT_USER\Software\Firmenname\Gamename] "UnitySelectMonitor_h17969598"=dword:00000000 "Screenmanager Resolution Width_h182942802"=dword:00000780 "Screenmanager Resolution Height_h2627697771"=dword:00000438 "Screenmanager Is Fullscreen mode_h3981298716"=dword:00000001 "unity.player_sessionid_h1351336811"=hex:36,33,36,39,36,31,38,34,33,34,31,31,38,32,31,37,32,37,31,00 "unity.player_session_elapsed_time_h192694777"=hex:33,30,39,32,00 "unity.player_session_background_time_h123860221"=hex:31,35,31,37,32,34,38,37,30,31,32,38,33,00 "UnityGraphicsQuality_h1669003810"=dword:00000005 */ public string CompanyName = "HuginMuninStudios"; public string ProductName = "TwinDestiny"; const string userRoot = "HKEY_CURRENT_USER"; private bool m_currentIsFullscreenMode = true; private int m_currentQualityLevel; private Vector2 m_currentResolution; private string subkey; private string keyName; private string KeyNamePartScreenmanagerIsFullscreenMode = "Screenmanager Is Fullscreen mode"; private string KeyNamePartScreenmanagerResolutionWidth = "Screenmanager Resolution Width"; private string KeyNamePartScreenmanagerResolutionHeight = "Screenmanager Resolution Height"; private string KeyNamePartUnityGraphicsQuality = "UnityGraphicsQuality"; private string KeyNameScreenmanagerIsFullscreenMode; private string KeyNameScreenmanagerResolutionWidth; private string KeyNameScreenmanagerResolutionHeight; private string KeyNameUnityGraphicsQuality; private bool registryLoadingSuccessfully = false; void Start() { //subkey = "Software\\AppDataLow\\Software\\" + CompanyName + "\\" + ProductName; subkey = "Software\\" + CompanyName + "\\" + ProductName; keyName = userRoot + "\\" + subkey; if (FindRegistryKeyNames()) { registryLoadingSuccessfully = true; GetWindowsRegistry(); } else { registryLoadingSuccessfully = false; } } void OnGUI() { if (!registryLoadingSuccessfully) { GUILayout.BeginVertical(); GUILayout.Label("Registrydaten der Anwendung konnten nicht geladen werden. Bitte \"CompanyName\" und \"ProductName\" überprüfen oder Build der Anwendung 1x starten!"); GUILayout.EndVertical(); return; } string[] names = QualitySettings.names; GUILayout.BeginHorizontal(); // Zeige alle Qualitätsstufen an GUILayout.BeginVertical(); int i = 0; while (i < names.Length) { // Markiere aktuelle Auswahl des Launchers if (m_currentQualityLevel == i) { GUILayout.BeginHorizontal(); GUILayout.Label(">"); } // Zeige alle Auflösungen an if (GUILayout.Button(names[i])) { QualitySettings.SetQualityLevel(i, true); m_currentQualityLevel = i; SetWindowsRegistry(); print("Current Quality Level: " + i); } // Markiere aktuelle Auswahl des Launchers if (m_currentQualityLevel == i) { GUILayout.EndHorizontal(); } i++; } GUILayout.EndVertical(); // Zeige alle Auflösungen an GUILayout.BeginVertical(); Resolution[] resolutions = Screen.resolutions; Resolution lastResolution = new Resolution(); foreach (Resolution res in resolutions) { if (lastResolution.width == res.width && lastResolution.height == res.height) continue; // Markiere aktuelle Auswahl des Launchers if (m_currentResolution.x == res.width && m_currentResolution.y == res.height) { GUILayout.BeginHorizontal(); GUILayout.Label(">"); } if (GUILayout.Button(res.width + "x" + res.height)) { Screen.SetResolution(res.width, res.height, true); m_currentResolution.x = res.width; m_currentResolution.y = res.height; SetWindowsRegistry(); print("Current Resolution: " + m_currentResolution); } if (m_currentResolution.x == res.width && m_currentResolution.y == res.height) { GUILayout.EndHorizontal(); } lastResolution = res; // Speichere letzte Auflösung um doppelte Auflösungen zu überspringen } GUILayout.EndVertical(); // Togglebutton für Vollbild oder Fenstermodus bool priorIsFullscreenMode = m_currentIsFullscreenMode; m_currentIsFullscreenMode = GUILayout.Toggle(m_currentIsFullscreenMode, "Full Screen?"); if (priorIsFullscreenMode != m_currentIsFullscreenMode) { Screen.fullScreen = m_currentIsFullscreenMode; SetWindowsRegistry(); } GUILayout.EndHorizontal(); } bool FindRegistryKeyNames() { RegistryKey OurKey = Registry.CurrentUser; OurKey = OurKey.OpenSubKey(subkey, true); if (OurKey == null || OurKey.GetValueNames().Length == 0) { Debug.LogWarning("Programmschlüssel konnten nicht gefunden werden!"); return false; } foreach (string Keyname in OurKey.GetValueNames()) { if (Keyname.Contains(KeyNamePartScreenmanagerResolutionWidth)) KeyNameScreenmanagerResolutionWidth = Keyname; if (Keyname.Contains(KeyNamePartScreenmanagerResolutionHeight)) KeyNameScreenmanagerResolutionHeight = Keyname; if (Keyname.Contains(KeyNamePartUnityGraphicsQuality)) KeyNameUnityGraphicsQuality = Keyname; if (Keyname.Contains(KeyNamePartScreenmanagerIsFullscreenMode)) KeyNameScreenmanagerIsFullscreenMode = Keyname; } return true; } void SetWindowsRegistry() { // Write Settings Registry.SetValue(keyName, KeyNameScreenmanagerIsFullscreenMode, unchecked((int)(m_currentIsFullscreenMode?1:0)), RegistryValueKind.DWord); Registry.SetValue(keyName, KeyNameUnityGraphicsQuality, unchecked((int)m_currentQualityLevel), RegistryValueKind.DWord); Registry.SetValue(keyName, KeyNameScreenmanagerResolutionWidth, unchecked((int)m_currentResolution.x), RegistryValueKind.DWord); Registry.SetValue(keyName, KeyNameScreenmanagerResolutionHeight, unchecked((int)m_currentResolution.y), RegistryValueKind.DWord); } void GetWindowsRegistry() { // Read Settings int isFullscreenMode = (int)Registry.GetValue(keyName, KeyNameScreenmanagerIsFullscreenMode, null); m_currentIsFullscreenMode = (isFullscreenMode == 1) ? true : false; m_currentQualityLevel = (int)Registry.GetValue(keyName, KeyNameUnityGraphicsQuality, null); int currentResolutionX = (int)Registry.GetValue(keyName, KeyNameScreenmanagerResolutionWidth, null); m_currentResolution.x = (float)currentResolutionX; int currentResolutionY = (int)Registry.GetValue(keyName, KeyNameScreenmanagerResolutionHeight, null); m_currentResolution.y = (float)currentResolutionY; } }
  9. 2 points
    Leute! Ich glaube ich habe das Problem gefunden und beseitigt. ^^ Aber erstmal will ich euch erzählen wie ich darauf gekommen bin. Vor einigen Tagen hat mein Sohnemann auf seiner Kiste die Flipper gespielt und er kam dann an und sagte mir, dass auch er das Problem mit dem Controller im Menü habe. Jetzt endlich konnte ich mir das mal anschauen und habe festgestellt, dass das Gamepad an sich geht, aber irgendwie die Signale nicht verarbeitet werden konnten. Wenn man nämlich den linke Joystick bewegt, sieht man im Menü, dass der oberste Button aktiv wird, er also auch Signale bekommt ( Ich frage da lediglich die 2 Achsen ab). Man konnte aber nicht navigieren. Treiber war so wie er sein sollte. Und als wir den Controller mal getrennt und wieder angeschlossen hatten, ging er. Genau wie bei den Meisten die so ein Problem hatten. Mich hat aber gewundert, dass mein Sohn von Steam das BigPicture als Meldung sieht, wenn das Spiel gestartet wird. Also diese Meldung wo steht, dass man mit Shift - Tab das Steamoverlay öffnen kann. Wir sind davon ausgegangen, dass das davon kommt, weil er mal versucht hat mit nem XBox Controller das BigScreen System zu steuern. Nach nem Neustart war das Problem dann wieder da. Ich selber habe bei Steam 2 Profile. Eines, mit dem ich Spiele und ein Developerprofil. Bei mir war ja alles gut, wenn ich mit dem Spiele Profil den Flipper gestartet habe. Mit dem Developer hatte ich das scheinbar nie getestet. Bis gestern! Dort war das Problem plötzlich auch da! Selber Rechner, selbe Dateien, nur andere Anmeldung bei Steam. Somit war schon fast klar, dass es am Steam liegen muss. Nur was? Ich habe allen Scheiß verglichen, konnte aber nichts finden. Lediglich, wenn man das Spiel startet, dann gleich wieder beendet und dann wieder neu startet, ging's plötzlich. Aber immer wenn der Controller im Spiel komplett funktioniert hatte, machte BigScreen blöd, denn dann konnte man nicht mehr mit der Maus steuen. Da habe ich erst mal ne Runde gegoogled. Aber nichts gefunden. Ja und dann bin ich aufs Frontend von Steam gegangen und habe geschaut ob es am Build liegen könnte. Ob es irgendeine Einstellung gibt, die Probleme mit dem Controller machen könnte. Und da war es! Auf einer Seite, wo man sachen für den STEAM Controller einstellen kann, gab es folgende Rubrik: Unter diesem Text waren 3 Felder zum anhaken. Einmal für PS4, einmal für XBox und einmal für irgendwas anderes. XBox war angehakt. Ich habe den Haken entfernt, das alles gespeichert, Steam neu gestartet und BÄM! Fehler ist weg!!! Bei meinem DeveloperProfil wie bei meinem Sohn. Jungs! Wenn ihr Controller Probleme hattet, dann testet es bitte mal aus. Es wäre echt genial, wenn's bei allen funktioniert. Übrigens. Das BigPictureLogo ging damitauch weg. Alles ist wieder so wie es sein soll!
  10. 2 points
    Ich würde Property's verwenden, wenn ich sie brauche. Beispielsweise, wenn ein Wert nur gelesen werden darf -> Property. Wenn ich innerhalb der Property eine Validierung machen muss , beispielsweise Property Health und wenn Health hier nicht größer wie 100 werden darf -> Property. Ansonsten finde ich reichen normale Felder, man muss nicht alles verkomplizieren mit dem Grund "guter Programmierstil". Mich "nerven" Property's auch relativ oft, weil man hier keine direkte Zuweisung vornehmen kann bei einer untergeordneten Eigenschaft (siehe rotation Eigenschaft beim Transform).
  11. 2 points
    Neues Unity Techdemo. Ich muss wohl bei meinem Terrain ein paar Schippen nachlegen xD
  12. 2 points
    Also hier eine sehr billige Lösung, ist aber noch lange kein Decal-System. Du kannst hier ein Unity-Quad als Decalprefab verwenden. Allerdings wenn das Decal an einer Kante anliegt, gibt es wieder Probleme, da das Decal dann bei der Kante übersteht. Für ein ausgefeiltes System müsste man das Quad des Decals prozedural erzeugen und alle 4 Punkte des Quads an die Oberfläche anpassen. Dabei werden zusätzlich 4 weitere Rays ausgesendet und überprüft, ob das Decal noch auf der Oberfläche liegt. Hier wird es dann komplizierter. Ich denke man kann das Decal dann entweder abschneiden oder anhand der Oberfläche "umklappen". Wenn das Decal sehr klein ist, kann man das Decal auch einfach verschieben, so daß es noch auf der Oberfläche liegt und nicht übersteht. using System.Collections; using System.Collections.Generic; using UnityEngine; public class DecalPlacer : MonoBehaviour { public GameObject decalPrefab; public float decalDistance = 0.01f; // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; bool hitSomething = Physics.Raycast(ray, out hitInfo); if (hitSomething) { GameObject decal = Instantiate(decalPrefab, hitInfo.point + (hitInfo.normal)*decalDistance, Quaternion.identity); decal.transform.LookAt(hitInfo.point); } } } }
  13. 1 point
    Sieht langsam immer besser aus deine Map, wenn du Gras brauchst
  14. 1 point
    Lass dir mal ausgeben, was du genau triffst: print(hit.transform.gameObject) Ich vermute, dein Ray trifft ein anderes Objekt und nicht den Boden. Wenn das stimmt, dann würde ich dem Boden ein Layer (="Ground") verpassen und so den Layer für den Raycast setzen: LayerMask groundLayer = LayerMask.GetMask("Ground"); if (Physics.Raycast(trackObject.transform.position, Vector3.down, out hit,100, groundLayer.value))
  15. 1 point
    Hi. Mein Fehler! Kein Bug! Gut das immer noch andere drüber schauen. @Mr 3d hat natürlich recht! Für Wertebereiche zwischen 0-255 musst Du statt "new Color(r,g,b)", new Color32(r,g,b,a) nehmen. Color Color32
  16. 1 point
    Ich hab das jetzt nicht getestet.. aber ich glaube dass die Werte in einem Bereich von 0.0f - 1.0f liegen müssen. aus (84, 84, 84, 255) wird effektiv (1, 1, 1, 1), also weiß. (255, 0, 0) wird auf (1, 0, 0) geclampt, also rot..
  17. 1 point
    Mal wieder aktiv: https://media.giphy.com/media/3ohs4coAbOOugzqSlO/giphy.gif
  18. 1 point
    So, ich hab auch mal wieder etwas an einem Prototyp gearbeitet: https://www.youtube.com/watch?v=9x3USbS8nC0&feature=youtu.be
  19. 1 point
    Hab ich mich schon drauf gefreut, meine!
  20. 1 point
    Hier 2 Beispiele: public GameObject menueHauptbereich; public Text[] menueHauptmenuebereichTexte; private void Awake() { menueHauptmenuebereichTexte = menueHauptbereich.GetComponentsInChildren<Text>(); List<Text> reduzierteListe = new List<Text>(); foreach (Text texte in menueHauptmenuebereichTexte) { //if (texte.text.Contains("blabla")) reduzierteListe.Add(texte); if (texte.text.EndsWith("*")) reduzierteListe.Add(texte); } } Oberes Beispiel (auskommentiert) erwartet Text mit Inhalt "blabla" (irgendwo im Textfeld) Unteres Beispiel erwartet Text mit "*" am Ende ...
  21. 1 point
    Hi, ich bin mir grad nicht ganz sicher was du mit der foreach Schleife machen willst. Für mich klingt es so, als willst du alle Text Komponenten der Kindobjekte von "menueHauptbereich" in dein "menueHauptbereichTexte" Array schreiben. Is das nicht genau das, was "GetComponentsInChildren<Text>();" macht? ( https://docs.unity3d.com/ScriptReference/Component.GetComponentsInChildren.html ) Edit: zu langsam
  22. 1 point
    Für alle die es demnächst einmal brauchen sollten, um beispielsweise einen bestimmten Winkel bei einer Rotation zu prüfen. Hier eine Methode die auf einen Winkel von 0-360 Grad umrechnet, beispielhaft für die X-Achse (Unity 2017 notwendig). Der Winkel bezieht sich dabei auf das globale Koordinatensystem. using UnityEngine; using System.Collections; public class TestRotation : MonoBehaviour { void Start() { transform.Rotate(new Vector3(200, 0, 0)); print(transform.eulerAngles.x + " " + transform.eulerAngles.y + " " + transform.eulerAngles.z); print(GetRealAngleX()); transform.rotation = Quaternion.identity; transform.Rotate(new Vector3(130, 0, 0)); print(transform.eulerAngles.x + " " + transform.eulerAngles.y + " " + transform.eulerAngles.z); print(GetRealAngleX()); } float GetRealAngleX() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.forward, Vector3.forward, Vector3.right); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } float GetRealAngleY() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.right, Vector3.right, Vector3.up); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } float GetRealAngleZ() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.up, Vector3.up, Vector3.forward); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } }
  23. 1 point
    Für alle die es demnächst einmal brauchen sollten, um beispielsweise einen bestimmten Winkel bei einer Rotation zu prüfen. Hier eine Methode die auf einen Winkel von 0-360 Grad umrechnet, beispielhaft für die X-Achse (Unity 2017 notwendig). Der Winkel bezieht sich dabei immer auf das globale Koordinatensystem. using UnityEngine; using System.Collections; public class TestRotation : MonoBehaviour { void Start() { transform.Rotate(new Vector3(200, 0, 0)); print(transform.eulerAngles.x + " " + transform.eulerAngles.y + " " + transform.eulerAngles.z); print(GetRealAngleX()); transform.rotation = Quaternion.identity; transform.Rotate(new Vector3(130, 0, 0)); print(transform.eulerAngles.x + " " + transform.eulerAngles.y + " " + transform.eulerAngles.z); print(GetRealAngleX()); } float GetRealAngleX() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.forward, Vector3.forward, Vector3.right); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } float GetRealAngleY() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.right, Vector3.right, Vector3.up); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } float GetRealAngleZ() { float resAngle = 0; float angle = Vector3.SignedAngle(transform.up, Vector3.up, Vector3.forward); if (angle < 0) resAngle = resAngle - angle; else resAngle = 360 - angle; return resAngle; } }
  24. 1 point
    Ich habe dir mal eine Klasse gebastelt, damit kannst du nun die Defaultwerte des Launcher mit deinem Settings-Dialog abgleichen. Über die Klasse kannst du die Defaultwerte des Launchers überschreiben (und Auslesen).
  25. 1 point
    Ich würde mal behaupten, dass da eher die .Net Community der Gewohnheit folgt. Hieraus public int Health {get; set;} = 100; macht der Compiler einfach private int health = 100; public int GetHealth () { return health; } public int SetHealth (int value) { health = value; } In anderen (OOP) Sprachen (z.B. Java) ist es üblich eine Get und / oder Set Methode anzulegen, einfach weil's da nun mal keine properties für gibt ¯\_(ツ)_/¯ Wenn du da also nichts weiter mit get / set speziell anstellst (wie Sascha und Zer0 schon meinten), ist das eher Dogma als guter Stil. Für den Unity Editor speziell gibt's übrigens das [SerializeField] Attribut, damit auch private Felder serialisiert werden.
  26. 1 point
    Kann man machen wie man möchte aber ja, man macht ein Hauptmenü mit (oder so ähnlich) - Start Game - Load Game - Settings - Exit
  27. 1 point
    Hier mal schnell zusammengestrickt: // Examples of VideoPlayer function using UnityEngine; public class Example : MonoBehaviour { private UnityEngine.Video.VideoPlayer videoPlayer; void Start() { // Will attach a VideoPlayer to the main camera. GameObject camera = Camera.main.gameObject; // VideoPlayer automatically targets the camera backplane when it is added // to a camera object, no need to change videoPlayer.targetCamera. videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>(); // Play on awake defaults to true. Set it to false to avoid the url set // below to auto-start playback since we're in Start(). videoPlayer.playOnAwake = false; // By default, VideoPlayers added to a camera will use the far plane. // Let's target the near plane instead. videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane; // This will cause our scene to be visible through the video being played. // videoPlayer.targetCameraAlpha = 0.5F; // Set the video to play. URL supports local absolute or relative paths. // Here, using absolute. videoPlayer.url = "/Users/graham/movie.mov"; } // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.Space)) { videoPlayer.Play(); } } }
  28. 1 point
    Sollte eigentlich funktionieren, sieht alles gut aus. Aber bevor du weiter verzweifelst: Gibt's einen bestimmten Grund, warum du Resources.Load benutzt? In der Regel ist es viel einfacher und völlig in Ordnung, einfach direkt den AudioClip zu referenzieren. public AudioClip[] clips; audioSource.clip = clips[5]; audioSource.Play();
  29. 1 point
    Ich hoffe, ich hab beim Überfliegen das Problem nicht falsch verstanden, aber warum nicht einfach Gizmos.matrix nutzen? Hier ein kleines Beispiel, das nicht zu deinem Problem passt, aber die Funktionsweise vermutlich gut verdeutlicht: private void OnDrawGizmos() { Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawRay(Vector3.zero, Vector3.forward); Gizmos.DrawRay(Vector3.right, Vector3.forward); } Das einfach mal auf ein Objekt packen und mit Position, Rotation und Scale des Objekts spielen. Die Matrix4x4-Klasse hat eine statische Funktion namens Matrix4x4.TRS. Damit kannst du eine Matrix erstellen, statt sie wie im Beispiel aus einer Transform-Komponente zu ziehen.
  30. 1 point
    Hier ist ein Ansatz, es funktioniert soweit mit der Ausnahme, wenn die beiden Punkte sich nur in Y unterscheiden, dann muss eine Ausnahmebehandlung erfolgen (fehlt noch im Code) Also zum Beispiel: Vektor1(1, 0.5 , 5) und Vektor2(1, 0.9 , 5) Dies kommt daher, daß ich das "Koordinatensystem" zwischen den beiden Punkten über die Y-Achse aufspanne. using System.Collections; using System.Collections.Generic; using UnityEngine; public class MultiRay : MonoBehaviour { public Transform origin; public Transform target; public int numRows = 5; public int numColumns = 5; public float width = 0.25f; public float height = 0.25f; private void OnDrawGizmos() { if (origin != null && target != null) { Gizmos.color = Color.cyan; Gizmos.DrawSphere(origin.position, 0.2f); Gizmos.DrawSphere(target.position, 0.2f); Vector3 dir = (target.position - origin.position).normalized; Vector3 crossVector = (-Vector3.Cross(Vector3.up, dir)).normalized; Gizmos.color = Color.red; Gizmos.DrawRay(origin.position, crossVector * 3.0f); Vector3 crossVector2 = (-Vector3.Cross(crossVector, dir)).normalized; Gizmos.color = Color.yellow; Gizmos.DrawRay(origin.position, crossVector2 * 3.0f); for (int r = 0; r < numRows; r++) { for (int c = 0; c < numColumns; c++) { Gizmos.color = Color.green; Vector3 startPoint = -((crossVector * (numColumns-1) * width + crossVector2 * (numRows-1) * height) / 2.0f) + origin.position + crossVector * c * width + crossVector2 * r * height; Gizmos.DrawRay(startPoint , (target.position - origin.position)); //Gizmos.DrawRay(origin.position + crossVector*c*width + crossVector2 * r*height , (target.position - origin.position)); } } } } } Abschuss Sonne:
  31. 1 point
    Nichts falsch, Eigenheit des Unity-Editors (die Zeile über der Klasse Drehfelder): using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public struct Drehfelder { public GameObject drehfeld; public Quaternion startRotation; public Quaternion zielRotation; public enum richtung : short { Unbekannt, Positiv_X, Positiv_Z, Negativ_X, Negativ_Z } public richtung zielTeleporterRichtung; } public class Drehfeldsteuerung : MonoBehaviour { public Drehfelder[] drehfelder; private void Start() { } }
  32. 1 point
    Ok, dann hier mal ein Beispiel wie man die Blätter eines Baum-Assets mit der 2. Variante "beweglich" machen kann. 1) Folgendes Asset herunterladen (ist ein Beispiel für ein Baum-Asset): https://assetstore.unity.com/packages/3d/vegetation/trees/realistic-tree-pack-vol-1-50418 2) Shader in Unity importieren: Den Shader nach Unity imporieren, ich hab dir das File mal erstellt. Herunterladen und ins Unityprojekt schieben. https://ufile.io/ksb80 3) Neues Material in Unity erstellen. 4) Dem Material den neuen Shader zuweisen: "Custom/Tree/TransparentCutoutDiffuse Shake" 5) Material auf die Blätter des Baumes ziehen. Im Projektfenster: "RTP Vol.1"-> "prefabs" -> "tree1a pre" -> "leaves" -> Neues Material aus dem Projektfolder in den Mesh Renderer ziehen 6) Das Prefab "tree1a pre" des Baums in die Szene ziehen. Der Shader arbeitet allerdings NICHT mit der Unity Windzone. Er simuliert einfach Windbewegungen über die Settings des Materials!
  33. 1 point
    Teleporter[] teleporters = FindObjectsOfType<Teleporter>(); // Alle Teleporterskripte in der Szene finden print("Anzahl gefundene Teleporters: " + teleporters.Length); // Alle Teleporter durchgehen int i = 0; foreach (Teleporter teleporter in teleporters) { i++; Debug.Log(i); Debug.Log(teleporter.gameObject); }
  34. 1 point
    Ich vermute mal alle 4 Wände sind von Innen transparent? Vermutlich ein "Fehler" beim Erzeugen des Meshes. Wenn die Normalen der Meshwände nach Außen zeigen, dann sind die Wände von innen nicht sichtbar. 3 Lösungsmöglichkeiten: des Mesh anders konstruieren (doppelte Wände, 1 Wand die nach außen zeigt und eine Wand die nach innen zeigt) alle 4 erzeugten Meshwände 1x kopieren und nach innen drehen als Beispiel: die erzeugte Wandseite wird 1xkopiert und 1x um 180 Grad gedreht, damit zeigt die Außenwand der kopierten Wand nun nach innen. Double Sided Shader verwenden, dieser verwendet die Normalen des Meshes auch für die Innenseiten, damit wird die Wand innen sichtbar
  35. 1 point
    Der Trigger stellt sicher, daß nur 1 Zustandswechsel erfolgt. Bei Bool kann es dir passieren (je nachdem wie man die Transitionen setzt), daß mehrere Übergange erfolgen. Zustand A -> (isB == true) -> Zustand B -> irgendwas -> Zustand C Zustand A <- irgendwas <- Zustand C Code: - isB = true => wechselt nach B - irgendwas => wechselt nach C - irgendwas => wechselt nach A => wechselt nach B (ggf. ungewollter Zustandsübergang) *irgendwas Steht für eine beliebige Bedingung die einen Zustandswechsel erzeugt
  36. 1 point
    Hallo zusammen, ich stelle mal auch mein Projekt vor Es handelt sich , wie des Thema schon beschreibt um ein Fitness Spiel. Man startet "unsportlich" und kann sich im Spiel Trainieren. Dazu hat man verschiedene Übungen. Nebenbei kann man auch Eiweiß, Kreatin nehmen um seine Trainingsergebnisse zu verbessern. Diese kann man für Coins kaufen die man entweder durchs Werbung schauen bekommt oder für Level ups Das Trainieren kostet Kcal welche sich alle 24h um einen bestimmten betrag erhöhen wenn man sich ins Spiel einloggt. Sobald die Kcal zur verfügung stehen bekommt man eine Push notification. Auserdem kann man jede Übung nur alle 15 Stunden Trainieren, danach hatt meine eine Art Cooldown. Diese werden mit Timestamps die vom Server kommen errechnet. Je mehr man Trainiert desto höher steigt die "Belastungs Anzeige", dies ist auch abhängig von der Übung. Die Belastungs reduziert sich täglich um einen gewissen Betrag. Ist diese bei 100% muss man halt warten bis man sich Erholt hat. Indem man im Shop bandagen kauft kann man diese auch reduzieren. Nebenbei hat man eine Freundschaftsliste wo das Level und Erfahrungspunkte angezeigt werden. Also beim Bild "Ubung" sieht man das das Trainieren nur über einer Gui verläuft, also man klickt auf Trainieren und Punkte werden Addiert. Beim BANKDRÜCKEN , KNIEBEUGEN, KREUZHEBEN sind aber komplette Animationen enthalten und man erfährt das Gewicht welches man Maximal stemmen kann.Diese Gewichte erhöhen sich auch mit steigender Kraft. Die Werte kann man dann auch in der Freundschaftsliste sehen und sich somit messen oder in Facebook Teilen Nebenbei wird auch noch das Gewicht des Charakters angezeigt. Ich glaube das wars Freue mich sehr auf Verbesserungsvorschläge, und noch mal ein Dank ans Forum und an den Leuten die mir bei meinen Fragen geholfen haben Android + IOS DrawCalls: 15 Tries: 40.000
  37. 1 point
    Die Frage ist vielleicht falsch gestellt, da GameObject/MonoBehaviours (in meinen Augen) bereits ein "Design Pattern" sind und daher das gängige Design Pattern in Unity (auch wenn das vielen nicht bewusst ist). Es macht aber durchaus Sinn sich davon zu lösen, da es oft nicht sehr performant ist. Wenn man das MVC auf Unity anwendet, dann gibt es in Unity quasi 2 Views. Die gerenderten Objekte und das UI. M + C werden in Unity dabei oft in einer Komponente vermischt. Möchte man beides Trennen, dann kann man diese in 2 Klassen auftrennen, eine Kontrollerklasse (Monobehavior) und eine Datenklasse (einfache C#-Klasse). Die Daten könnte man nochmals auftrennen in Szenendaten und Projektdaten. Szenendaten werden dabei als Instanz in der Szene gehalten, Projektdaten als Assets.
  38. 1 point
    Ja, tut es, aber war noch ein kleiner Fehler drin, so wäre es richtig: float step = speed * Time.deltaTime; Vector3 target = transform.position + transform.forward * 50; transform.position = Vector3.MoveTowards(transform.position, target, step); "target" sind dann 50 Einheiten in Richtung lokaler Vorwärtsachse des transforms (also dahin wohin geschaut wird).
  39. 1 point
    "Assembly-C-Sharp" ist die Assembly, in die dein ganzer eigener Code geladen wird, also kein Unity stuff wenn ich mich recht erinnere. Unity hat also irgend ein Problem damit, was von deinem Code zu laden. Das könnte beispielsweise durch Zugriff auf korrupten Speicher (Access Violaation) passieren. Sprich: irgendeine deiner Dateien ist eventuell beschädigt oder ähnliches.
  40. 1 point
    Abgesehen von Unity selber und Assets die sich in einem Projekt befinden ...oder eine Systemfehler auf deinem PC (defekte Festplatte, defekter Ram) Ich hatte schon einmal ähnliche Probleme mit Virenscannern (auf meinem System sind mindestens 2 aktiv, der von Windows und ein selbst installierter) und andere Software (AdwareScanner usw.) die im Hintergrund Dateien scannen. Man sollte für Unity Ausnahmeregeln erstellen und Projektverzeichnisse und Unity selbst aus diesen Scannern herausnehmen. Es kann ansonsten passieren, daß der Scanner entweder eine Datei des Unityprojektes blockiert oder eine Datei von Unity (DLL), was schlimmstenfalls zu einem Unitycrash führen kann.
  41. 1 point
    Ich schließe mich hier auch mal an. In letzter Zeit habe ich mich mal dem (zusammen-)bau einer Tastatur gewidmet: Fehlt noch eine Unterseite, und ggf. muss ich ein paar der Kabel noch umlegen um das ganze Kompakter zu bekommen, da sonst das Gehäuse nicht zu geht.
  42. 1 point
    So letzter Versuch. An der alten Fehlerstelle folgendes einsetzen (Zeile 414): #if defined(SHADOWS_SCREEN) attenuation = 1; #else UNITY_LIGHT_ATTENUATION(attenVal, input, posWorld); //Das Problem attenuation = attenVal; #endif Scheinbar nimmt er so bei Schatten des Directional Light die obere Zeile und ohne Schatten die untere... Hat irgendwie was mit mehreren Shadervarianten zu tun... die vermutlich beim Kompilieren erzeugt werden...
  43. 1 point
    Funktioniert bei WoW auch nicht richtig, die haben die Anzahl der Leute in einer Instanz von 40 Leuten auf 25 und 10 gesenkt. Als ich es noch gespielt habe, konnte man sich in einer Stadt teilweise kaum bewegen, wenn da mehr wie 50 Leute unterwegs waren ... Ansonsten --- möglich ist es schon -- aber der (Optimierungs)Aufwand ist enorm: - die Anzahl der Spielerdaten senken wo es nur geht - Spielerdaten komprimieren bevor sie versendet werden - Verarbeitung von Spielerdaten hochperformant programmieren (C / Assembler) - Serverleistung erhöhen (entsprechende Hochleistungsserver) - ggf. Verarbeitung von Spielern auf einer Instanz auf mehrere Server verteilen - Lösungen finden, um die Synchronisationsrate zwischen Server und Clients zu senken: Hier gibt es diverse Techniken wie Extrapolation / Interpolation und "Predictive Movement" (Bewegungsvorhersage) die man oft zusätzlich zum Networking Framework selbst implementieren muss (in UNET sind nur Ansätze davon enthalten).
  44. 1 point
    Siehe meine Mail, ich vermute du musst dein Array auf 65x65 Felder "strecken", da Unity bei der Heightmap-Resolution immer 2^x + 1 haben möchte. Wenn du also bei der HMR 65 einstellst und über SetHeights nur ein 64x64 Array übergibst, dann setzt Unity die Höhe für die letzte Spalte und die letzte Zeile nicht (=Höhe 0) und damit bekommst du einen Rand. Ich würde einfach den letzten Spalteneintrag verdoppeln und die letzte Zeile.
  45. 1 point
    Ich bin mir nicht sicher, ob dir die Beschreibung ausreicht, ich versuche es mal: - Prefab für die Raketen machen und Skript dranhängen, welches sich um die Kollisionserkennung kümmert (dieses Skript kann auch Partikeleffekte starten) - RB ans Prefab hinzufügen - ein 2. Skript erstellen, welches dafür sorgt, diese Raketen abzuschiessen (siehe unten) Das 1. Skript lasse ich mal weg. Bei Bedarf, kann ich es ja nochmal nachliefern. Ich habe noch einmal Aufladungen hinzugefügt. Wenn nicht benötigt einfach auf 1 setzen. using System.Collections; using System.Collections.Generic; using UnityEngine; public class Missilecontroller : MonoBehaviour { public GameObject MissileLeft; public Transform MissileSpawnLeft; public int MissileChargesLeft = 10; public GameObject MissileRight; public Transform MissileSpawnRight; public int MissileChargesRight = 10; public float MissileSpeed = 20f; private enum Side { Left, Right }; private Side shoot; void Start() { shoot = Side.Left; } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) { Fire(); } } void Fire() { GameObject prefab = null; Transform spawn = null; if (shoot == Side.Left && MissileChargesLeft > 0) { prefab = MissileLeft; spawn = MissileSpawnLeft; MissileChargesLeft--; } if (shoot == Side.Right && MissileChargesRight > 0) { prefab = MissileRight; spawn = MissileSpawnRight; MissileChargesRight--; } if (prefab == null) return; // No charges left // Create the missile from the missile prefab GameObject missile = (GameObject)Instantiate(prefab, spawn.position, spawn.rotation); // Add velocity to the missile missile.GetComponent<Rigidbody>().velocity = missile.transform.forward * MissileSpeed; // Destroy the missile after 4 seconds Destroy(missile, 4.0f); // Trigger next missile if (shoot == Side.Right) shoot = Side.Left; else shoot = Side.Right; } } "MissileLeft" und "MissileRight" sind die Prefabs für die Raketen. "MissileSpawnLeft" und "MissileSpawnRight" sind "Marker" (3D-Spawnpunkte) in der Szene, wo die Raketen herauskommen sollen. Für solch einen Marker einfach ein leeres GameObjekt erzeugen und an die korrekte Position verschieben. Den Marker mit der blauen Achse in die Richtung drehen wohin die Rakete fliegen soll!
  46. 1 point
    Hallo mein Name ist Turritom und ich entwickel in meiner Freizeit ein Dungeon Crawler mit Unity und Playmaker. das Ganze ist seit ca. 4-5 Wochen in der Entwicklung(meist abends nach Feierabend) also befindet sich in einer sehr frühen Entwicklungsphase. Ich möchte hier in dem Threat immer meine Fortschritte zeigen. Als erstes habe ich ein Youtube Video erstellt das so den derzeitigen Stand zeigt. Das Ganze soll so grob eine Mischung aus Dark Souls/Roque Legacy//Dungeon of the Endless/Binding of Isaac usw. werden. Über Fragen und Anregungen würde ich mich natürlich freuen. hier der Link zum Video
  47. 1 point
    Hallo, ich möchte euch ein paar Bilder vom aktuellen Projektstand zeigen.
  48. 1 point
    so ich teste ein paar fallen im Jail Level
  49. 1 point
    Hier noch eine leicht verbesserte Version mit Rotation um 2 Achsen: Wheelcontrol: using UnityEngine; using System.Collections; public class WheelControl : MonoBehaviour { public bool rotating = false; float speed = 45.0f; float maxSteering = 45.0f; public void Rotate(float angle, Vector3 axis) { StartCoroutine(RotateBy(angle, axis, speed)); } IEnumerator RotateBy(float angle, Vector3 axis, float speed) { rotating = true; Quaternion start = transform.localRotation; if ((start.eulerAngles.z + angle) < (90.0f - maxSteering) || (start.eulerAngles.z + angle) > (90.0f + maxSteering)) { rotating = false; yield break; } // Debug.Log("x. " + start.eulerAngles.x + " angle: " + angle + " sum "); if ((start.eulerAngles.x != 0) && (start.eulerAngles.x - angle) < (360f - maxSteering) && ((start.eulerAngles.x - angle) > (maxSteering))) { rotating = false; yield break; } float curAngle = 0.0f; while (Mathf.Abs(curAngle - angle) > 0.0001f) { curAngle = Mathf.MoveTowards(curAngle, angle, Time.deltaTime * speed); transform.localRotation = Quaternion.AngleAxis(curAngle, axis) * start; yield return null; } transform.localRotation = Quaternion.AngleAxis(angle, axis) * start; rotating = false; } } Hovercarcontrol: using UnityEngine; using System.Collections; public class HoverCarControl : MonoBehaviour { Rigidbody body; float deadZone = 0.1f; public float groundedDrag = 3f; public float maxVelocity = 50; public float hoverForce = 1000; public float gravityForce = 1000f; public float hoverHeight = 1.5f; public GameObject[] hoverPoints; public float forwardAcceleration = 8000f; public float reverseAcceleration = 4000f; float thrust = 0f; float acceleration = 0f; public float turnStrength = 1000f; float turnValue = 0f; public ParticleSystem[] dustTrails = new ParticleSystem[2]; public WheelControl[] Wheels; int layerMask; void Start() { body = GetComponent<Rigidbody>(); body.centerOfMass = Vector3.down; layerMask = 1 << LayerMask.NameToLayer("Vehicle"); layerMask = ~layerMask; } // Uncomment this to see a visual indication of the raycast hit points in the editor window // void OnDrawGizmos() // { // // RaycastHit hit; // for (int i = 0; i < hoverPoints.Length; i++) // { // var hoverPoint = hoverPoints [i]; // if (Physics.Raycast(hoverPoint.transform.position, // -Vector3.up, out hit, // hoverHeight, // layerMask)) // { // Gizmos.color = Color.blue; // Gizmos.DrawLine(hoverPoint.transform.position, hit.point); // Gizmos.DrawSphere(hit.point, 0.5f); // } else // { // Gizmos.color = Color.red; // Gizmos.DrawLine(hoverPoint.transform.position, // hoverPoint.transform.position - Vector3.up * hoverHeight); // } // } // } void Update() { // Get thrust input thrust = 0.0f; acceleration = Input.GetAxis("Vertical"); if (acceleration > deadZone) thrust = acceleration * forwardAcceleration; else if (acceleration < -deadZone) thrust = acceleration * reverseAcceleration; // Get turning input turnValue = 0.0f; float turnAxis = Input.GetAxis("Horizontal"); if (Mathf.Abs(turnAxis) > deadZone) turnValue = turnAxis; } void FixedUpdate() { // Do hover/bounce force RaycastHit hit; bool grounded = false; for (int i = 0; i < hoverPoints.Length; i++) { var hoverPoint = hoverPoints [i]; if (Physics.Raycast(hoverPoint.transform.position, -Vector3.up, out hit,hoverHeight, layerMask)) { body.AddForceAtPosition(Vector3.up * hoverForce* (1.0f - (hit.distance / hoverHeight)), hoverPoint.transform.position); grounded = true; } else { // Self levelling - returns the vehicle to horizontal when not grounded and simulates gravity if (transform.position.y > hoverPoint.transform.position.y) { body.AddForceAtPosition(hoverPoint.transform.up * gravityForce, hoverPoint.transform.position); } else { body.AddForceAtPosition(hoverPoint.transform.up * -gravityForce, hoverPoint.transform.position); } } } var emissionRate = 0; if(grounded) { body.drag = groundedDrag; emissionRate = 10; } else { body.drag = 0.1f; thrust /= 100f; turnValue /= 100f; } for(int i = 0; i<dustTrails.Length; i++) { var emission = dustTrails[i].emission; emission.rate = new ParticleSystem.MinMaxCurve(emissionRate); } // Handle Forward and Reverse forces if (Mathf.Abs(thrust) > 0) body.AddForce(transform.forward * thrust); // Handle Turn forces if (turnValue > 0) { body.AddRelativeTorque(Vector3.up * turnValue * turnStrength); } else if (turnValue < 0) { body.AddRelativeTorque(Vector3.up * turnValue * turnStrength); } // Limit max velocity if(body.velocity.sqrMagnitude > (body.velocity.normalized * maxVelocity).sqrMagnitude) { body.velocity = body.velocity.normalized * maxVelocity; } foreach (WheelControl wheel in Wheels) { if (!wheel.rotating) { //Debug.Log("rotateby "+ wheel .gameObject.name + " by: " + turnValue); float maxSteeringAngle = 45.0f; //Debug.Log(maxSteeringAngle * acceleration); float angleh = maxSteeringAngle * turnValue; float anglev = maxSteeringAngle * acceleration; wheel.Rotate(angleh, Vector3.forward); wheel.Rotate(anglev, Vector3.left); } } } } Weitere Verbeserungen wären wie gesagt, die Räder wieder auf ihre 0-Positionen zu bringen und die Rotation in V und H in eine Coroutine zu packen (ist sogar dringend angesagt, da aktuell eigentlich nur um eine Achse zu gleichen Zeit gedreht werden kann, du könntest auch 2 Coroutinen erstellen und müsstet dann den "rotating" bool für 2 Routinen auslegen bspw. "rotatingh" und "rotatetingv"). Die Räder scheinen auch noch bei ihren maximalen Ausschlagswinkeln ab und zu hängen zu bleiben, da muss man noch an der RotateBy()-Routine drehen, an der Stelle wo ich die Coroutine verlasse (yield break), wenn der maximale Ausschlagswinkel erreicht wird (mit Rotation auf 0-Stellung entfällt dieses Problem).
  50. 1 point
    Weil viele Leute ein Spiel mit Unity erstellen wollen, aber ein paar wichtige Infos fehlen, werde ich hier einmal erklären was alles wichtig ist und warum es manchmal zu Problemen kommt. Warum mach ich das? Weil ich mich eben gerade geärgert habe! Eines unserer Forenmitglieder (den Namen werde ich nicht nennen) hatte mich eben über Skype gefragt, ob ich jemanden kennen würde, der 3D Objekte erstellt. Das war die Frage, nicht mehr und nicht weniger! Natürlich war mir klar was er wollte. Er wollte, dass ich ihm jemanden vermittle, der kostenlos Modelle erstellt oder aber das ich sie für lau erstelle. Als ich ihm gesagt hatte, dass ich einige Leute kenne, die das aber professionell, also gegen Bezahlung machen, und ich selber keine Zeit dafür habe, hat er mich aus den Kontakten raus gekickt! Das war nicht die feine Art und außerdem unrealistisch. Vorallem ärgert es mich, da ich ihm schon einige Male geholfen habe. Somit sind wir beim Thema: Jeder, der ein Spiel erstellen will sollte beachten, dass ein Spiel nicht nur aus dem Code besteht, der die Engine (in unserem Fall Unity3d) steuert. Nein, das Wichtigste sind die Objekte, die gesteuert werden! Die müssen in einem 3D Programm oder, wenns 2D sein soll, in einem 2D Grafikprogramm erstellt werden. Diese Sachen kosten eine Menge Zeit und Können! Die meisten Leute denken, dass sowas mal eben gemacht ist. Dem ist nicht so. Ein einfaches Haus welches ne nette Textur hat, dauert schon mehrere Stunden. Ein Männchen, welches mit Bones versetzt und animiert wird, dauert mindestens einen Tag, wenn nicht mehrere Tage!!!! Die Objekte für ein ganzes Spiel dauern Wochen bis Monate, bis sie alle gebaut, texturiert, animiert und arangiert sind! Natürlich braucht ein Spiel auch Geräusche und Musik. Einfache Geräusche sind teilweise im Netz für lau zu bekommen. Gute Geräusche muss man kaufen oder aber selber aufnehmen bzw. selber erstellen. Dieses dauert auch. Nicht ganz so lang, aber es summiert sich. Bei der Musik sieht es schon ganz anders aus. Wer kann schon selber Musikstücke erstellen. Also entweder kaufen oder jemanden komponieren lassen. Natürlich gibt es auch GEMA freie Stücke im Netz, meist passen die aber nicht oder andere Spiele haben diese Musik schon drin. Das will man natürlich nicht. Jetzt kommt die GUI, die Menüs, die Anzeigen, und und und... auch dafür braucht es jemanden, der sowas kann, wenn es nach etwas aussehen soll. Auch hier kann man mehrere Tage einplanen, bis alles Nebensächliche erstellt worden ist. Story, Dialoge, Spielziele lasse ich jetzt einfach mal weg. Da gehe ich davon aus, dass wenigstens das vorher schon gemacht wurde. Das Programmieren des Codes rechne ich auch nicht ein, denn ich gehe davon aus, dass die Jungs hier, genau das machen. So, jetzt seht ihr, dass ein Spiel viel mehr ist, als einen Cube von a nach b zu bewegen. Ihr solltet jetzt auch erkennen, dass komplexere Spiele nur schwer von einer Person zu bewältigen sind. Ihr solltet außerdem bedenken, dass die Sachen, die ihr nicht könnt, nicht immer umsonst von anderen Leuten hergestellt werden. Nein, gerade das Gegenteil ist der Fall. Es dauert nämlich unheimlich lange und warum sollte der Mensch seine Freizeit für jemanden anderes opfern, von dem er nichts hat? Was mir auch noch ganz wichtig ist: Nur weil ich Tutorials umsonst ins Netz stelle, heißt das nicht dass ich alles umsonst mache und nix anderes zu tun habe als hilflosen Fans zu helfen. Die Tutorials sind gerade deswegen da, damit andere Leute es lernen und selber machen können! Es geht nicht nur mir so, nein allen Jungs geht's so, die Tut's ins Netz stellen. Ganz so als wäre man Mutter Theresa! Versteht einfach, dass so Leute wie ich 40Stunden in der Woche arbeiten, eine Familie haben, eigene Hobbys betreiben und dann nur noch wenig Zeit für anderes da ist. Diese wenige Zeit ist kostbar und wird nicht leichtfertig an Andere abgetreten. Somit macht euch klar, dass nix umsonst ist! Manchmal hat man Glück und bekommt etwas für lau. Meistens aber nicht. Also bleibt euch nur alles selber zu machen, sich mit Gleichgesinnten zusammen zu schließen um alle Felder abzudecken oder aber Geld für Leistungen zu bezahlen. Selbst die Gleichgesinnten wollen was haben. Meist arbeiten sie in Vorleistung und wollen einen Teil des Gewinns, wenn es denn einen Gewinn gibt. Das Ganze soll euch nicht entmutigen, nur die Augen öffnen!
×