Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

1

05.12.2013, 22:53

[Unity & C# ] Einige Fragen/Probleme zu/mit Unity

Hallo Community,

ich habe zur Zeit ein Problem bei dem First-Person-Shooter den ich gerade entwickle. Ich will mehrere Waffen zur Auswahl stellen (bisher hatte ich bloß eine Pistole). Nun habe ich den Code der Pistole in eine Waffen-Klasse gepackt um so nur noch eine Instanz dieser Klasse erstellen zu müssen um eine neue Waffe zu implementieren. Seitdem Verhalten sich die Kugeln komisch. Trotz gleicher Physik-Einstellungen fallen sie auf den Boden (an falscher Position!) und Rollen dort umher bis sie nach einigen Sekunden deletet werden. Ich habe den Fehler bis her weder in Code noch in den Physik-Einstellungen gefunden.

Wie man beim Spielen sieht (Link zu einer älteren Versionen weiter unten) kann man wenn die Kamera zu dicht an die Waffe bewegt hindurch sehen. Ändert sich das wenn ich die Waffe texturiere bzw. wie kann ich das ändern.

Kennt jemand von euch ein gutes deutsches Tutorial zum texturieren von Modellen direkt in Unity?

Ältere Version des Spiels.

Komplette Projekt-Datei.

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

06.12.2013, 04:55

Hat die neue Waffe vielleicht eine Collision, auf die die Kugel reagieren könnte?
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

3

06.12.2013, 11:55

Die neue Waffe hat keinen Collider. Ich habe mir allerdings noch einmal die Einstellungen der Kugel angeschaut und gesehen das ihr Collider-Radius größer war als sie selbst. Nun fliegen die Kugeln manchmal in die richtige Richtung. Das Script das die Kugel wenn sie irgendetwas berührt zerstören sollte funktioniert allerdings nicht.

BULLET_ThermalDetonator.cs

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
27
28
29
30
31
32
33
using UnityEngine;
using System.Collections;

public class BULLET_ThermalDetonator : MonoBehaviour {
    
    float lifespan = 6.0f;

    
    // Use this for initialization
    void Start () {
    
    }
    
    void Explode() {
        Destroy(gameObject);
    }
    
    void OnCollisionEnter(Collision collision) {
            Explode ();
    }
    
    // Update is called once per frame
    void Update () {
        lifespan -= Time.deltaTime;
        
        
        if(lifespan <= 0) {
            Explode();
        }
    }

    
}

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

4

07.12.2013, 21:04

Hat keiner ne' Idee woran es liegen könnte? :(

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Renegade123

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

5

07.12.2013, 21:25

Pack auf die Kugeln ein Rigidbody. Und rufe in der Start AddForce() auf. Jedes mal wenn dann eine neue Kugel instanziiert wird, wird eine Kraft in eine Richtung darauf gewirkt.
Das ganze könnte z.B. so aussehen:

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
27
using UnityEngine;
using System.Collections;

public class BULLET_ThermalDetonator : MonoBehaviour {
    
    public float lifespan = 6.0f;
    public float force = 100.0f;
    public Transform playerTransform = null;
    private Rigidbody _rigid = null;

    
    // Use this for initialization
    void Start () {
        Invoke("Explode", lifespan);
        _rigid = GetComponent<Rigidbody>();
        _rigid.AddForce((transform.position - playerTransform.position ).normalized * force , ForceMode.Impulse);

    }
    
    void Explode() {
        Destroy(gameObject);
    }
    
    void OnCollisionEnter(Collision collision) {
            Explode ();
    }  
}


Bezüglich der Collision könntest du mal die Layer checken. Desweiteren musst du beachten das für einen Aufruf der OnCollisionEnter einer der beiden GameObjects ein Rigidbody besitzen muss. Siehe Collisionmatrix etwas weiter unten.
Liebe Grüße,
René

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Renegade123« (07.12.2013, 21:40)


Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

6

07.12.2013, 22:45

In FP_Shooting beschleunige ich bereits die Kugel.

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using UnityEngine;
using System.Collections;

public class FP_Shooting : MonoBehaviour {
    
    enum eIsUsed {
        Pistole,
        AK47
    };

    eIsUsed IsUsed = eIsUsed.Pistole;

    public class Shooting {

        public Shooting (GameObject Weapon, GameObject Bullet, int magazin_max, float bulletImpulse, Texture2D Crosshair) {
            reload = false;
            this.Weapon = Weapon;
            this.Bullet = Bullet;
            this.magazin_max = magazin_max;
            magazin = magazin_max;
            Wait = 0.0f;
            this.bulletImpulse = bulletImpulse;
            this.Crosshair = Crosshair;
            KeyDownR = false;
        }

        public void Update (GameObject weapon) 
        {
            // Fire!!!
            if( Input.GetButtonDown("Fire1") && reload == false ) {
                
                GameObject thebullet = (GameObject)Instantiate(Bullet, weapon.transform.position + weapon.transform.up, weapon.transform.rotation);
                thebullet.rigidbody.AddForce( weapon.transform.up * bulletImpulse, ForceMode.Impulse);
                magazin--;
            }
            
            
            if( Input.GetKeyDown (KeyCode.R) && magazin < magazin_max)
                KeyDownR = true;
            
            if( KeyDownR && magazin > 0 && magazin < magazin_max )
            {
                Wait += Time.deltaTime;
                reload = true;
                if( Wait >= 5.0f ){
                    magazin = magazin_max;
                    Wait = 0.0f;
                    reload = false;
                    KeyDownR = false;
                }
            }
            
            // If magazin is empty
            if( magazin <= 0 ){
                Wait += Time.deltaTime;
                reload = true;
                if( Wait >= 5.0f )
                {
                    magazin = magazin_max;
                    Wait = 0.0f;
                    reload = false;
                }
            }

        }

        public bool reload;
        public GameObject Weapon;
        public GameObject Bullet;
        public int magazin_max;
        public int magazin;
        public float Wait;
        public float bulletImpulse;
        public Texture2D Crosshair;
        bool KeyDownR;

    }

    public GameObject bullet_prefab;
    public bool reload;
    public int magazin;
    public float Wait;
    float bulletImpulse;
    bool KeyDownR; 
    public Texture2D Crosshair;
    public Shooting Pistole;
    public Shooting AK;
    public GameObject AKObject;


    // Use this for initialization
    void Start () {
    reload = false;
    magazin = 20;
    Wait = 0.0f;
    bulletImpulse = 60000f;
    KeyDownR = false;

    Pistole = new Shooting (GameObject.Find ("Player/Pistole"), bullet_prefab, 20, bulletImpulse, Crosshair);

        
        AK = new Shooting (GameObject.Find ("Player/AK-47"), bullet_prefab, 40, bulletImpulse-bulletImpulse+30f, Crosshair);
    }
   

    // Update is called once per frame
    void Update () {


        AK.Update (AKObject);

        
        
    }
    
    void OnGUI ()
    {
        
        if( !AK.reload )
        GUI.Box (new Rect (30, 50, AK.magazin*10, 20), AK.magazin.ToString());
        
        if( AK.reload )
        GUI.Box (new Rect(30, 50, AK.Wait*40, 20), "reloading...");

        GUI.Label (new Rect((Screen.width - Crosshair.width) / 2, (Screen.height - Crosshair.height) / 2, Crosshair.width, Crosshair.height), Crosshair);
    }
}

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Renegade123

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

7

07.12.2013, 23:38

Das Script empfinde ich als fürchterlich durcheinander. Ich finde es Vorteilhaft für die Leserlichkeit erst mit den öffentlichen, dann mit den private Variablen zu beginnen. Danach folgen die Methoden.

Nun fliegen die Kugeln manchmal in die richtige Richtung.

Warum wird der AddForce der Up-Vektor der Weapon übergeben? Sollte es nicht der Fordward-Vektor sein?
Außerdem könntest du ein leeres GameObject am Laufende der Waffe positionieren für die Instanziierung einer Kugel.

Das Script das die Kugel wenn sie irgendetwas berührt zerstören sollte funktioniert allerdings nicht.

Am FP_Shooting Script sollte es nicht liegen. Wie in meinem vorigen Post, rate ich dir einmal die Layer zu checken.
Desweiteren könnte ich mutmaßen, dass die Kugel womöglich zu schnell ist. Ich habe selbst schon öfters das Phänomen beobachtet, dass die Methoden für die Kollision ab einer bestimmten Geschwindigkeit nicht mehr richtig aufgerufen werden.

PS: Wozu eigentlich die Nested Class? Ich sehe den Nutzen nicht so richtig. Warum hat nicht jede Waffe ihr eigenes Script als Komponente?
Liebe Grüße,
René

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Renegade123« (07.12.2013, 23:47)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

8

08.12.2013, 00:10

Ich empfehle einen Raycast zu verwenden, der von der Kamera ausgeht, zu verwenden anstatt die Kollision der Kugel zu verwenden. Da trifft man einfach besser.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Cranberry

Treue Seele

Beiträge: 312

Wohnort: Innsbruck, Tirol

  • Private Nachricht senden

9

08.12.2013, 00:14

Für sowas braucht man doch nicht extra Bullet-Objekte. Die sind eh zu schnell als dass man sie wahrnehmen könnte. (Außer in dem Spiel gibt es Bullettime wie in Max Payne)
Check einfach mit Hilfe eines Raycasts ob sich der Gegner in Schussbahn befindet, das ist nicht so umständlich.

Edit.: Verdammt NachoMan :D

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

10

08.12.2013, 00:43

Je nach Geschwindigkeit des Projektils, Größe des Projektils (oder zumindest dessen Collider) und Größe der Collider, mit denen das Projektil kollidieren soll, kann es zu Tunneling kommen, was sich wohl am ehesten auf die von NachoMan genannte Art vermeiden lässt.

Abgesehen von der reinen Reihenfolge der Member und der unnötigen Einbettung der Klasse und Enumeration gibt es noch ein paar andere Dinge, die ich anmerken will:
Die Namen sind sehr schlecht gewählt, da sie nicht auf den Zweck schließen lassen. "Shooting" sollte eher "Gun" oder "Weapon" und "eIsUsed" sollte eher "WeaponType" heißen.
Es gibt anscheinend bereits GameObjects, die die Waffen darstellen, warum wird diesen dann nicht die bisherige Klasse "Shooting" (daher besser "Weapon") als Komponente zugewiesen? Die dem Konstruktor übergebenen Parameter könnten als Member der Klasse vertreten und dann vom Editor aus zugewiesen werden.
Du weist die Standardwerte für "FP_Shooting" in "Start" zu, obwohl diese eher direkt an der Deklaration angegeben werden sollten. Andernfalls hat man aus dem Editor heraus nicht die Möglichkeit, andere Werte zuzuweisen. Sollen die Werte nicht aus dem Editor heraus verwendet werden, dürfte NonSerialized von Interesse sein. (Mit SerializeField kann man private Variablen im Inspector sichtbar machen.)
Die Enumeration dürfte eigentlich unnötig sein. Die Waffe kennt auch so ihren Typ und an anderen Stellen kann die Waffe (das GameObject) selbst verwendet werden.

@Renegade123:
Wenn einem GameObject ein Rigidbody zugewiesen wurde, kann man aus jedem zugewiesenen Skript heraus über "rigidbody" bzw. "this.rigidbody" bzw. "this.gameObject.rigidbody" zugreifen. "GetComponent" dafür aufzurufen oder den Rigidbody zwischenzuspeichern dürfte nicht notwendig sein.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige