Jump to content
Unity Insider Forum

Sascha

Administrators
  • Content Count

    11,522
  • Joined

  • Last visited

  • Days Won

    565

Everything posted by Sascha

  1. Wenn du mich (und viele andere fragst), ist Komponenten-Design, gerade für Spiele, wesentlich besser als klassisches OOP. Wenn man seinen Code in verschiedene logische Einheiten (Klassen) aufteilt, dann kann man das noch gar nicht richtig OOP nennen. OOP bedeutet, Klassen voneinander erben zu lassen und damit eine hierarchische Ordnung herzustellen. Das ist für Spiele oft mehr schlecht als recht. Stattdessen voneinander abhängige Komponenten zu bauen, ist nicht ohne gutem (!) Grund der Weg, wie man das in Unity macht. Ja gut, das sollte man so oder so vermeiden
  2. Naja, auch OOP kann man in Unity benutzen - und auch lernen. Aber in Unity gibt's halt noch komponentenbasiertes Design obendrauf, und beides gleichzeitig zu lernen (und auseinanderhalten zu müssen) macht den Lernprozess wesentlich schwerer als nötig. Wenn dir ein brauchbarer Lehrer OOP mit Unity beibringen will, ist das vermutlich okay, aber auf eigene Faust wirst du immer wieder in (unnötige) Verständnisprobleme wie dieses laufen.
  3. Also, erstmal kannst du Dinge aus Lehrmaterial zu objektorientiertem Programmieren nicht unbedingt auf Unity-Klassen übertragen. Beide deine Klassen erben von MonoBehaviour, was sie zu Komponenten macht. Und Komponenten darfst du niemals über new erzeugen. Ein üblicher (aber nicht der einzige) Weg, dass ein Objekt ein anderes kennenlernt, ist über GetComponent. Dafür ziehst du beide Scripts auf dasselbe GameObject. Dann kannst du, am besten in Awake, die eine Komponente die andere aussuchen lassen: Script_B script_b; private void Awake() { script_b = GetComponent<Script_B>(); }
  4. Muss er nicht. Du kannst bei jedem Raycast eine LayerMask mitgeben, die bestimmt, welche Layer getroffen werden können. Darüber hinaus kannst du nach dem Raycast das getroffene Objekt filtern. Eine LayerMask kannst du z.B. so benutzen: [SerializeField] private LayerMask layers; private void Update() { RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, layers)) { // ... } } Dann kannst du im Inspektor ein Häckchen bei jedem gewünschten Layer setzen. Da musst du aber bedenken, dass der Ray blind durch alles durchgeht, was nicht der LayerMask entspricht. Du kannst also durch ein platziertes Gebäude hindurch den Boden treffen. Üblicherweise würde man ja aber wollen, dass man einfach nicht bauen kann, wenn die Maus über einem Gebäude ist. Du würdest also eher einfach Raycasten und dann schauen, was getroffen wurde: private void Update() { RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (CanBuildOn(hit.collider)) { // ... } } } private bool CanBuildOn(Collider c) { // Check if c is ground } CanBuildOn kann jetzt beliebig aussehen. Wieder ein bestimmter Layer wäre möglich, aber auch eine Komponente auf dem Boden-GameObject. Von Tags würde ich wie üblich abraten.
  5. Dickes Update: Unter anderem enthält das Paket jetzt den gesamten Quellcode.
  6. I know this is not the answer you hoped for, but before solving any problems, you should abandon UnityScript as it's entirely unsupported by now. Switch to C# and see if you get the same issues, then you should go from there.
  7. Dann solltest du dir die Zeit für ein paar Einführungstutorials nehmen. Aber ansonsten einfach private void OnMouseDown() { Debug.Log(gameObject.name + " wurde geklickt!"); }
  8. Ja, und alle Leute antworten dasselbe. Wenn du diese Hürde nicht überwinden kannst, ist Spieleentwicklung vielleicht einfach nichts für dich.
  9. Doch. Dein erstes Video zeigt auch keine Kugeln, sondern Dinge mit gerade Kanten. Da fällt das weniger auf. Sobald deine Szene auch nicht mehr nur aus einer einzelnen Kugel besteht sondern aus einer richtigen Welt, dann merkt man das nicht mehr so. Dinge, die im Fokus sind, müssen halt auch eher in der Mitte sein. Wenn du's aber nicht glauben kannst, nimm dir einfach mal das Handy und einen möglichst perfekt runden Ball. Dann machst du ein Foto von recht nah dran, sodass der Ball ganz an der seitlichen Kante des Fotos ist. Dann zoomst du so an das Bild heran, dass der Ball im Mittelpunkt ist. Ist dann auch nicht mehr rund. Das ist ganz normal, aber unser Gehirn erlaubt uns nicht, solcherlei Dinge im Augenwinkel zu sehen. Da überrascht es uns das erste Mal, wenn wir auf ein perspektivisches Bild schauen, da aber dann die Möglichkeit haben statt in die Mitte an den Rand zu schauen. Das passiert halt einfach in der Natur nicht. Ich wette auch mit dir, dass wenn du dich zwingst, den Fokus auf der Mitte des Bildes zu halten, dass dir dann nichts komisches mehr auffällt. Naja, zumindest wenn dein Bildschirm einen hinreichend großen Anteil deines Sichtfeldes einnimmt.
  10. Das ist normal. Wenn du drauf achtest, fällt dir das bei jedem einzelnen Spiel auf, das es gibt.
  11. Dein Vertex-Array wird schon einmal falsch angelegt. vertices[i + a] = bla; Da werden nicht der Reihe nach alle Elemente des Arrays befüllt, sondern Teile wieder überschrieben. Richtig wäre vertices[i + a * kreispunkte] = bla; Damit sehen auch die Vertices gleich etwas besser aus. Irgendwo in deinen sechs Zeilen nach der inneren for-Schleife ist noch was komisch... und die Faces zeugen alle nach innen. Aber sonst sieht das dann schon ganz richtig aus.
  12. Es sollte auch in Unity 2019.x noch gehen, ein Script mit OnMouseDown auf ein Objekt zu werfen. In beiden Fällen braucht dein GameObject einen Collider.
  13. Benutze mal bitte einen Code-Block (<>-Knopf) anstatt riesiger Bilder für deinen Code Was das Problem angeht: Ich lese und und ich habe keine Ahnung, wo das Problem liegt. "Funktioniert nicht" ist halt nach wie vor keine brauchbare Fehlerbeschreibung. Deinem ersten Code-Bild entnehme ich die Vermutung, dass du ein korrektes Basisverständnis über den Zusammenhang von Vertices und Triangles erworben hast. Schreibe doch einfach mal: Was erwartest du, was passiert? Was für Code benutzt du dafür? (und zwar nicht nur einen kleinen Ausschnitt, bei dem eindeutig etwas fehlt) Was passiert stattdessen, was nicht wie erwartet ist?
  14. NavMeshes befinden sich auf Renderern oder Collidern. Wenn du also über See fahren willst, brauchst du eines von beidem, damit sich ein NavMesh darauf bilden kann. Du kannst also einfach eine Plane drunter packen, und sicherstellen dass sie Navigation Static ist. Dann dasselbe mit den Ländern tun, damit diese auf einem anderen NavMesh-Layer auch als Hindernisse für deine Schiffe dienen.
  15. Dann kannst du Transform.TransformDirection benutzen, um deinen Wisch-Vektor reinzuschmeißen und eine Richtung relativ zur Ausrichtung der Kamera zu erhalten.
  16. "Vorne" der Kamera kannst du abfragen durch Camera.main.transform.forward Da die Kamera ja aber auch etwas nach oben oder unten gucken kann, solltest du den Y-Wert dieses Vektors auf 0 setzen, um einen horizontalen Vektor zu erhalten. Könnte also insgesamt etwa so aussehen: public void KickBall() { var direction = Camera.main.transform.forward; direction.y = 0; ball.AddForce(direction.normalized * power, ForceMode.Impulse); }
  17. Joa, gut, dann ist mein Code weiter oben ja das, was du brauchst.
  18. Ach so... Naja, das Problem löst sich ja auch mit dem Code von mir oben. Ich meine: Warum solltest du wollen, dass dein Runtime-Code dein Projekt verändern kann? Da würde ich lieber verhindern, dass das passiert als zu versuchen, die Änderungen vom Play Mode persistent zu machen. Ansonsten kannst du sicherlich irgendwie ein AssetDatabase.SaveAssets oder so durchführen, um alles mögliche zu speichern, was sich geändert hat.
  19. Deine (!) ScriptableObjects sind Assets. Assets werden nicht zurückgesetzt, wenn du den Play Mode ausmachst. Gilt gleichermaßen für alle anderen Assets, wie z.B. Materials. Wenn du die Werte deiner ScriptableObjects in deinem Code veränderst, hilft dir dieses Pattern: public class IntVariable : ScriptableObject, ISerializationCallbackReceiver { [SerializeField] private int initialValue = default; [System.NonSerialized] public int value; public void OnAfterDeserialize() { value = initialValue; } public void OnBeforeSerialize() { } } Wenn du im Editor jetzt die "initialValue" verstellst, dann bleibt die Änderung, aber dein Code arbeitet mit "value", welches nicht serialisiert wird. Du kannst damit jetzt den Laufzeit-Wert weder anschauen (es sei denn, du schreibst ein bisschen Editor-Code) noch ändern (dafür brauchst du dann heftigen Editor-Code, wie ich ihn in Soda eingebaut habe).
  20. Soda ist für kurze Zeit (wie lang genau, weiß ich leider selber nicht...) 30% reduziert!
  21. Am besten ist es, wenn du die Ursache für das Leerzeichen behebst, aber ansonsten (oder auch einfach zur Sicherheit) hilft dir " meinString ".Trim()
  22. Asset Bundles sind auch dafür da, im Editor erstellt und im Build nur geladen zu werden. Wenn du etwas serialisieren willst, gibt's dafür zwei Teile: Das Format und die Datenquelle. Beim Format kannste machen was du willst. Ganz simpel wäre es, die Daten in Json reinzuknallen. Dafür hat Unity direkt JsonUtility eingebaut, aber du kannst auch ein beliebiges Paket dafür herunterladen. Bei der Datenquelle musst du halt schauen, in welcher Weise deine Daten, die du serialisieren willst, vorliegen. Bei z.B. einem einfachen Objekt oder Struct kannst du das Ding in JsonUtility reinstopfen und unten kommt ein String heraus, den du in eine Datei schreiben kannst. Wenn du eine beliebige Menge an platzierten Objekten hast, die gespeichert werden sollen, dann musst du da ein bisschen mehr Arbeit reinstecken. Im Zweifelsfall sollte es aber reichen, alle zu speichernden Tiles in ein Array oder eine Liste zu stopfen und dann diese Liste zu serialisieren.
  23. OnTriggerEnter geht auch. Das eine ist halt für Kollisionen und das andere für Dinge, die einen Trigger berühren. Trigger sind halt durchlässig, deshalb ist das keine Kollision in dem Sinne. http://www.unitystudygroup.com/collisiontable
  24. Grundlegender Hinweis: Wenn etwas nicht funktioniert, und du glaubst, es sei ein Bug in Unity oder so, dann liegt's mit 99.893% Wahrscheinlichkeit in Wirklichkeit an dem, was du gemacht hast Mit if (Input.GetAxis("Fire2") >= 0.5f) kann man einfach nicht sonderlich viel falsch machen. Kannst ja einfach mal einen UI-Text irgendwo hintun und da so ein Script drankleben: private void Update() { GetComponent<UnityEngine.UI.Text>().text = Input.GetAxis("Fire2") + ""; } (Kurz und hässlich hingeschrieben...) Wenn dein Controller nicht irgendwie kaputt ist, dann solltest du damit recht sinnvolle Werte sehen können.
  25. Camera.main.transform.gameObject.transform.position Alter! Das stimmt leider nicht. Vector3.forward ist das gleiche wie new Vector3(0,0,1). Transform.forward ist die Richtung, in die das Objekt "schaut". transform.forward eines Objekts mit Rotation (0, 90, 0) wäre entsprechend (1, 0, 0). Anders gesagt: transform.forward ist ein Shorthand für transform.TransformDirection(Vector3.forward). Wenn du transform.TransformDirection(transform.forward) schreibst, kommt Käse dabei heraus. Ich nehme mal an, du willst den "vorne"-Vektor der Kamera haben. Hast aber nicht Camera.main.transform.forward geschrieben. Du benutzt hier den "vorne"-Vektor des Objekts, auf dem das Script liegt.
×
×
  • Create New...