Zum Inhalt springen
  • 0

Unity 2D - C# Code trennen


Frage

Geschrieben

Hallo, ich arbeite derzeit an einem kleinen Endless Runner, der bereits fertig ist. Da ich das Spiel weiterhin ausbaue, versuche ich jetzt erst mal den Code etwas sauberer zu machen bzw. Klassen zu erstellen, um den Code voneinander zu trennen. Allerdings würde mich interessieren, was aus eurer Sicht sinnvoll wäre.

Als Beispiel findet man in meinem Projekt mehrere Klassen: PlayerScript, CameraScript, +- 6 Scripts...

In meinem PlayerScript befindet sich der Bewegungs-, Sprung-, Animations-, Kollisions- und Soundcode. Jetzt habe ich vor Sound, Animation und Kollision in separate Klassen einzuteilen. Würdet ihr grundsätzlich das auch so machen oder hättet ihr Vorschläge, wie sowas ordentlich gemacht werden muss?

Ich danke vorab für Rückmeldungen.

6 Antworten auf diese Frage

Empfohlene Beiträge

  • 0
Geschrieben
vor 20 Stunden schrieb Monsieur Bate:

In meinem PlayerScript befindet sich der Bewegungs-, Sprung-, Animations-, Kollisions- und Soundcode. Jetzt habe ich vor Sound, Animation und Kollision in separate Klassen einzuteilen. Würdet ihr grundsätzlich das auch so machen oder hättet ihr Vorschläge, wie sowas ordentlich gemacht werden muss?

Definitiv!
Schaue dir dazu die sog. SOLID-Prinzipien an. 

Dein PlayserScript verstößt schon gegen das Single-Responsibility-Prinzip, weil es mehr als eine Verantwortung trägt. Es ist ja quasi für alles verantwortlich und das darf nicht sein. Daher ist der erste Schritt, all die Methoden und die Klassenvariablen in ihre Verantwortlichkeiten zu separieren und daraus einzelne Klassen machen. 

  • 0
Geschrieben
vor 4 Stunden schrieb Whiz-zarD:

Definitiv!
Schaue dir dazu die sog. SOLID-Prinzipien an. 

Dein PlayserScript verstößt schon gegen das Single-Responsibility-Prinzip, weil es mehr als eine Verantwortung trägt. Es ist ja quasi für alles verantwortlich und das darf nicht sein. Daher ist der erste Schritt, all die Methoden und die Klassenvariablen in ihre Verantwortlichkeiten zu separieren und daraus einzelne Klassen machen. 

Danke erst mal für deine Antwort.

Würdest du das dann in die sog. partellien Klassen unterteilen und daraus mehrere Dateien machen oder würdest du gleich aus dem Code komplett unabhängige Klassen machen? Ich hatte auch währenddessen im Internet recherchiert und fand nämlich Programmierer, die partielle Klassen für soetwas verwenden würden und diese als Files abspeichern.

  • 0
Geschrieben
vor 11 Minuten schrieb Monsieur Bate:

Danke erst mal für deine Antwort.

Würdest du das dann in die sog. partellien Klassen unterteilen und daraus mehrere Dateien machen oder würdest du gleich aus dem Code komplett unabhängige Klassen machen? Ich hatte auch währenddessen im Internet recherchiert und fand nämlich Programmierer, die partielle Klassen für soetwas verwenden würden und diese als Files abspeichern.

Unabhängige Klassen - nur ein Beispiel: Dein "Soundcode" bzw. dein Framework funktioniert nicht mehr oder muss überarbeitet werden. Wenn du eine unabhängige Klasse hast, findest du diese sehr schnell wieder und musst nur in dieser Klasse etwas umschreiben.
Würde es als partielle Klasse in deiner PlayerScript Klasse eingebunden sein, müsstest du erstmal suchen und würdest unter Umständen auch noch anderen Code in der Klasse umschreiben müssen, der gar nichts mit dem Sound zu tun hat.

Hier kann es dann schnell zum typischen "Fix one bug, create two" Phänomen kommen.

  • 0
Geschrieben (bearbeitet)

Partielle Klassen verwende ich so gut wie gar nicht, weil sie nur in sehr wenigen Situationen wirklich Sinn machen. Partielle Klassen wurden in C# auch nur wegen WinForms eingeführt, damit man den automatisch generierten Code vom selbstgeschriebenen Code kapseln kann. Früher war der generierte Code mit dem selbstgeschrieben Code in einer Datei, was sehr unübersichtlich wurde, weil der generierte Code für die WinForms-Applikation sehr lang werden konnte.

Ich kenne dein Code jetzt nicht aber in der Regel entwickelt man Interfaces, die dann die Klassen implementieren und die Klassen werden dann per Inversion of Control bzw. Dependency Injection zusammengefügt. Also die Abhängigkeiten einer Klasse werden vom Erzeuger reingereicht. So könnte man z.B. ein Interface für die Sounds definieren:

public interface ISound
{
    void Play();
}
public class PlayerSound : ISound
{
    public void Play()
    {
        \\ Spiele Sound
    }
}

Per Inversion of Control wird dies jetzt mit dem Player verbunden:

public class Player
{
    public ISound Sound { get; private set; }

    public Player(ISound sound)
    {
        this.Sound = sound;
    }
}

Man sieht hier also, um eine Instanz von der Player-Klasse zu erzeugen, brauchen wir auch eine Instanz, die das ISound-Interface implementiert.

Zum Erzeugen der Player-Klasse müssen wir dann folgendes aufrufen:

var player = new Player(new PlayerSound());

Auf diese Weise ist die Player-Klasse nicht  mehr hart mit den Sounds verdrahtet und können die Sounds einfach austauschen. Beispiel:

public class PlayerASound : ISound
{
    public void Play()
    {
        \\ Spiele "Uff"
    }
}
public class PlayerBSound : ISound
{
    public void Play()
    {
        \\ Spiele "Ahh"
    }
}
var spielerA = new Player(new PlayerASound());
var spielerB = new Player(new PlayerBSound());

// ...

spielerA.Sound.Play(); // Spielt "Uff"
spielerB.Sound.Play(); // Spielt "Ahh"

 

Bearbeitet von Whiz-zarD
  • 0
Geschrieben (bearbeitet)

Hallo, danke bisher für eure Antworten. Ich habe seit heute morgen mich mit meinem Code befasst und hatte als Beispiel dieses SoundManagerScript.cs geschrieben:

using System.Collections.Generic;
using UnityEngine;

public class SoundmanagerScript : MonoBehaviour {
 
    private AudioSource audioSource;
    [SerializeField] private List<AudioClip> soundClips;
 
    // Use this for initialization
    void Start () {
        audioSource = GetComponent<AudioSource>();
    }
    
    // Spiele Soundclip
    public void PlaySound(string audioClipToPlay)
    {
        foreach (AudioClip clip in soundClips)
        {
            if (clip.name == audioClipToPlay)
            {
                audioSource.PlayOneShot(clip);
            }
 
        }
    }
}

Unzwar füge ich das Script wie im folgenden Bild meinem PlayerObject hinzu und füge manuell die einzelnen SoundClips ein. Dann muss logischerweise, wenn der Player springt in der selben Methode die Methode Playsound im SoundmanagerScript aufrufen und nur noch den String "JumpSound" eingeben.

https://imgur.com/a/qrTVp

Anmerkung: Ich werde mich auch mit dem Beispiel von dir nochmal befassen, @Whiz-zarD.

Bearbeitet von Monsieur Bate
  • 0
Geschrieben

Da bin ich leider auch ein bisschen raus, da ich mich mit Unity nicht wirklich auskenne. Da weiß ich nicht, wie man mit Unity arbeitet. Sorry.


Aber ein kleiner Hinweis: Anstatt List<AudioClip> kannst du auch ein Dictionary<string, AudioClip> machen, dann brauchst du die foreach-Schleife nicht und die PlaySound-Methode lautet einfach:

public void PlaySound(string audioClipToPlay)
{
    if(this.soundClips.Exists(audioClipToPlay))
        audioSource.PlayOneShot(this.soundClips[audioClipToPlay]);
}

 

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...