Jump to content
Unity Insider Forum

malzbie

Moderators
  • Content Count

    5,124
  • Joined

  • Last visited

  • Days Won

    357

Everything posted by malzbie

  1. Wenn du mit Sprites arbeitest solltest du immer Order In Layer vom Spriterenderer mit Zahlen bestücken. Je größer die Zahl, umso weiter vorne ist das Sprite. Egal, ob es näher an der Kamera ist oder nicht. (Oder in deinem Fall genau gleich weit weg) https://docs.unity3d.com/Manual/class-SpriteRenderer.html
  2. Also es ist so: Der Code ansich wird Zeile für Zeile abgearbeitet. Eingabesignale und Ausgaben, z.B. auf den Bildschirm, passieren Frameweise. Welcher Code wann abgearbeitet wird, hängt davon ab, welche Funktion du nutzt. In der Update Funktion wird einmal pro Frame alles von oben nach unten abgearbeitet. In der FixedUpdate wird einmal pro FixerdTime Intervall der gesammte Code abgearbeitet. Genauso ist das in OnTrigger oder OnCollision Funktionen. In jedem Script in deiner Szene können unterschiedliche Funktionen drin stehen. Die Funktionen werden alle nach gewissen Intervallen abgearbeitet. Wenn also der Update Zyklus dran ist, werden alle Update Funktionen in allen aktiven Scripts abgearbeitet. Das passiert aber nicht gleichzeitig sondern ein Script nach dem anderen. Welches Script damit anfängt, wird beim Spielstart zufällig festgelegt. Da kann man aber eingreifen und eine Abarbeitungsreihenfolge einstellen. Wärend eines Frames werden die Scripte also von oben nach unten abgearbeitet. EIn Inputsignal, steht wärend des kompletten Frames an, denn es wird auch nur einmal pro Frame ausgewertet. Somit sollten dein 3 Debugzeilen alle geschrieben werden. Aber der Output wird erst am Ende des Frames gemacht. Also quasi gleichzeitig. Solltest du beim Drücken der Taste H z.B. etwas berechnen wollen, und du hättest da auch 3 Zeilen, die untereinander stehen, dann würden alle 3 Zeilen genauso von oben nach unten abgearbeitet werden. Es geht also immer von oben nach unten. Willst du da dynamisch mal so mal so abarbeiten lassen, musst du dir Bedingungen schaffen. Dann würdest du gewisse Sachen nur dann ausführen, wenn eine bestimmte Bedingung erfüllt ist.
  3. Wenn ein GameObject in der Szene nicht aktiv ist, kann es auch nicht gefunden werden. Mach doch einfach deine panel Variable public und zieh dann das Panel im Inspector auf die nun sichtbare Variable. GameObject.Find brauchst du dann natürlich nicht mehr.
  4. Welchen Wert siehst du denn bei spawnRate im Inspector? Ich gehe davon aus, dass da keine 900 zu sehen ist. Dass es eine Rechteck- Form ist, ist ja klar. Du ermittelst ja die x und y Werte wie bei einem Rechteck. Du holst dir zufällige Werte aus einer definierten Breite und einer definierten Höhe.
  5. Das ist normal! Denk daran, dass dies Public Variablen sind. Also du das erste Mal gespeichert hattest wurde der Wert 1 beim adaptSpeed übergeben. Dies ist jetzt der Public (also der Öffentliche) Wert. Ab jetzt kannst du im Code Werte eintragen wie du willst, sie werden den public Wert nicht mehr überschreiben. Willst du den Wert ändern, dann ändere ihn im Inspector. Bei Private Variablen ist das anders, da ist wirklich nur der Wert im Code entscheidend, denn da gibt es ja nichts was von Außen geändert werden kann.
  6. Hast du in dieser Datei weiter unten auch _content=bytes drin stehen und die alten _content Einträge auskommentiert, so wie ich das oben im Bild gezeigt habe?
  7. Tja, dann musst du mal auf Fehlersuche gehen, denn bei mir funktioniert das tadellos. Als erstes musst du mal deine Bildposition überprüfen. Die Position gibt nämlich die untere linke Ecke des Bildes an. Vielleicht ist dein Bild nicht zu sehen, weil es oben aus dem Blatt herausragt. Dann setz mal ein Debug.Log in das ImageElement script. Und zwar hier: internal imageElement(Texture2D myImage, int newCoordX, int newCoordY) { MemoryStream outStream = null; try { byte[] bytes = myImage.EncodeToPNG(); // das hier ist neu um die Bytes zu bekommen. //Hier drunter Debug.Log("length: "+bytes.Length); //hier drüber outStream = new MemoryStream(); Das Debug.Log im simplePDF wo erstellt drin steht haste noch? Wenn ja, dann solltest du das ja auch sehen. Wenn du als die Szene startest, solltest du diese Dinge in der Console sehen: Wenn die length größer als 0 ist, hat er das Bild schonmal geladen und den bytes übergeben. Ja und "erstellt" sollte auch kommen, denn dann ist er fertig. Du darfst auch keine Fehlermeldung sehen.
  8. Oh ja, hab ich vergessen zu erwähnen. Du musst in dem pdfPersistentPage ganz oben noch using UnityEngine; einfügen. Die Fehlermeldung sagt das ja quasi aus. Die Coroutine newAddImage kommentierst du komplett aus. Die brauchst du nicht.
  9. So. Ich habe jetzt den vorhandenen Code soweit geändert, dass auch eine Texture2D geladen UND in die PDF eingefügt werden kann. Ich erkläre dir, was ich gemacht habe und welche Scripte alle betroffen sind. 4 Scripte müssen bearbeitet werden. 1. pdfPersistentPage.cs Hier ist, genauso wie bei pdfPages.cs, die Methode addImage zu verändern. Die Version mit Bytes muss weg ( ab Zeile 53) und die Methode mit Texture2D muss frei werden (ab Zeile 72). Ich weiß jetzt gar nicht mehr, ob da auch das Textures2D fehlte, deswegen poste ich den Abschnitt mal, wie er sein muss. public void addImage( Texture2D newImgObject, int X, int Y) { try { imageElement objImage = new imageElement(newImgObject, X, Y); _persistentElements.Add(objImage); objImage = null; } catch (pdfImageNotFoundException ex) { throw new pdfImageNotFoundException(ex.Message,ex); } catch (pdfImageIOException ex) { throw new pdfImageIOException(ex.Message,ex); } } Vergleiche einfach ob es im Code bei dir genauso steht. 2. pdfPages.cs Das war der Bereich, bei dem ich dich animieren wollte, soelbst den Fehler zu finden: public void addImage( Texture2D newImgObject, int X, int Y) { try { imageElement objImage = new imageElement(newImgObject, X, Y); _elements.Add(objImage); objImage = null; } catch (pdfImageNotFoundException ex) { throw new pdfImageNotFoundException(ex.Message,ex); } catch (pdfImageIOException ex) { throw new pdfImageIOException(ex.Message,ex); } } Da fehlte einfach nur das Texture2D in der void. 3. ImageElements.cs Hier habe ich einiges abändern müssen, da der Codeersteller versucht hatte, die Bytes des Bildes per System.Drawing zu ermitteln, was aber ga nicht geht, weil in System, gibt es kein Drawing. Ich zeige dir erstmal den Codeabschnitt und erkläre ed dir danach: internal imageElement(Texture2D myImage, int newCoordX, int newCoordY) { MemoryStream outStream = null; try { byte[] bytes = myImage.EncodeToPNG(); // das hier ist neu um die Bytes zu bekommen. outStream = new MemoryStream(); //myImage.Save(outStream,System.Drawing.Imaging.ImageFormat.Jpeg); //_content = new byte[outStream.Length]; //_content = outStream.ToArray(); _content = bytes; // das hier ist neu _height = myImage.height; // hier war ein Height mit großem H _width = myImage.width; // hier war ein Width mit großem W _coordX = newCoordX; _coordY = newCoordY; } catch (System.IO.FileNotFoundException ex) { throw new pdfImageNotFoundException("Oggetto Immagine non corretto!", ex); } catch (System.IO.IOException ex) { throw new pdfImageIOException("Errore generale di IO sull' oggetto immagine!", ex); } finally { if (outStream != null) { outStream.Close(); outStream = null; } } } Um an die Bytes zu kommen, habe ich einen Workarround genutzt. Und zwar nutze ich Texture2D.EncodeToPNG( ) dafür, wie es auch im Beispiel für WWWForm angegeben war. diese Info wird dann der _content Variable übergeben. die Variablen _height und _width wollten die werte vom myImage haben, dort wurde Width und Height jedoch groß geschrieben, was es so bei Texture2D aber nicht gibt. Da werden die Parameter klein geschrieben. Das ahbe ich also auch geändert. Ja und dann habe ich alles, was nicht funktioniert auskommentiert. Siehste ja. 4. SimplePDF.cs Hier sind die letzten Zeilen des Codes wichtig (ab Zeile70). Ursprünglich wurde ja die Coroutine myFirstPage.newAddImage() gestartet. Das hatten wir ja gestern schon auf den direkten Start von myFirstPage.addImage() geändert. Jetzt habe aber heute erst gesehen, dass dieser ganze Code in einer Coroutine drin steht und eine Coroutine wartet immer auf etwas und will gerne was zurückgeben. Das tut sie mit dem yield return. Damit das jetzt hier ohne weiteren Umbau des Codes funktioniert, habe ich einfach auf die testgrafik an sich warten lassen. Hier der veränderte Code : var testgrafik = Resources.Load<Texture2D>("Picture1"); myFirstPage.addImage(testgrafik, 100, 500); // hier wird nur die Grafik und die Position im PDF übergeben yield return testgrafik; // da das ne Coroutine ist, muss auch auf was gewartet werden //yield return StartCoroutine ( myFirstPage.newAddImage ( "FILE://picture1.jpg",2,100 ) ); myDoc.createPDF(attacName); myTable = null; Debug.Log("erstellt"); Ein Hinderniss gibt es jetzt noch: Die Grafiken, die im Resources Ordner drin liegen, müssen in den Importeinstellungen auf Read/Writ Eabled gestellt werden und sie dürfen nicht Komprimiert sein. Nur so, kann er die Bytes auslesen. Siehe Bild: Jetzt solltest du es auch hinkriegen. Ich habs jedenfalls im Editor und im Build getestet und bei mir geht's.
  10. Och nö! Du musst versuchen zu verstehen, was da passiert. Es ist zwar toll, wenn es vorgefertigte Dinge gibt, die man nutzen kann, aber sobald man etwas verändern will/muss, muss man den Code auch verstehen. Worauf ich hinaus wollte, ist der fehlende Typ von newImageObject. Und zwar muss der ja auch Texture2D sein. Wenn du eine Methode aufrufst und ihr auch irgendetwas übergeben willst, dann muss die Methode so angelegt sein, dass klar ist was für Typen da kommen und in welche Variable sie gespeichert werden. Also: public void addImage( Texture2D newImgObject, int X, int Y) Trotzdem hast du Recht. Der auskommentierte Code ist fehlerhaft. PDF Elemente werden scheinbar nur als Stream abgespeichert, also Byteweise. Tja, und da wäre für dich noch Einiges zu tun. Ich habe aber scheinbar ne Lösung für das Problem gefunden. Ich melde mich gleich nochmal.
  11. Wenn du dir die Zeile public void addImage( newImgObject, int X, int Y) mal anschaust und zwar ganz genau auf die drei Dinge, die da übergeben werden sollen, was fällt dir da auf? Die Fehlermeldung sagt dir übrigens, dass da ein unerwartetes Symbol auftaucht, nämlich das Komma. Warum ist das unerwartet? Weil da etwas wichtiges fehlt! Das Komma sollte nämlich noch gar nicht kommen. Hast du's erkannt? was ist denn newImageObject? Ich meine bei X und Y ist klar was sie sind. Nämlich int Typen. newImageObject ist aber irgendwie garnix, oder? Da liegt der Fehler!
  12. Ich habe mir das Package mal angeschaut und was bemerkt. Pass auf: Es gibt da 2 entscheidende Scripts. Einmal das pdfPage Script und dann das imageElement Script. Im pdfPage so bei Zeile 128 ist die Methode addImage versteckt. Da siehst du , dass adImage gewisse Dinge übergeben haben will. Wie eben auch den String. Wenn du aber mal runter scrollst, siehst du , dass der Ersteller des Scripts, jede Menge weitere addImage Methoden erstelt hat, die aber alle auskommentiert sind. Bei Zeile 154 gibt es eine Methode, die keinen String erwartet, sondern ein ImageObject. Diese Methode bräuchtest du und die andeer ( die mit den String) müsstest du dafür auskommenteren. Damit das Funktioniert musst du so ähnlich bei dem imageElement Script etwas verändern. Dort erwartet imageElement die Bytes, die vom WWW herkommen würden. Weiter unten, bei Zeile152, ist aber eine andere Art vorhanden, die eben eine Texture2D will. Das ist genau das was wir wollen!!! Also auch hier den oberen Internal auskommentieren und den bei Zeile 152 freigeben. Jetzt musst du nur noch den Aufruf verändern. Du rufst ja momentan noch die Coroutine newAddImage auf, die über WWW ein Bild einlädt. Und wenn's geladen ist, ruft sie wiederum addImage auf um die Bytes zu übergeben. Da du aber keine Bytes mehr hast, sondern direkt eine Texture2D die ja in der Varibale testgrafik gespeichert ist, kannst du direkt das addImage aufrufen. Eine Wartende Coroutine brauchst du nicht mehr. myFirstPage.addImage(testgrafik,X,Y); // hier wird nur die Grafik und die Position im PDF übergeben So sollte das gehen. Testen werde ich es nicht, da mir son bisschen die Zeit fehlt.
  13. Zeig ersteinmal, was in der Funktion addImage passiert. Dir muss klar sein, dass ich nicht wissen kann, was in irgendwelchen Funktionen passiert und somit kann ich auch nicht sagen, wie dein Format sein muss. Ich weiss jetzt schon einmal, dass in der Coroutine WWWForm genutzt wird um das Bild irgendwo her zu laden. Das geht natürlich nur, wenn dieser Pfad und die entsprechende Dateien da drin auch zugänglich sind. Das ist bei einem Build mit dem Ressources Ordner aber nicht der Fall. Es gibt zwar diesen Ordner in deinem Build, aber nicht die Datei so wie du sie gerne hättest. Sollen die User bei deinem Projekt auch eigene Bilder nutzen können, oder sollen es nur die Bilder sein, die du vorgegeben hast und die in deinem Build schon drin sind? Das wäre wichtig zu wissen, denn wenn der User da auch eingene Bilder nutzen will, musst du eh irgendwie mit Ordnern außerhalb des Builds arbeiten. Dann wärre WWWform auch ganz toll. Wenn nicht, dann stellt sich die Frage, ob du WWWForm überhaupt brauchst und in was denn die Bytes codiert werden. Als was passiert da in der addImageFunktion, in die die Bytes rein geschoben werden?!
  14. So machste das: using System.Collections; using System.Collections.Generic; using UnityEngine; public class grafiktest : MonoBehaviour { public Material myMat; Texture2D testgrafik; void Start() { testgrafik = Resources.Load("grafiken/testgrafik") as Texture2D; myMat.mainTexture = testgrafik; } } In diesem Beispiel liegt das Script auf einer Plane. Im Inspector ziehe ich das Material in den Slot des Scripts. Das Mat könnte jetzt schon irgendeine MainTextur haben, oder auch nicht. Ist egal. Die Textur ist als default Grafik in Unity inportiert worden. Und der Pfad ist Resources/grafiken/ und genau das siehst du ja in der Zeile wo ich die Testgrafik Variable vom Typ Texture2D mit Ressources.Load bestücke. Natürlich kannst du das auch mit einem Sprite machen oder einer Textdatei. Du braucht eine Variable vom gewünschten Typ und lädst diese mit Resources.Load als gleichen Typ ein. Oder aber du machst das so wie in den Beispielen, dass du von vonherein gar keine Variable deklarierst, sondern in irgendeiner Funktion/Methode ein undefinierte Variable nutzt. Diese Variable wird dann zu dem Typ, den du übergeben hast. var testgrafik2 = Resources.Load("grafiken/testgrafik")as Texture2D; Und natürlich kannst du auch in beiden Wegen das Resources.Load mit den Spitzklammern <typ> nutzen. testgrafik = Resources.Load<Texture2D>("grafiken/testgrafik") ; oder var testgrafik2 = Resources.Load<Texture2D>("grafiken/testgrafik") ; In deinem Script ganz oben rufst du ja eine Coroutine auf wo du auch gleich das Bild mit zusätzlichen Werten lädst. Das Laden brauchst du jetzt nicht mehr, denn die Grafik ist ja schon in der Variable drin. Du musst also die Variable an die Coroutine übergeben. Soweit klar?
  15. Ja klar, warum nicht. Wenn du willst, dass die Bilder auch nach dem Builden zugänglich sein sollen, dann ist der Streaming Ordner besser. Willst du das aber nicht, dann nutze den Ressources Ordner.
  16. Erzeuge mal einen Ordner namens Resources und leg da deine Bilder rein. Diese Bilder kannst du dann mittels Resouces.Load<Texture2D> laden und einer Variable übergeben. Schau hier: https://docs.unity3d.com/ScriptReference/Resources.Load.html
  17. Ja, da hat der MaZy recht! Aber mal zu dem, was du da im Code machst: Du arbeitest da einige Zeilen COde in der OnTriggerStay Funktion ab, unteranderem auch das Intsanzieren der Kugeln. OnTriggerStay wird "nicht" einmal per Frame abgearbeitet, sondern einmal pro FixedTime. Das ist ein Zyklus, der Unabhängig von der Update Funktion ist. Je nach eingestelltem FixedTime Wert und deiner Maximalen Framerate kann das ofter oder auch weniger oft als einmal in Frame sein. Ich weiß, das hilft jetzt erst einmal nicht viel weiter. Ich wollte dir damit nur mal sagen, dass nicht alles einmal pro Frame passiert. OnTriggerStay wird solange aufgerufen, wie das Objekt in dem Trigger drin steckt. Das ist gut, wenn das Objekt genauso lange etwas machen soll. Das Ermitteln der Blickrichtung passt da ganz gut. Damit die Bullets jetzt in einem ganz anderen Zyklus instanziert werden, musst du eigentlich nur wissen wann du in den Trigger drin bist. Ja, und damit das wieder aufhört, musst du wissen, wann du wieder da raus gegangen bisst. Dafür eignet sich Stay nicht so gut, weill da bekommst du nur die Eigenschaft, dass man im Trigger drin ist. Nutze also OnTriggerEnter() für das Setzen einer Variable, die dir sagt, dass man im Trigger drin ist. Und nutze OnTriggerExit() für das Zurücksetzen der Variable. Diese Variable wird quasi als Schalter genutzt und in einer Bedingung abgefragt. Du willst in einem bestimmten Intervall schießen, also brauchst du eine Variable, die diesen Intervall definiert. Das ganze muss nun mit der SpielZeit verknüpft werden und dafür brauchst du noch eine dritte Variable, die das AbJetzt definiert. Das sind deine 3 Variablen: private bool canShoot=false; public float shootIntervall=1f; private float intervallStartTime=0f; Sobald du im Trigger bist, soll canShoot auf true gesetzt werden, und sobald du den Trigger verlässt soll canShoot wieder false werden. void OnTriggerEnter(){ canShoot=true; } void OnTriggerExit(){ canShoot=false; } Und damit intervallmäßig geschossen wird musst du in der Update() etwas eintreten, damit das so passiert: if (canShoot && intervallSartTime + shootIntervall <= Time.time){ // kugel instanzieren GameObject bullet0 = Instantiate(bullet, transform.position, transform.rotation); // intervall Startzeit auf jetzt setzen intervallStartTime = Time.time; // und so weiter } Du siehst, dass nur dann die Bedingung erfüllt ist, wenn canShoot true ist und die Intervall Startzzeit plus die IntervallZeit kleiner oder gleich der jetzigen Zeit ist. Wenn die Bedingung erfüllt ist wird einmalig instanziert und die Intervall Startzeit wird auf "jetzt" gestellt. Das bedeutet, dass hiernach die Bedingung fürs Schießen ersteinmal nicht erfüllt ist. Denn die Startzeit plus die Intervallzeit ist jetzt größer als die Spielzeit. Nach der Intervallzeit ist das dann wieder vorbei und es kann wieder instanziert werden. Man kann sowas auch mit einer Coroutine machen, die eine Zeit lang wartet, bis sie etwas tut. Das ist aber ersteinmal egal, weil du willst das Grundlegende wissen. Ach so, ich bin 51.
  18. Hey! Danke dass du den Flipper mal getestet hast. Das mit der angeblichen Verzögerung war nur ganz am Anfang, also November 2017. Und das hatte 3 Gründe: als Hauptproblem ist ein Haken im Steam Manager auszumachen der was mit irgendwelchen Joystickfunktionen zu tun hat. Ich habe immer noch nicht so ganz raus was der macht, aber nachdem ich den Haken rausgenommen hatte, waren 90% der Probleme behoben. Das ist komischerweise nur bei einigen Leuten aufgetreten und hat irgendwie mit dem Big Picture zu tun. Die restlichen 10% kamen nur bei Leuten vor, die mit billigen Notebooks und einfacher Intel-Grafikkarte gespielt hatten. Da konnte ich auch noch etwas raus holen, als ich die Inputs in der FixedUpdate, anstatt der Update abgefragt hatte. Wenn so eine Bewertung einmal steht, geht sie nie mehr weg, selbst nach fixen des Problems. Damit muss man leben. Hätte ich diesen Anfängerfehler nicht gemacht, hätte ich ne Rate von über 90% positiv. So habe ich nur 73% aber das ist auch schon ok. Da sich meine Flipper an die 90er orientieren, habe ich den Federabzug nicht eingebaut. Die Flipper aus der Zeit hatten das genauso gehabt. Da gab es nur noch ne handvoll Tische mit Federabzug alle anderen hatten magnetische Abschüsse. Das braucht man eh, wenn man mehrere Kugeln ins Spiel bringen will, ohne sie alle vorher in irgendwelche Löcher zu deponieren. Du kannst alle Tische ohne Kauf probespielen. Sind also schon alle vorhanden. Ab einer gewissen Punktzahl wird dann aber das Spiel beendet. Wenn dir ein Flipper gefällt, kaufst du ihn einfach. Beim nächsten Spielstart ist der Flipper dann freigeschaltet. Alles total fair. Ich bin inzwischen hauptberuflich als Spieleentwickler unterwegs. Aber ja, die Idee zum Flipper und die ersten Bauten kamen schon vorher, als ich das nur als Hobby betrieben hatte. Hab Spaß!
  19. Ja, aber .Play() und .PlayOneShot() zusammen machen Probleme. Außerdem kannst du die Sounds nicht unterschiedlich modifizieren (z.B. in der Lautstärke) weil es eben nur eine Quelle ist. Deswegen einfach 2 Komponenten rein und gut ist's. Übrigens: Das gute alte PlayClipAtPoint gibt es ja auch noch. Da wird zwar jedes Mal ein SoundObjekt instanziert, aber das ginge super in seinem Spiel. Aber auch das habe ich ihm auch nicht angepriesen.
  20. Wenn du mehrere AudioSources an einem Gameobject nutzen möchtest, weil eines vielleicht einen Dauerton abspielt und ein anderes immer nur manchmal einen Ton abspielt, dann musst du im Script eben genausoviele Referenzen bilden, wie du auch Soundsources hast. Dafür erzeugst du mehrere Public Variablen vom Typ AudioSource und ziehst dann die Audiosources im Inspector in die entsprechenden Variablenfelder rein. public AudioSource LoopSound; // entsprechende AudioSource Komponente im Inspector reinziehen public AudioSource HitSound; Wenn den Audiosources jetzt jeweils schon eine eigene SoundFile hinzugefügt wären, könntest du die jetzt je nach Ereignis steuern. Also starten, stoppen, in der Lautstärke verändern usw. Den LoopSound könntest du schon in der Start() starten, aber eben noch auf stumm schalten. In der Update() würdest du dann evtl. die Lautstärke je nach Geschwindigkeit anpassen. private float volu; // Diese Variable wird für die Lautstärke benötigt. private float speed; // die Geschwindigkeit deines RB'Ss. void Start(){ LoopSound.loop = true; // falls der Haken nicht gesetzt war, setze ich ihn hier Loopsound.volume=0f; // erstmal auf stumm schalten Loopsound.Play(); // der Sound wird jetzt gestartet } void Update(){ speed = myRB.velocity.magnitude; if(speed>20f){ speed=20f; // maximaler Speed } volu=speed / 20; // durch den maximalen Speed teilen, damit die Lautstärke bei max Speed auch maximal 1 beträgt if(speed < 1.2f){ // nur wenn speed groß genug ist, soll der Sound zu hören sein volu=0f; } Loopsound.volume=volu; //Wert übergeben } Um jetzt einen HitSound abzuspielen, also in deinem Fall die andere Audiosource zu starten, musst du einfach nur mit .Play() der Audiosource sagen, dass sie spielen soll. Ist der Soundclip fertig gespielt stoppt er automatisch, sofern die Audiosource nicht auf auf Loop gestellt ist. Und natürlich kannst du auch je nach Gegebenheit unterschiedliche Clips abspielen. Natürlich musst du für die Clips auch Variablen haben und die Clips müssen auch im Inspector den Variablen zugewiesen worden sein. public AudioClip HitSoundNormal; // im Inspector die Sound Files rinlegen public AudioClip HitSoundExtrem; void OnCollisionEnter(Collision other){ if(other.collider.CompareTag("wall"){ // bei einer Wand wird der normale Sound etwas leiser abgespielt HitSound.clip = HitSoundNormal; HitSound.volume = 0.5f; } else{ // alle anderen Kollisionen machen richtig krach Hitsound.clip = HitSoundExtrem; Hitsound.volume = 1f; } Hitsound.Play(); }
  21. malzbie

    HoverBikeArcade

    Das ist schon schick! Dein Männchen müsste jetzt noch ein wenig interagieren. Z.B. sich etwas zusammenstauchen, wenn der Hoover beim Fallen abbremst oder eine schräge hoch geht. Genauso könnte sich das Männchen auch strecken wenn der Hoover von oben runter fällt. Ich weiß, es it ja kein richtiges Fallen. Ja und den Kopf könnte es auch ein wenig gegen die Lenkrichtung bewegen, wenn die Seitkräfte recht stark sind.
  22. Unity packt sich die Spritesheets nochmal neu, bevor die Szene im Editor startet. Das kann dann etwas dauern. Wenn du ein Build erstellst, wird das gepackte gleich mit ins Build geschoben und die Wartezeit, die du im Editor hattest, ist dann weg.
×
×
  • Create New...