Jump to content
Unity Insider Forum

Sascha

Administrators
  • Posts

    12,863
  • Joined

  • Last visited

  • Days Won

    698

Everything posted by Sascha

  1. Jup, Events: https://developers.google.com/admob/unity/interstitial // Called when an ad request has successfully loaded. this.interstitial.OnAdLoaded += HandleOnAdLoaded; // Called when an ad request failed to load. this.interstitial.OnAdFailedToLoad += HandleOnAdFailedToLoad; // Called when an ad is shown. this.interstitial.OnAdOpening += HandleOnAdOpened; // Called when the ad is closed. this.interstitial.OnAdClosed += HandleOnAdClosed; // Called when the ad click caused the user to leave the application. this.interstitial.OnAdLeavingApplication += HandleOnAdLeavingApplication; Ich würde sagen, du machst interstitial.OnAdFailedToLoad += OnAdFinished; interstitial.OnAdClosed += OnAdFinished; interstitial.OnAdLeavingApplication += OnAdFinished; und dann private void OnAdFinished() { SceneManager.LoadScene(mainMenu); }
  2. Ich würde jetzt einfach mal auf deinen Animationscode tippen. Den müsstest du allerdings mal posten.
  3. Moin Normals sind die Vektoren, die von der Fläche weg zeigen. Der Vektor kann extra angegeben werden, damit sie sich von den eigentlichen Normalen unterscheiden können. Eine Kugel besteht ja auch aus Flächen mit Kanten dazwischen; wenn man die Normalen allerdings alle vom Mittelpunkt wegzeigen lässt, dann wird die Lichtberechnung so beeinflusst, dass man die Kanten nicht mehr sieht. Wenn du Unity die Dinger automatisch berechnen lässt, kommt halt nicht unbedingt das raus, was du haben willst. Manchmal willst du direkt ein Array befüllen, das genau so groß ist wie das Vertex-Array und da selbstgemachte Normalenvektoren reinschmeißen. Tangenten sind da seltener ein Problem. Die Frage ist da eher, ob du sie brauchst. Die üblicheren Shader brauchen alle gar keine Tangenten. Und Bounds, da kannste nix mit falsch machen. Ist halt die AABB, also die Box, die dein Mesh umschließt, mit deren Hilfe Culling und sowas gemacht wird. Wenn du das in einem Spiel mal gesehen hast, das ein Objekt am Bildschirmrand verschwindet, obwohl es eigentlich noch im Bild ist; da waren die Bounds falsch. Richtige Bounds zu haben ist daher wichtig, und wenn dein Mesh nach dem Update eine merkbar andere äußere Form hat, dann kannst du die gerne automatisch neu berechnen lassen. Wenn nicht (wenn dein Mesh z.B. einfach nur ein bisschen wabert), dann kannst du dir die Rechenleistung aber auch sparen.
  4. Du kannst bei Instantiate Position und Rotation als zweiten und dritten Parameter mitgeben. Instantiate(coin, somePosition, someRotation);
  5. Das... klingt überaus krumm. Sowas hab ich noch nie gehört, und da fällt mir auch irgendwie nix zu ein 🤔
  6. Nice! Hallo Joa, wenn man mit einem Pointer (Maus oder Touch) damit interagieren will, muss das an sein, weil das Event System einen Raycast macht, um zu schauen, was du mit dem Pointer berührt hast. Wenn du übrigens nur mit Tastatur oder Gamepad durch das Menü navigierst, braucht's das auch nicht. Aber da kann man dann auch einfach ein eigenes EventSystem bauen, das gar nicht erst raycastet und hat die beste Performance-Ersparnis Wenn ein Ding interagierbar ist und auch Raycast Target an hat, dann solltest du da auch draufklicken können. Wenn das nicht geht, ist es am wahrscheinlichsten, dass das Ding von etwas anderem verdeckt ist. Da du hier ein Pause-Menü hast, stellt sich auch die Frage, ob du die Zeit anhältst (Time.timeScale = 0). Das kann für UI auch manchmal schlecht sein, wenn man da nicht an ein paar Schrauben dreht. Generell gilt übrigens, dass Performance nicht immer sofort optimiert werden muss. Klar, zum Lernen probiere alles mal aus. Aber es gibt so genannte "Premature Optimization". Das steht dafür, dass Arbeitszeit am Projekt unnötig verschwendet wird, um die Performance zu verbessern, obwohl diese von vornherein gar nicht schlecht war.
  7. Also, wenn die Daten vom Server kommen sollen, dann kannst du im Editor nicht gerade sinnvoll etwas einstellen. Sonst kann man gut GameObjects in der Szene verteilen, diese in ein Array packen und in der Coroutine das Array durchlaufen. Mit OnDrawGizmos kann man da noch schön Linien zwischen malen, um den Pfad zu visualisieren. Generell gilt, dass der Editor hervorragend dazu geeignet ist, kleine und große Tools und Visualisierungen einzubauen, um einen ganz eigenen, zum Projekt passenden Design-Workflow zu schaffen. Aber wie gesagt... mit Daten vom Server wird das eher schwieriger. Es klingt, als wolltest du irgendwie die Ausrichtung des Objekts irgendwo einstellen. Dabei ist es viel einfacher, wenn du einfach nur definierst, wo das Ding hinlaufen soll, und dann richtet es sich automatisch immer zum nächsten Punkt aus.
  8. Gerade bei Blender ist das bekannt. Da ist die Z-Achse ja oben, während bei Unity Y die vertikale Achse ist. Und aus irgendeinem Grund schafft Unity das nicht, dem FBX Exporter beim automatischen Export zu sagen, dass er das fixen soll. Als Resultat haben wir um -90° gedrehte importierte Objekte, damit sie richtig herum sind. Tatsächlich habe ich mal einen AssetPostProcessor geschrieben, der das reparieren soll, aber der ist nie brauchbar geworden, weil es brutal viele Sonderfälle zu beachten gibt... Wenn du dann ein solches Objekt auf eine normale Rotation setzt, die diesen Umstand nicht beachtet, dann gehen diese -90° flöten und das Objekt ist falsch ausgerichtet. Der beste Weg ist, das Objekt selber zu exportieren: https://unity3d.college/2017/07/08/fix-bad-90-x-rotation-unity3d-blender/ Wenn das aber nicht drin ist, ist es nicht unüblich, ein leeres Objekt zu nehmen, das Modell als Child mit der -90°-Drehung hinzuzufügen, und dann den Parent normal zu drehen. Ja, das kannst du, aber du kannst auch einfach einen Vector3 statt drei floats deklarieren Beides sind Repräsentationen derselben Sache. Euler-Winkel sind nur doof, weil sie "Gimbal-locken" können. Quaternions sind schwerer zu verstehen, aber ansonsten einfach nur besser. Um eine Ausrichtung im Editor einzugeben, sind Euler-Winkel in Ordnung. Aber sobald du im Code angekommen bist, wirfst du die recht schnell weg. Mit Quaterion.Euler kannst du einen Euler-Vector3 in ein Quaternion umwandeln. Aber willst du wirklich Ausrichtungen im Editor definieren? Oder vielleicht doch lieber Punkte zum Hinlaufen, und dann die Ausrichtung mit z.B. Quaternion.LookRotation errechnen lassen?
  9. Du kannst dein Canvas anders skalieren, aber die Objekte zu skalieren ist auch nicht schlecht. Nee, einfach alles in einen Parent packen und nur den Parent skalieren. Dein Ansatz ist aber schon gut, denke ich. Man kann da mit mehreren Kameras Dinge machen und so, aber so ist's schon gut simpel. Und simpel heißt, dass du weniger einfach Fehler machst.
  10. Fast richtig - es gibt hier nur eine Coroutine, die pausiert wird. "yield return null;" darf man übersetzen mit "Warte einen Frame". Du steckst einen Vektor rein und kriegst eine Rotation zurück, die ein Objekt so ausrichtet, dass es in die Richtung dieses Vektors schaut. Das hier: transform.rotation = Quaternion.LookRotation(direction); macht dasselbe wie transform.forward = direction; Da wir ja aber schrittweise da hindrehen wollen, erzeuge ich erstmal die Drehung (das Quaternion) und benutze RotateTowards, um das Objekt immer weiter dieser Rotation anzunähern.
  11. Kann ich wirklich nicht sagen, dazu habe ich zu wenig Ahnung von deinem Projekt. Allgemein sind ScriptableObjects super, um im Editor Daten in andere Objekte einzuspeisen. Z.B. welches Item eine Truhe beim looten gibt oder zu welcher Klasse von Gegenständen ein auf dem Boden liegendes Item gehört. Vielleicht ist das hier ja so ein Fall.
  12. Du hast da ein grundlegendes Problem in der Logik. Deine Anzeige ist dafür gemacht, auf das Event eines einzelnen Objekts zu reagieren. Es ist außerdem etwas ungewöhnlich, dass das UI sich bei den Objekten meldet und nicht umgekehrt. Du könntest einfach statt lauter überall verteilter Events ein einziges Event definieren. Wenn du das im UI machst, brauchst du dafür nicht einmal mehr ein Event: public class GUIDisplay : MonoBehaviour { private static GUIDisplay instance; private void Awake() { if (!instance) { instance = this; } else { Destroy(gameObject); } } public static void Refresh() { instance.DoStuff(); } private void DoStuff() { // ... } } Und dann rufst du das so auf: GUIDisplay.Refresh(); Dieses Pattern wird in Unity-Kreisen oft als "Singleton" bezeichnet, obwohl es nicht wirklich eines ist. Es hat einige Nachteile, weswegen man es auf lange Sicht meistens (wenn auch nicht immer!) vermeiden möchte.
  13. Verstehe ich das richtig - du hast mehrere ObjektInfo-Komponenten in der Szene? Dann ist das Problem klar: aktualisierungUi=FindObjectOfType<ObjektInfo>(); Das hier gibt dir eins davon zurück. Bei diesem einen fügt dein Code dann eine Reaktion auf dessen Event hinzu. Alle anderen Objekte haben danach immer noch leere Events.
  14. Warum ziehst du nicht einfach bei jedem Vertex einmal die halbe Breite und Länge von der jeweiligen Achse ab?
  15. Moin! Abläufe, wo Dinge über mehrere Frames hinweg passieren sollen, kann man wunderbar mit Coroutinen bauen. Da Coroutinen andere Coroutinen ausführen können, kannst du eine "Hinbewegen"- und eine "Drehen"-Coroutine bauen, und eine dritte Coroutine, die diese beiden immer wieder aufruft. Das könnte z.B. so aussehen: private const float ROTATE_SPEED = 90f; private const float WALK_SPEED = 2f; public float walkDistance = 10f; private void Start() { StartCoroutine(RunAround()); } private IEnumerator RunAround() { while (enabled) { yield return TurnTowards(Vector3.forward); yield return RunTowards(Vector3.forward * walkDistance); yield return TurnTowards(Vector3.left); yield return RunTowards(Vector3.left * walkDistance); yield return TurnTowards(Vector3.backward); yield return RunTowards(Vector3.backward * walkDistance); yield return TurnTowards(Vector3.right); yield return RunTowards(Vector3.right * walkDistance); } } private IEnumerator TurnTowards(Vector3 direction) { var targetRotation = Quaterion.LookRotation(direction); while (transform.rotation != targetRotation) { transform.rotation = Quaternion.RotateTowards(transform.rotation, targtetRotation, ROTATE_SPEED * Time.deltaTime); yield return null; } } private IEnumerator RunTowards(Vector3 direction) { var targetPosition = transform.position + direction; while (transform.position != targetPosition) { transform.position = Vector3.MoveTowards(transform.position, targetPosition, WALK_SPEED * Time.deltaTime); yield return null; } }
  16. Moin! Deine UV-Koordinaten sind Vielfache von 1, also 0, 1, 2, 3, ... UV-Koordinaten gehen aber nur von 0 bis 1. Vom ersten Quadrat gehen die UV-Koordinaten also von 0 bis 1, das Quadrat daneben geht von 1 bis 2. Texturen wiederholen sich normalerweise, daher zeigen beide (alle) Quadrate einmal das vollständige Bild an. Wenn du z.B. ein 10x10-Grid hast, dann müsste das erste Quadrat das erste Zehntel, das zweite das zweite Zehntel usw. anzeigen. Dann gehen alle Quadrate zusammen von 0 bis 1. Du musst also bei den UVs durch die Anzahl der Vertices auf der jeweiligen Achse teilen.
  17. Ja... im Editor. Wenn du den Play Mode startest, dann wird die geöffnete Szene entladen und wieder komplett neu geladen. Verlässt du den Play Mode, passiert dasselbe. Alle Änderungen an der Szene werden verworfen und sie wird neu von der Platte geladen. Ist ja auch sehr wichtig, sonst müsstest du nach jedem Testlauf per Hand alles auf Ausgangsposition zurücksetzen. Alle anderen Assets allerdings haben das nicht. Wenn du ein Material oder eine Textur änderst, die in den Assets liegt, dann sind die Änderungen persistent. Kannst du ja einfach ausprobieren, wenn du willst. Und deine ScriptableObjects liegen halt auch als Assets im Assets-Ordner. Dieses ganze Konzept vom Assets-Ordner gibt es aber im Build nicht mehr. ScriptableObjects sind keine einzelnen Dateien mehr, sondern nur noch Objekte, die zur Laufzeit aus den SharedAssets geladen werden. Keine. Du kannst alles und jeden speichern. Nur helfen dir ScriptableObjects dabei halt nicht.
  18. Verstehe ich das richtig, dass du ein SO benutzen willst, um Laufzeit-Daten abzuspeichern? Da kann ich ganz kurz und knapp sagen, warum das nicht geht: Weil's nicht geht. Die ScriptableObject-Klasse hat exakt null Funktionalität dafür. Wenn ich das falsch verstanden habe, sag gerne Bescheid, dann wird's vermutlich schon interessanter
  19. Keine Ahnung, hab von EasyFile noch nie was gehört
  20. Prefabs kannst du leider nicht zur Laufzeit bauen. Ergibt aber auch nicht viel Sinn, denn Prefabs sind einfach nur GameObjects, die im Assets-Ordner liegen. Den Assets-Ordner gibt's ja aber im Build gar nicht. Wenn du etwas im Spiel speichern willst, dann musst du entweder PlayerPrefs oder ein anderes Speichersystem nutzen. Die guten alten Json-/Yaml-/Sonstwas-Dateien bieten sich da immer an. Und ja, eine Liste zu haben und dann die Indizes von Objekten auf dieser Liste zu speichern kann funktionieren. String-IDs sind da aber etwas sicherer, weil die nicht kaputt gehen, wenn sich die Liste zu krass ändert.
  21. Hast du denn alles umziehen lassen? Du willst nur dabei haben: Assets/ ProjectSettings/ Packages/ und so Sachen wie Temp/ oder Library/ sollten nicht mit umziehen, sondern immer nur lokal existieren. Lösche einfach mal diese Ordner, könnte schon reichen. Wobei die von @malzbie vorgeschlagene Lösung das vielleicht sogar automatisch mit macht; keine Ahnung.
  22. Das ist zwar keine gute Idee, aber genau dafür gibt's Resources.Load. Aber warte, PrefabUtility? Das geht doch gar nicht während des Spiels? Also im Editor, ja, aber nicht im Build.
  23. Es gibt jetzt ein neues Video und noch viel mehr neues; schaut einfach mal in den ersten Post
  24. Ich glaube, du bringst da ein paar Systeme durcheinander. Ein MeshCollider ist kein UI-Element. Wenn du auf einen Collider drücken willst dann musst du von irgendwo aus einen Raycast schießen. Bei einer Anwendung auf einem normalen Bildschirm wäre das z.B. von der Kamera aus in Abhängigkeit zur Mausposition. In VR ist das alles nicht so standartisiert, da kann man entweder den Controller wie einen Laser Pointer benutzen oder in die Nähe halten. Ersteres wäre wieder ein Raycast, aber halt vom Controller aus und nicht von der Kamera, letzteres wäre z.B. mit einem Trigger am Collider zu machen. Die ganzen PointerHandler-Dinger sind für UI-Elemente da, also das, was du in einem UI-Canvas unterbringst. Das ist ein völlig anderes System, das mit Colliders nichts am Hut hat. Was allerdings sein kann ist, dass Microsoft da Interfaces von Unity schlicht zweckentfremdet und das, was du da tust, tatsächlich dem entspricht, was Microsoft vorsieht. In dem Fall müsstest du dich aber direkt bei Microsoft informieren, die haben für ihr Paket hoffentlich eine brauchbare Dokumentation.
×
×
  • Create New...