Jump to content
Unity Insider Forum

malzbie

Moderators
  • Content Count

    5,107
  • Joined

  • Last visited

  • Days Won

    354

malzbie last won the day on March 12

malzbie had the most liked content!

Community Reputation

1,563 Excellent

2 Followers

About malzbie

  • Rank
    Moderator
  • Birthday 10/30/1968

Profile Information

  • Gender
    Male
  • Location
    Kassel, Hessen, Deutschland

Recent Profile Visitors

21,659 profile views
  1. 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.
  2. 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
  3. 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.
  4. 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ß!
  5. 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.
  6. 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(); }
  7. 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.
  8. 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.
  9. Global Illumination ist ja ein Beleuchtungsmodell, bei dem es primär nicht um das Beleuchten über echte Lichter geht, sondern eben das Aufnehmen von reflektiertem Licht oder einem selbstleuchtenden Material. Licht wird von einer Lichtquelle oder einem selbstleuchtenden Material abgegeben und trifft dabei auf ein Objekt. Je nach Materialeigenschaften des Objektes wird ein Teil des Lichtes reflektiert und bekommt von dem Material eine Färbung. Dieses nun eingefärbte Licht trifft dann wiederum auf ein anderes Objekt (falls es im Reflektionswinkel des Lichts liegt) und dieses wird mit der reflektierten Lichtfarbe und Intensität beleuchtet. Das neue Objekt würde nun auch wieder reflektieren und einfärben und weitere Objekte beleuchten. Jede Reflektion würde immer schwächer werden, aber trotzdem zur Grundhelligkeit beitragen. Und das könnte ewig so weiter gehen. Das steuerst du Bounces. Das ist natürlich extrem rechenintensiv. Vorallem, weil die Materialeigenschaften da mit eingebunden werden. Z.B. NormalMaps, die eine Unebenheit im Material simulieren. Diese Simulation ist ja auf das Licht bezogen und würde auch das Licht unterschiedlich reflektieren. Realtime GI ist etwas besonderes, denn normalerweise kann man GI nicht so schnell berechnen, dass du da mit 60fps fahren kannst. Du würdest noch nicht einmal 1fps hinbekommen. Damit das geht, werden gewisse Dinge vorberechnet und dann wird natürlich etwas gefaked. Wie das alles funktioniert, kann ich nicht sagen. Es werden aber UV Maps angelegt, über die dann ganz schnell ermittelt wird, wo Licht von welcher Seite auftrifft. Das geht natürlich über die Normalen deines Objektes, denn Unity muss ja wissen, in welche Richtung eine Fläche zeigt. Die UV Maps werden scheinbar für die Vorberechnung in kleinere Stücke zerlegt. Ja und das kannst du mit dem Ignore Normals wohl ausschalten. Ich vermute, dass dadurch sichtbare Beleuchtungsfehler entstehen können, aber dadurch die Vorberechnung beschleunigt wird. Kann aber auch anders herum sein! Jetzt ist Realtime GI aber veraltet und wird bald durch den Progressive Lightmapper ersetzt. https://blogs.unity3d.com/2019/07/03/enlighten-will-be-replaced-with-a-robust-solution-for-baked-and-real-time-giobal-illumination/ Also würde ich mir da jetzt keine großen Gedanken machen. Realtime GI zieht auch ganz schön Leistung, egal ob da eine dynamische Lichtquelle im Raum ist, oder nicht. In deiner offenen Szenerie würde ich das sowieso nicht nutzen.
  10. Ich glaube ich weiß, was die Frage ist. Unity kann nicht nur 0-360° es sind auch Winkel über 360° möglich. (Das geht natürlich auch ins negative) Wenn du immer nur 0-360° haben willst, dann musst du den entsprechenden Winkel abfragen und sobald er 360° oder mehr hat, ziehst du einfach 360° von ihm ab und übergibst den neuen Wert der Transformkomponente.
  11. Na, das ist doch schon mal was. Das mit dem Gamepad findest du auch noch raus. Kannst dir ja auch da mal die Controller-Werte ausgeben lassen um zu sehen, wann und warum es da aussetzer gibt. Zeit ist immer so eine Sache und ich finde gut, dass du Verständniss dafür hast. Ich habe nämlich momentan kaum Zeit.
  12. In deinem Codeausschnitt kann man leider nicht erkennen, wann du nach dem Objekt suchst. Wird die entsprechende Methode überhaupt aufgerufen? Hat denn dein Gameobject überhaupt den Tag mit besagtem Namen? Wenn das Objekt nicht gefunden wurde, bleibt die Variable null und du solltest eigentlich eine Fehlermeldung sehen, sobald du versuchst auf die Referenz zuzugreifen, denn es gibt ja keine Referenz. Du solltest deine Methode nicht SetActive nennen. Gib ihr einen eindeutigen Namen, der klar macht, dass es einen Methode/Funktion von dir ist und nicht von Unity. Das kann problematisch sein oder wenigstens zu Verwechselungen führen.
  13. Ich will's dir mal erklären, denn du hast da 2 große Fehler drin. Um festzulegen, wie weit dein Ding sich neigen darf, muss einmalig ein Grundwinkel ermittelt werden. Das ist der Winkel, der anliegt, wenn sich noch nichts neigt. Dafür wird eine Variable vom Tpy Vector3 gebraucht und die wird curRot genannt. Die momentanen 3 Winkel deines Dings, werden nun in dieser Variable gespeichert. curRot = this.transform.eulerAngles; Die beiden maximalen Neigungswinkel werden jetzt auch einmalig ermittelt und dafür wird maxTiltAngle genutzt. maxX = curRot.x + MaxTiltAngle; minX = curRot.x - MaxTiltAngle; Dafür wird nur der gespeicherte Wert der X Achse, aus deiner Vector3 Variable curRot genutzt. Dieser Wert plus dem Maximalwert wird der Variable maxX übergeben und der Wert minus dem Maximalwert wird maxY übergeben. Damit sich etwas ändert, muss natürlich von irgendwo ein Wert her kommen. Bei dir kommt der Wert von Input.GetAxis("lean_fb") Der Werteumfang bei GetAxis geht von -1 über die 0 zu +1. Wenn du nur leicht nach rechts lenkst, wird es irgendein Wert zwischen 0 und +1 sein, z.B. 0.3f. Diesen Wert mutliplizierst du mit der deltaTime ( was soviel wie Wert pro Sekunde bedeutet, aber in Wirklichkeit die Verstrichene Zeit zwischen 2 Frames ist) und multiplizierst ihn nocheinmal mit dem tiltSpeed. Es ist also sowas: 0.3f *0.1f*30f und das wäre 0.9f. Das bedeutet, in diesem Zyklus soll sich das Ding um 0.9° neigen. Damit es das tut, muss der ermittelte Wert natürlich auch deinem Ding übergeben werden. Das wird aber am Schluß erst gemacht. Denn wir wollen mit diesem Wert ja den momentanen Wert verändern. Aber das auch nur, wenn wir nicht schon unseren maximalen Neigungswinkel rechts oder links erreicht haben. Dafür müssen diesen Wert dem curRot.x hinzufügen bzw. abziehen, kurz überprüfen, ob dieser Winkel noch im Rahmen ist und ihn dann komplett mit allen anderen vorher gespeicherten Achsen übergeben. Damit der Neigungswinkel nicht unsere Maximalwinkel über- oder unterschreitet, gibt es die Mahtf.Clamp Funktion. Clamp ist englisch für einklemmen und Mathf.Clamp überprüft jetzt den curRot.x Wert und schaut ob er zwischen maxX und minX liegt. tut er es, wird nichts geändert. Liegt er über maxX, wird er zu maxX, liegt er unter minX wird er zu minX. Das ist alles. Jetzt, am Schluß, der Berechnung werden alle Winkel von deinem Ding mit den Werten von curRot überschreiben. Dein Ding ist also jetzt sofort etwas geneigt. Verändert wurde jetzt aber nur der Wert der x Achse, die andern beiden Achsen haben wir ja nicht verändert. Jetzt zu deinem Fehler: Du hast versucht ein vorhandenes Script umzuschreiben und hast dafür den Variablennamen curRot in curRotF umbenannt. Diesem curRotF übergibst du zwar die Werte von deinem Transform, aber im weiteren Verlauf nutzt du curRot ohne das F ! Da es in dem Script, was ich hier sehe, aber keine Deklaration von curRot gibt, müsstest du eigentlich Fehlermendungen bekommen, denn man kann nichts beschreiben, was nicht bekannt ist. Aber vielleicht hast du auch nicht alle Zeilen gepostet und es gibt in deinem Script noch auch ein curRot. Dann wäre aber das Problem, dass du den x Wert von curRot änderst, aber eben nicht von curRotF! curRotF verändert sich somit nicht und somit siehst du auch keine Änderung. Ein weiteres Problem sehe ich darin, dass du in jeder Update die Winkel dem curRotF übergibst und die Maximalwinkel neu ermittelst. Das würde bedeuten, dass sich nach einer Neigung auch der Maximalwinkel verschiebt und somit dein Ding eben nicht aufhört zu rotieren. In dem angehangenen Script ist das auch so ähnlich und meiner Meinung nach wird das nicht funktionieren. Wenn du deine Fehler beseitigt hast, könntest du eigentlich auch 2 Winkel gleichzeitig bearbeiten. curRot ist ja ein Vector3, wo alle deine 3 Winkel drin sind. Du kannst also mittels deiner InputAxis curRot.x und curRot.z direkt hintereinander verändern. Brauchst da natürlich Variablen für die Maximale von x und von z. Beides wird verändert, beides wird eingeklemmt und dann zusammen wieder der Transform Komponente übergeben.
  14. Hi. Meine Pinball Collection ist komplett: Ich arbeite eigentlich nicht mehr dran. Und da auch keine Bugs mehr auftauchen (jedenfalls meldet niemand etwas), habe ich schön Zeit um mich meinem neuen Projekt zu widmen. Was das ist , werde ich demnächst mal posten.
  15. Alles zählt! Soviel ich weiß, gibt es keine Listenansicht der Materialien und Texturen.
×
×
  • Create New...