Jump to content
Unity Insider Forum

Rakete abfeuern


brilzi89

Recommended Posts

Hallo zusammen,

bin neu in der Welt von Unity und dem Programmieren, und versuche es durch Videos und Bücher zu erlernen.

Momentan versuche ich mit der Hilfe von einem Unity video ein Spiel zu erstellen. Doch seit 2 Tagen hänge ich an einer Stelle fest und komme nicht weiter.

Nun zum Problem:

Wenn ich die Scene starte funktioniert alles soweit wie es soll. Nur wenn ich die Rakete abfeuere, fliegt die durch alles durch ohne zu Explodieren, und die Tankexplosionaudio wiederholt sich nach dem schuss ständig. Habe alles wie im Video gemacht, trotzdem habe ich dieses Problem. Hier der Link zum Video.

Könnte mir vll jemand helfen?!

Danke im vorraus:)

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,
sehe leider kein Videolink. 

Ich kann hier nur Vermutungen anstellen, da ich ja das Video ja nicht sehen kann. Damit die Rakete mit etwas kollidieren kann, braucht deine Rakete einen Rigidbody und einen Collider. Zudem brauchen die Objekte mit denen deine Rakete kollidieren können soll ebenfalls einen Collider. Zusätzlich braucht deine Rakete nun noch ein entsprechendes Skript, welches die Explosion bei einer Kollision auslöst:

using UnityEngine;
using System.Collections;

 // Die Rakete braucht einen RB und einen Collider (non-Trigger).
 // Diese Klasse sollte an der bereits abgeschossenen Rakete (die Rakete bewegt sich bereits über eine wirkende Kraft auf ihren RB) hängen.
 // "explosionPrefab" ist das Prefab für eine Explosion (inklusive AudioSource mit "Play on Awake" aktiviert und entsprechendem Soundclip)
 // "explosionPrefab" braucht noch ein Skript, damit es sich später selbst zerstört oder man baut es in dieses Skript ein (habs schon angedeutet)
public class RocketProjectile : MonoBehaviour
{   
   public GameObject explosionPrefab;
 
   // Wird bei einer Kollision mit einem anderen Collider ausgelöst
   // Es wird "explosionPrefab" am Kollisionspunkt gespawnt und das Projektile wird zerstört
   void OnCollisionEnter(Collision collision) {
      ContactPoint contact = collision.contacts[0];
      Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);
      Vector3 pos = contact.point;
      GameObject explosion = Instantiate(explosionPrefab, pos, rot);
      Destroy(gameObject);
      // Destroy(explosion, 2.0f); 
   }

}


Das "Tankexplosionsaudio" solltest du erst dann abspielen (per Skript siehe oben), wenn die Kollision erfolgt. Wenn du diesen Audioclip einfach ans explosionsPrefab hängst (und nicht an die Rakete selbst), dann wird der Sound auch erst abgespielt, wenn die Kollision erfolgt ist (bei der AudioSource bei "Loop" Haken raus und bei "Play On Awake" Haken setzen).

Link zu diesem Kommentar
Auf anderen Seiten teilen

oh sry hier der link https://www.youtube.com/watch?v=_In3KT97aTw

Rigidbody ist vorhanden so wie die Collider

hier der script

using UnityEngine;
using UnityEngine.UI;

namespace Complete
{
    public class TankShooting : MonoBehaviour
    {
        public int m_PlayerNumber = 1;              // Used to identify the different players.
        public Rigidbody m_Shell;                   // Prefab of the shell.
        public Transform m_FireTransform;           // A child of the tank where the shells are spawned.
        public Slider m_AimSlider;                  // A child of the tank that displays the current launch force.
        public AudioSource m_ShootingAudio;         // Reference to the audio source used to play the shooting audio. NB: different to the movement audio source.
        public AudioClip m_ChargingClip;            // Audio that plays when each shot is charging up.
        public AudioClip m_FireClip;                // Audio that plays when each shot is fired.
        public float m_MinLaunchForce = 15f;        // The force given to the shell if the fire button is not held.
        public float m_MaxLaunchForce = 30f;        // The force given to the shell if the fire button is held for the max charge time.
        public float m_MaxChargeTime = 0.75f;       // How long the shell can charge for before it is fired at max force.


        private string m_FireButton;                // The input axis that is used for launching shells.
        private float m_CurrentLaunchForce;         // The force that will be given to the shell when the fire button is released.
        private float m_ChargeSpeed;                // How fast the launch force increases, based on the max charge time.
        private bool m_Fired;                       // Whether or not the shell has been launched with this button press.


        private void OnEnable()
        {
            // When the tank is turned on, reset the launch force and the UI
            m_CurrentLaunchForce = m_MinLaunchForce;
            m_AimSlider.value = m_MinLaunchForce;
        }


        private void Start ()
        {
            // The fire axis is based on the player number.
            m_FireButton = "Fire" + m_PlayerNumber;

            // The rate that the launch force charges up is the range of possible forces by the max charge time.
            m_ChargeSpeed = (m_MaxLaunchForce - m_MinLaunchForce) / m_MaxChargeTime;
        }


        private void Update ()
        {
            // The slider should have a default value of the minimum launch force.
            m_AimSlider.value = m_MinLaunchForce;

            // If the max force has been exceeded and the shell hasn't yet been launched...
            if (m_CurrentLaunchForce >= m_MaxLaunchForce && !m_Fired)
            {
                // ... use the max force and launch the shell.
                m_CurrentLaunchForce = m_MaxLaunchForce;
                Fire ();
            }
            // Otherwise, if the fire button has just started being pressed...
            else if (Input.GetButtonDown (m_FireButton))
            {
                // ... reset the fired flag and reset the launch force.
                m_Fired = false;
                m_CurrentLaunchForce = m_MinLaunchForce;

                // Change the clip to the charging clip and start it playing.
                m_ShootingAudio.clip = m_ChargingClip;
                m_ShootingAudio.Play ();
            }
            // Otherwise, if the fire button is being held and the shell hasn't been launched yet...
            else if (Input.GetButton (m_FireButton) && !m_Fired)
            {
                // Increment the launch force and update the slider.
                m_CurrentLaunchForce += m_ChargeSpeed * Time.deltaTime;

                m_AimSlider.value = m_CurrentLaunchForce;
            }
            // Otherwise, if the fire button is released and the shell hasn't been launched yet...
            else if (Input.GetButtonUp (m_FireButton) && !m_Fired)
            {
                // ... launch the shell.
                Fire ();
            }
        }


        private void Fire ()
        {
            // Set the fired flag so only Fire is only called once.
            m_Fired = true;

            // Create an instance of the shell and store a reference to it's rigidbody.
            Rigidbody shellInstance =
                Instantiate (m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;

            // Set the shell's velocity to the launch force in the fire position's forward direction.
            shellInstance.velocity = m_CurrentLaunchForce * m_FireTransform.forward; 

            // Change the clip to the firing clip and play it.
            m_ShootingAudio.clip = m_FireClip;
            m_ShootingAudio.Play ();

            // Reset the launch force.  This is a precaution in case of missing button events.
            m_CurrentLaunchForce = m_MinLaunchForce;
        }
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dir fehlt vermutlich die Shell-Prefab, da hängen noch einmal Skripte, Sound und ein Partikelsystem dran. Du hast quasi hier nur das Skript für den Raketenlauncher gepostet. Die Prefab muss an das Launcher-Skript übergeben werden.

Hier ist das Video wie man dieses Prefab erstellt:
https://unity3d.com/de/learn/tutorials/projects/tanks-tutorial/shell-creation?playlist=20081

Dieses Prefab hat einen Trigger-Collider + RB und sorgt damit für die Explosion bei der Kollision des Projektiles (=Shell-Prefab). Wenn diese Rakete mit nichts kollidiert, dann hast du das Prefab falsch erstellt bzw. keine Objekte mit einem Collider in der Szene.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 36 Minuten schrieb brilzi89:

einen Shell prefab habe ich erstellt, genau so wie in dem Video. Die objekte in der Map haben alle einen Collider :/ hmm

Schau halt mal, ob du auch wirklich Shells verschiesst, die sollten in der Szene erzeugt werden und auch herumfliegen.

Ansonsten im Skript welches an der Shell hängt, ist folgende Methode wichtig (zudem muss die Shell einen RB besitzen und einen Collider mit Trigger gesetzt):

private void OnTriggerEnter(Collider other) 
{
  print("Was getroffen: " + other.gameObject.name + "!"); // Diese Zeile hinzufügen

}

Hier mal die Debugausgabe ergänzen und schauen ob du überhaupt irgendwas triffst ...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kann es sein, dass dein Objekt sehr schnell ist? Schnelle Dinge sollte man nicht unbedingt mit Rigidbodys machen. Die können nämlich erst einmal nicht ihren Weg checken, sondern teleportieren sich in festen Zeitschritten immer ein Stück weiter. Der Zeitschritt ist die FixedUpdate-Zeit, also standardmäßig 0.02 Sekunden.

Wenn dein Objekt jetzt sehr schnell ist, sagen wir... 50m/s (180km/h), dann bewegt es sich dafür alle 0.02 Sekunden genau einen Meter weit. 50 Mal pro Sekunde je einen Meter = 50m/s. Wenn dein Objekt jetzt noch dazu im Vergleich nicht besonders groß ist - sagen wir 20cm lang, dann teleportiert sich dein 20cm-Objekt pro FixedUpdate einen Meter weiter und "überspringt" dabei 80cm. wenn innerhalb dieser 80cm ein Hindernis liegt, dann findet keine Kollision statt.

Wenn etwas so schnell ist, sollte man einfach pberlegen, stattdessen das Projektil mit einem Raycast zu abstrahieren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb brilzi89:

ich habe festgestellt wenn ich näher an das Objekt gehe explodiert die Shell an dem Objekt. Sobald ich weiter weg gehe fliegt die Shell durch das Objekt ohne zu explodieren.

Du kannst die Geschwindigkeit des Projektiles ja senken (zusätzlich die Werte im Inspektor ändern!):

       public float m_MinLaunchForce = 15f;        // The force given to the shell if the fire button is not held.
       public float m_MaxLaunchForce = 30f;        // The force given to the shell if the fire button is held for the max charge time.
       =>
       public float m_MinLaunchForce = 5f;        // The force given to the shell if the fire button is not held.
       public float m_MaxLaunchForce = 10f;        // The force given to the shell if the fire button is held for the max charge time.


Jedenfalls stimmt da etwas nicht, aber schwer zu sagen, wo genau nun das Problem ist, ohne daß man deinen Szeneaufbau sehen kann. Vielleicht ist dein Zielobjekt auch zu klein oder zu schmal (und damit der Collider, was dann auch zu dem Problem führt was Sascha meinte). Nimm mal einen großen Unity-Cube als Ziel. Ansonsten, du kannst das Projekt ja mal hochladen und hier verlinken.

Zudem würde ich noch einmal schauen, daß deine Shell auch 1:1 so aussieht wie in dem Bild hier:
- blaue Achse der Shell zeigt nach vorn
- die Größe der Shell passt
- der Capsule-Collider umschließt die Shellmesh
- Capsule-Collider: isTrigger / 0 0 0.2 / 0.15 / 0.55 / Direction "Z-Axis"
- Rigidbody vorhanden

TgIFd3A.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

hab jetzt versucht die Geschwindigkeit zu senken, hilft leider nichts. Die Rakete fliegt trotzdem durch, und explodiert nicht :/

lade mal paar Bilder hoch. Das mit dem Cube habe ich auch versucht, leider fliegen die da auch durch. Denke mal das die Rakete zu klein ist. Habe ja nicht die original Shell wie im Video

verwendet.

 

5a528642aed60_Screenshot(3).thumb.png.dc8dd09c8789b10ee3f24074f6ffd8f0.png5a5286480ca57_Screenshot(6).thumb.png.bc840905a031710919f76f561ba0217a.png5a5286467588c_Screenshot(5).thumb.png.28e9853675404589afea55e09915acea.png

Screenshot (4).png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ein paar Bilder sind ja recht wenig um einen Vorgang, der mit der Phyhsik zu tun hat, zu beurteilen.
Was ich aber sehe: Du hast in jedem Bild ne Fehlermeldung drin, denn du hast im Inputmanager scheinbar nicht die HorizontalUI drin. Solche Fehlermeldungen können das ganze Programm stören und auch die physik, wenn sie ständig anliegen.
Außerdem ist der Collider deiner Rakete auf Trigger geschaltet. Soll das so sein? Triggerst du auch das Event? Also nutzt du dann auch OnTriggerEnter ?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, die Fehlermeldungen sollten alle eleminiert sein ... Trigger ist für dieses Beispielprojekt korrekt.

Was sagen denn nun die Debugausgaben, trifft die Shell irgendwas? Wenn hier nichts reportet wird, kann auch keine Explosion ausgelöst werden.

Ins "ShellExplosion"-Skript einfügen:

private void OnTriggerEnter(Collider other) 
{
  print("Was getroffen: " + other.gameObject.name + "!"); // Diese Zeile hinzufügen

}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was mit noch auffällt, evtl. ist deine Shell tatsächlich zu klein, der Scale deiner Shell ist 0.05.
Alle Objekte in Unity gehen von der Maßeinheit 1 (quasi 1 Meter) aus. Ein Projektile eines Panzers sollte damit ca. 0.2 groß sein.

Zieh mal einen Würfel in deine Szene und setze dessen Scale auf 0.2/0.2/0.2. Deine Shell sollte nun ungefähr so groß wie dieser Cube sein. Wenn deine Objekte zu winzig werden, dann "schlüpfen" sie durch die Kollisionserkennung. Du solltest das Scaling aller deiner Gameobjekte entsprechend anpassen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Na ja, wenn du die Scale von deinem Objekt erhöhst, dann ist es natürlich viel größer als vorher. Wahrscheinlich berührt es dann sofort den Panzer und explodiert deswegen.
Da du aber die Scale recht klein gemacht hast, ist das Modell scheinbar recht groß.
Da die Scale ja eigentlich nichts aussagt, wäre es interessant zu wissen, wie groß dein Geschoss denn im vergleich zu einem Unity-Cube ist. Der Cube kommt ja immer als 1x1x1 raus. Also 1m³.

Zer0Cool wollte darauf hinaus, dass die Objekte in der Szene schon maßstabsgereu sein sollten. Und der Maßstab ist der Meter, alse eine Einheit in Unity.
Wenn das bei dir so passt, dann kannst du diese mögliche Fehlerquelle bei der Physik ausschließen.
Jetzt kann es eigentlich nur sein, dass das Geschoss zu schnell fliegt und dadurch andere Collider tunnelt.
Du kannst jetzt entweder einen Raycast nutzen oder die Geschwindigkeit reduzieren oder die FixedTime verringern. Von Standard 0.02 mal testweise auf 0.01 oder sogar auf 0.005. Das würde die Genauigkeit erhöhen, kostet aber CPU Leistung.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zitat

Hab jetzt mal versucht den Scale auf 0.2 zu setzten.


Wie @malzbie sagt, die Shell und der Panzer sollten größentechnisch im Verhältnis zum einem 1x1x1-Unity-Würfel passen. Die Shell sollte ca. so groß sein wie ein 0.2/0.2/0.2 skalierter Unity-Würfel und der Panzer vielleicht so groß wie ein 4/4/4 Würfel.

Die Größe deiner Shell hängt dabei nicht nur vom Scale deiner Shell ab, sondern auch vom Import-Scale der Shell des FBX der Shell. Wenn du das Asset deiner Shell anklickst (im Projektfenster), dann kannst du dort beim Import einen Scale setzen, diese bestimmt die Größe des Meshes in Unity. Am besten lässt du den Scale deiner Shell in der Unityscene auf 1.0 und setzt die Größe deiner Shell nur im Projektfenster!

Ich vermute im Beispielprojekt war der Scale der Shell auf 1.0 und die hast ihn verändert und damit funktioniert der ganze Aufbau nicht mehr.

Wenn die Shell mit einem Scale von 1.0 (in der Szene) die richtige Größe hat und du stellst 0.05 ein, dann ist sie 20x kleiner als normal!

Zudem sollte die Shell beim "Spawn" (wenn die Shell erzeugt wird) den Panzer nicht berühren, weil sonst schießt du dich selber ab! Die Shell darf beim "Spawn" den Collider des Panzers nicht berühren.

Zudem siehst du, was die Shell trifft, wenn du meine Debugausgabe eingebaut hast. Hier sollte nicht dein Panzer in der Console stehen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

erstmal danke malzbie und Zer0Cool :) hab eine Debugausgabe eingebaut und die gibt nur aus was getroffen, wenn ich näher am Gebäude bin. Hab gerade die original Shell von dem Tutorial genommen, und mit der funktioniert es einwandfrei. Sprich es muss an der Shell liegen. Hab dann die Shell die ich im Assetstore gekauf habe nochmal im original 1x1x1 genommen (natürlich sehr gross :) ) aber die fliegt auch wieder durch.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Den "Scale Factor" im unteren Fenster anpassen und die Größe (Scale) des GameObjects am besten auf (1.0/1.0/1.0) lassen.  Damit stellst du die Größe des Meshes in Unity ein.

An dein "Kauf"-Asset (Mesh) müssen natürlich wieder alle Komponenten hinzugefügt werden. RB und ein Capsule-Collider mit Trigger aktiviert. Der Collider muss den Mesh deines Kaufassets umschließen (grünes Netz in der Szeneview), d.h. du musst den Collider von der Größe her evtl. ebenfalls anpassen! Wenn du deinem Kaufasset einen Capsule-Collider hinzufügst sollte der von der Größe her eigentlich bereits passen.

Zudem ist es egal wie groß der Mesh deines Kauf-Assets ist, daß ausschlaggebende ist die Größe des Colliders der am Mesh hängt.
Du könntest also auch die Originalshell aus dem Tutorial nehmen und dort den Mesh (und Material) austauschen (auch gegen dein Kauf-Asset) und die Shell muss genauso funktionieren wie vorher, da der Mesh keine Rolle spielt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 48 Minuten schrieb brilzi89:

hab jetzt alles versucht, aber fliegt immer noch durch die objekte. Naja schaue mal ob ich andere Asset modele bekomme.

Kann eigentlich nicht sein, der Collider bestimmt, wie die Kollisionserkennung arbeitet, welcher Mesh am GameObjekt hängt, ist dabei völlig egal. Einzige Ausnahme ist, wenn du ein Meshcollider verwendest und dies solltest du nicht tun. Ich gehe davon aus, daß du einen Capsulecollider um dein Mesh gelegt hast.

Wenn das Asset aus dem Tutorial funktioniert:
- dein Kaufasset in die Szene ziehen (alle Komponenten entfernen außer Meshfilter und Meshrenderer)
- auf das Transform des Tutorialassets gehen -> Zahnrad Icon -> "Copy Component"
- auf das Transform des Kaufasset in der Szene -> Zahnrad Icon -> "Paste Component Values"
- auf den Collider des Tutorialassets gehen -> Zahnrad Icon -> "Copy Component"
- Kaufasset in der Szene -> Zahnrad Icon -> "Paste Component as New"
- auf den Rigidbody des Tutorialassets gehen -> Zahnrad Icon -> "Copy Component"
- Kaufasset in der Szene -> Zahnrad Icon -> "Paste Component as New"
- auf den Shell Explosion Script des Tutorialassets gehen -> Zahnrad Icon -> "Copy Component"
- Kaufasset in der Szene -> Zahnrad Icon -> "Paste Component as New"
- sonstige Komponenten die sich am Tutorialasset befinden ebenfalls mit der obigen Methode übertragen

Aus dem Kaufasset in der Scene nun ein Prefab machen (in den Projektfolder ziehen)
Beide Assets sollten sich nun nur noch über den Meshfilter und den Meshrenderer unterscheiden, ansonsten sollte alles gleich sein (ggf. andere Reihenfolge der Komponenten, aber auch die könnte man noch anpassen)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...