Du bist nicht angemeldet.

Werbeanzeige

techtreedev

Frischling

  • »techtreedev« ist der Autor dieses Themas

Beiträge: 50

Wohnort: 127.0.0.1 | localhost

Beruf: Webentwickler

  • Private Nachricht senden

1

11.12.2016, 14:44

Artillerie Projektil Physik

Moin,

ich muss für mein RTS einen Kanonenschuss simulieren und habe da einige Probleme bei der Implementation. Als Basis nutze ich diese Formel zur Kalukaltion des Abschisswinkels:


https://en.wikipedia.org/wiki/Trajectory_of_a_projectile

Der Code dafür sieht im Moment so aus:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  public float CalculateAngle()
    {

        Transform exit = transform.FindChild("Exit");
        Transform muzzle = transform.FindChild("Muzzle");
        Vector3 pos = exit.position;
        target.y = pos.y;
        transform.LookAt(target);  
        Vector3 dist = target - pos;
        dist = exit.transform.InverseTransformDirection(dist);

        float x = dist.z;
        float y = dist.y;
        float v = 100; //speed
        float g = 9.8f;
        
        float v2 = v * v;
        float v4 = v2 * v2;
        float x2 = x * x;

        float theta = Mathf.Atan2(v2 - Mathf.Sqrt(v4 - g * (g * x2 + 2 * y * v2)), g * x);

        muzzle.transform.Rotate(new Vector3(-theta * Mathf.Rad2Deg, 0, 0));
        Debug.Log( "Range X = " + x + "  Range Y = " + y + "  theta = " + theta * Mathf.Rad2Deg);
        return theta;
    }


In fast allen Fällen kommt 90 Grad zurück, was im Folgenden Code dazu führt, dass das Instanzierte Objekt einfach nur nach Unten fällt. Offenbar scheint auch die Kraftübertragung nicht ganz zupassen.

"Exit" ist ein 1x1x1px kleiner Cube, welcher den Austrittpunkt darstellen soll. "Muzzle" ist in dem Fall das Kanonenrohr. Der Rigidbody "projketil" ist ein unmodifizierter StandardRB auf einer Kugel, welche im Inspector der Kanone zugewiesen ist.

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    private void FireCannon()
    {

        Vector3 pos = transform.FindChild("Exit").position;
        float bulletSpeed = 1000;
        float dist = Vector3.Distance(pos, target);
        angle = CalculateAngle();

        float Vi = Mathf.Sqrt(dist * -Physics.gravity.y / (Mathf.Sin(Mathf.Deg2Rad * angle * 2)));
        float Vy, Vz;

        Vy = Vi * Mathf.Sin(Mathf.Deg2Rad * angle);
        Vz = Vi * Mathf.Cos(Mathf.Deg2Rad * angle);

        Vector3 localVelocity = new Vector3(0f, Vy, Vz);
        Vector3 globalVelocity = transform.TransformVector(localVelocity);

        Rigidbody clone = Instantiate(projektil, pos, transform.rotation) as Rigidbody;
        clone.AddForce(globalVelocity * bulletSpeed);        
        canFire = false;    
    }


Ausgeführt wird das Ganze in der Updatemethode.

Als Resultat erhalte ich immer 90 Grad, die Entfernungen stimmen jedoch. 90 Grad würde bedeuten, dass das Ziel direkt in der einheit steht. Im Inspector sind die Koordinaten des Ziels zu sehen: 8-0-68:



Un der Konsole scheint die Distanz aber zu stimmen, weshalb auch der Winkel eigentlich nicht 90 sein sollte:



Was auch seltsam ist, dass sich das Rohr seitlich dreht, statt nach oben.

Mein Verdacht ist, dass der Winkel in die falche Richtung geht, aber ich finde im Code keinen Anhaltspunkt für den Fehler

Wüsste jemand, woran das liegt, bzw ob es eine Best Practise für solche Systeme gibt?
Game-Designer und Entwickler bei Coffee Peak Games.

Thread zu unserem Projekt: Pro Gloria et Patria - das rollenspielbasierte RTS

-- Wir würden uns über Support in den Sozialen Netzen freuen.

Facebook: https://www.facebook.com/coffeepeakgames
Twitter: https://twitter.com/coffeepeakgames

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »techtreedev« (11.12.2016, 15:12)


equinox

Frischling

Beiträge: 49

Beruf: Student

  • Private Nachricht senden

2

11.12.2016, 17:04

Ich weiß zwar nicht ob dir das weiter hilft, aber in der von dir verwendeten Berechnung steht was von +/-. Du berechnest scheinbar nur den mit der Subtraktion.

Edit: Jetzt wo ich den Wiki-Artikel mal gelesen habe, fällt mir auf, dass da noch eine Formel für das Errechnen eines Winkels bei einem Ziel steht:

BlueCobold

Community-Fossil

Beiträge: 10 637

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

11.12.2016, 21:52

Abschisswinkels
Wie eklig 8o
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Nox

Supermoderator

Beiträge: 5 219

Beruf: Student

  • Private Nachricht senden

4

11.12.2016, 23:42

Ich empfehle die Verwendung eines Taschenrechners um mal selbst das ganze durchzurechnen. Dann sollte schnell klar werden an welcher Stelle dir die Formel um die Ohren fliegt (zumindest mit den Werten aus der Ausgabe). Tipp: es hat was mit Koordinatensystemen zu tun und geht in die Richtung die equinox schon ansprach - wobei die von ihm genannte Formel augenscheinlich für sphärische Koordinaten gültig ist.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy

TGGC

1x Rätselkönig

Beiträge: 1 717

Beruf: Software Entwickler

  • Private Nachricht senden

5

12.12.2016, 14:11

Du hast doch eine ganz andere Formel programmiert, als du oben aufgeschrieben hast. Und da kommt jetzt was anderes raus? Na woran kann das wohl liegen...

techtreedev

Frischling

  • »techtreedev« ist der Autor dieses Themas

Beiträge: 50

Wohnort: 127.0.0.1 | localhost

Beruf: Webentwickler

  • Private Nachricht senden

6

12.12.2016, 17:09

Du hast doch eine ganz andere Formel programmiert, als du oben aufgeschrieben hast. Und da kommt jetzt was anderes raus? Na woran kann das wohl liegen...


Sorry, falls ich jetzt doof klinge, aber die o.g Formel ist die angegebene, oder?

C#-Quelltext

1
Mathf.Atan2(v2 - Mathf.Sqrt(v4 - g * (g * x2 + 2 * y * v2)), g * x);





Nebenbei; ist mein Ansatz evetuell total überflüssig und würde es einfacher gehen?
Game-Designer und Entwickler bei Coffee Peak Games.

Thread zu unserem Projekt: Pro Gloria et Patria - das rollenspielbasierte RTS

-- Wir würden uns über Support in den Sozialen Netzen freuen.

Facebook: https://www.facebook.com/coffeepeakgames
Twitter: https://twitter.com/coffeepeakgames

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »techtreedev« (12.12.2016, 17:29)


TGGC

1x Rätselkönig

Beiträge: 1 717

Beruf: Software Entwickler

  • Private Nachricht senden

7

13.12.2016, 10:44

Ja aber die Werte haben doch ganz andere Bedeutungen? Und wie shcon jemand sagte laesst du auch einfach die Haelfte der Loesungen weg. Nur weil du die gleiche Rechenoperationen auf irgendwelche Zahlen anwendest ist das doch nicht die gleiche Formel. Schau dir dein Beispiel an im Vergleich zur Originalbedeutung "hit a target at range x and altitude y". Das waere dann ein Ziel das sehr hoch ist aber bei sehr geringer Reichweite. Da macht es sehr viel Sinn das man quasi senkrecht nach oben zielt.

techtreedev

Frischling

  • »techtreedev« ist der Autor dieses Themas

Beiträge: 50

Wohnort: 127.0.0.1 | localhost

Beruf: Webentwickler

  • Private Nachricht senden

8

13.12.2016, 15:08

Ja aber die Werte haben doch ganz andere Bedeutungen? Und wie shcon jemand sagte laesst du auch einfach die Haelfte der Loesungen weg. Nur weil du die gleiche Rechenoperationen auf irgendwelche Zahlen anwendest ist das doch nicht die gleiche Formel. Schau dir dein Beispiel an im Vergleich zur Originalbedeutung "hit a target at range x and altitude y". Das waere dann ein Ziel das sehr hoch ist aber bei sehr geringer Reichweite. Da macht es sehr viel Sinn das man quasi senkrecht nach oben zielt.


Jup, ich weiß nicht, was da mit mir los war. Hatte wohl eine geistige Blockade. Problem wurde gelöst und eins davon war nicht mal ein Code Problem(ich wollte das Verhalten für frontale Treffer durch die Formel erzwingen, was ja auf 20m keinen Sinn macht, da indirektes Feuer anzuwenden, wenn nichts den Weg versperrt)
Game-Designer und Entwickler bei Coffee Peak Games.

Thread zu unserem Projekt: Pro Gloria et Patria - das rollenspielbasierte RTS

-- Wir würden uns über Support in den Sozialen Netzen freuen.

Facebook: https://www.facebook.com/coffeepeakgames
Twitter: https://twitter.com/coffeepeakgames

Renegade

Alter Hase

Beiträge: 427

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

9

13.12.2016, 20:44

//Kleine Anmerkung
Wenn man das Unity Physiksystem nutzen möcht, ist das Problem lediglich ein Zweizeiler. Dabei kann man via fireTransform die Position und Rotation bestimmen, sowie mittels launchForce auch die Kraft variieren. Das Snippet stammt im Übrigen aus der Tanks! Demo von Unity, siehe Lektion 6: Firing Shells.

C#-Quelltext

1
2
3
4
// Create an instance of the shell and store a reference to it's rigidbody.
Rigidbody shellInstance = Instantiate (shellPrefab, fireTransform.position, fireTransform.rotation) as Rigidbody;
// Set the shell's velocity to the launch force in the fire position's forward direction.
shellInstance.velocity = launchForce * fireTransform.forward;
Liebe Grüße,
René

techtreedev

Frischling

  • »techtreedev« ist der Autor dieses Themas

Beiträge: 50

Wohnort: 127.0.0.1 | localhost

Beruf: Webentwickler

  • Private Nachricht senden

10

13.12.2016, 21:34

//Kleine Anmerkung
Wenn man das Unity Physiksystem nutzen möcht, ist das Problem lediglich ein Zweizeiler. Dabei kann man via fireTransform die Position und Rotation bestimmen, sowie mittels launchForce auch die Kraft variieren. Das Snippet stammt im Übrigen aus der Tanks! Demo von Unity, siehe Lektion 6: Firing Shells.

C#-Quelltext

1
2
3
4
// Create an instance of the shell and store a reference to it's rigidbody.
Rigidbody shellInstance = Instantiate (shellPrefab, fireTransform.position, fireTransform.rotation) as Rigidbody;
// Set the shell's velocity to the launch force in the fire position's forward direction.
shellInstance.velocity = launchForce * fireTransform.forward;


Und wenn man einen bestimmten Winkel Nutzen will, z.B für Indirektes Feuern? Oder für Höhenunterschiede? Das will ich ja damit erzielen.

Code für direktes Feuern (leichte Parabel)

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void getAngle()
    {
        float dist = Vector3.Distance(exit.position, target.transform.position);
        angle = (Mathf.Asin((gravitation * dist) / (velocity * velocity))) / 2;
    }

    private void FireCannon()
    {
        getAngle();
        transform.LookAt(target.transform.position);
        Vector3 direction = new Vector3(0, Mathf.Sin(angle), Mathf.Cos(angle));
        Rigidbody clone = Instantiate(projektil, exit.transform.position, transform.rotation) as Rigidbody;
        clone.AddForce(direction  * velocity);
        canFire = false;
    }


Dachte, der Code würde ausreichen, aber die Projektile fliegen Richtung Boden (direkt unter das Rohr). Laut Taschenrechner ist der berechnete Winkel korrekt. Ich hab da jetzt so lang rumexperimentiert, dass ich wohl den Blick für das Einfache verloren habe.
Game-Designer und Entwickler bei Coffee Peak Games.

Thread zu unserem Projekt: Pro Gloria et Patria - das rollenspielbasierte RTS

-- Wir würden uns über Support in den Sozialen Netzen freuen.

Facebook: https://www.facebook.com/coffeepeakgames
Twitter: https://twitter.com/coffeepeakgames

Werbeanzeige