Showing posts with label Unity3D. Show all posts
Showing posts with label Unity3D. Show all posts
Der Boxhandschuh

Tuesday, January 21, 2014

Der Boxhandschuh

Der Boxhandschuh ist ein typisches Item was man unbedingt loswerden möchte. 


Denn nach ca. 10 Sekunden wird es herunterfallen und den eigenen Charakter treffen, ihm somit Lebenspunkte entziehen und bewegungsunfähig machen. In dieser Zeit ist er leicht angreifbar. Also sollte man dafür sorgen, den Handschuh an den Gegner durch Nahkampf abzugeben.


Das Item ist zwar ähnlich wie die Mine oder die Bombe programmiert, hat jedoch einen großen Unterschied. 
Man kann es nicht manuell auslösen, es startet direkt beim Aufnehmen ein Countdown. Sobald dieser auf 0 ist, löst das Item aus und man erhält selbst Schaden.

IEnumerator waitBoxhandschuh()
{
    yield return new WaitForSeconds(8); 
    itemManager.boxhandschuhMe=false;
    if(boxhandschuhAusfuehren==true)
    {
        getroffen=true;
        healthPointsEnemy-=Screen.width/3*0.95f/8; 
        networkView.RPC("boxhandschuhRPC", uLink.RPCMode.Others);
        yield return new WaitForSeconds(2);
        getroffen=false;
        networkView.RPC("clearBildEnemy", uLink.RPCMode.Others);
        boxhandschuhAusfuehren=false;   
   }
}

Das Auslösen, Löschen und Aufnehmen des Items läuft wie bei der Mine. Wen das interessiert kann es in diesem Post noch einmal nachlesen. 

Ansonsten wird die Funktion waitBoxhandschuh ausgelöst, sobald boxhandschuhMe true ist. 
Nachdem 8 Sekunden gewartet wurden, wird dem eigenen Charakter Schaden hinzugefügt und die Variable getroffen auf true gesetzt. Dies bewirkt, dass eine Getroffen-Animation ausgeführt wird, 2 Sekunden andauert und danach mit getroffen=false; wieder gestoppt wird.
"Itemspawnsystem"

Saturday, January 18, 2014

"Itemspawnsystem"

Wie kommen die Items eigentlich ins Spiel?


Dazu habe ich mir ein eigenes Spawnsystem einfallen lassen, welches den zuvor Item-Variablen, wie z.B. bombeMe aus den vorherhigen Posts, die Werte wahr oder falsch gibt.
Für dieses System erstellte ich mehrere Punkte / leere GameObjects mit einem großen Trigger in meinem Level, in welchen Items erscheinen können. Dort erscheinen sie jedoch nur, wenn der Spieler sich nicht in diesem Trigger befindet:

// Item 01
if(noCharInItem.charInItem01==false)
{
    if(charScreenManager.enemyIn==false)
    {
         if(spawnPositionBesetzt01==false)
  {   
      if(networkView.isMine)
      {
   networkView.RPC("setRandomTime",
                 uLink.RPCMode.Server); 
   StartCoroutine(waitingForSec01()); 
   spawnPositionBesetzt01=true; 
      }  
  }        
  if(waiting01==false)
  {
      if(networkView.isMine)
      {
   networkView.RPC("setRandomValue",
                 uLink.RPCMode.Server); 
   itemSpawn();
   itemPosition01 = uLink.Network.Instantiate(
                 itemToSpawn,spawnPointItem01.transform.position, 
                 transform.rotation,0); 
   waiting01=true;
             }
  }
    }
}
Erklärung:
Das Spawnsystem läuft nur auf Client 1 aufgrund der Abfrage if(charScreenManager.enemyIn==false), da sonst mehrere Items auf einer Position gespawnt werden würden. 
Nachdem sicher gestellt wurde, dass das Item gespawnt werden kann,wird eine zufällige Zahl auf dem Server erstellt, die festlegt nach wie vielen Sekunden das Item erscheinen wird. 
In der Funktion waitingForSec01(); wird dann gewartet und später die Variable waiting01 auf true gesetzt. Somit kann die nächste Abfrage durchgeführt werden, welche einen zufälligen Wert erstellt, welcher das zufällige Item bestimmt. Nun kann endlich das Item auf itemPosition01 instanziiert werden.


Die Wasserbombe

Friday, January 17, 2014

Die Wasserbombe

Die Wasserbombe ist ein weiteres Item aus meinem Spiel und sie funktioniert folgendermaßen:


Beim Betätigen der Aktionstaste, wird die Bombe geworfen. Hierbei bewegt sie sich mit einer festgelegten Kraft in Sichtrichtung. Bei einem Zusammenprall mit einem Objekt mit dem Tag "Player" wird sie explodieren und Schaden hinzufügen. Auch das eigene Objekt kann also, wenn man sich unvorteilhaft anstellt, getroffen werden. Somit wirkt sie ähnlich wie der Ferkampf, nur eben schneller. Zudem hat sie eine kürzere Reichweite.


Jedes Item hat einen speziellen Tag, worüber sie auch auseinander gehalten werden. Läuft also ein Spieler durch ein instanziiertes Item mit dem Tag „Bombe“, erhält er die Bombe in Form einer Variable. Danach wird über diesem Spieler das Icon für „Wasserbombe“ erscheinen. Anschließend wird, je nach dem an welcher Stelle das Item aufgenommen wurde, die entsprechende Variable auf false gesetzt, sodass hier wieder ein neues instanziiert werden kann:

if(other.tag=="Bombe")
{  
    objectToDestroy=other.gameObject;
    if(networkView.isMine)
    {
        if(bombeMe==false&&boxhandschuhMe==false&&schnelligkeitMe==false&&mineMe==false&&flagMe==false&&kaefigMe==false)
        {
     if(RPCTest.kaefigAktiv==false)
     {
   canDestroyObject=true;
   networkView.RPC("setcanDestroyObjecttrue", uLink.RPCMode.Others);
     }
     if(canGetNewItem==true)
     {
   audio.PlayOneShot(aufnehmenSound);
   bombeMe=true;
     } 
 } 
 if(canDestroyObject==true)
 {    
  testPosOther=other;   
  testPos();
 }
    }    
}

Weiterhin wird im Skript festgelegt, welches Objekt zerstört wird (objectToDestroy). In der Abfrage if(networkView.isMine) wird noch einmal genau nachgesehen ob man auch wirklich kein Item hat (if(bombeMe==false&&...)) und ob der Käfig im Moment nicht aktiv ist. Nur dann wird das auf dem Boden liegende Item zerstört und die Variable bombeMe wird true.
Das Zerstören des Items passiert in einer ausgelagerten Funktion.

In einem anderen Skript kann nun durch das drücken der Aktionstaste die Bombe ausgelöst werden. In diesem Fall wird ein neues Objekt instanziiert und die Variable bombeMe wieder false:

if(itemManager.bombeMe==true)
{ 
    bombeAusloesbar = uLink.Network.Instantiate(bombeAusloesbarPrefab, 
    new Vector3(transform.position.x-30,transform.position.y+5,
    transform.position.z), transform.rotation, 0);  
    itemManager.bombeMe=false;                    
}

Nun fehlt nur noch die Bewegung der Bombe. 
Durch den auf dem instanziierten Objekt enthaltenen Rigidbody kann ich die Funktion AddForce(); ausführen um die Bombe zu bewegen. 
Sobald die Bombe nun in einen Trigger hinein fliegt, wird sie je nach dem dem eigenen oder dem gegnerischen Spieler Schaden anrichten. Wenn der Trigger kein Spieler war, wird die Bombe einfach zerstört.

void OnTriggerEnter(Collider other)
{
    if(other.tag=="Player")
    { 
        playerGetroffen=other.gameObject;
        if(networkView.isMine)
        {
            if(playerGetroffen==Player)
            {
   RPCTest.getroffen=true; 
   RPCTest.healthPointsEnemy-= Screen.width/3*0.95f/10;
   networkView.RPC("bombeTreffer",uLink.RPCMode.Others);
     }
     else
     {     
  networkView.RPC("stopMovement", uLink.RPCMode.Others); 
  RPCTest.healthPointsEnemyLocal-= Screen.width/3*0.95f/10;     
            }
     Destroy(this.gameObject);
 }
    }
    if(other.tag=="LevelObject"||other.tag=="Boden")
    {
  Destroy(this.gameObject);
    }
}








Die Mine

Monday, December 16, 2013

Die Mine

Nachdem ihr nun gesehen habt, welche Items es in meinem Spiel geben wird, werde ich euch das erste genauer zeigen: die Mine.


"Beim aktivieren wird sie an die aktuelle Position des minenlegenden" Charakters gesetzt und erst explodieren wenn der Gegner darüber läuft. Sie soll sehr schlecht erkennbar dargestellt sein, sodass man sie bei vorsichtigem pirschen erkennen kann und in Eile übersieht. So kann man dem Gegner den Weg auf der Treppe versperren um es selbst einfacher zu haben an das nächste Item zu kommen."



Mine Avatar

Nachdem also ein Spieler die Mine aufgenommen hat erscheint das Zeichen dafür als Avatar über dem Kopf des Spielers.
Dieser hat nun die Möglichkeit die Mine an irgendeiner Stelle, solange er sich nicht in der Luft befindet, abzulegen:
if(Input.GetKeyDown(KeyCode.Mouse1))
{
   if(controllerObject.isGrounded)
   {
       if(itemManager.mineMe==true)
       { 
           mineAusloesbar = uLink.Network.Instantiate(mineAusloesbarPrefab, 
           new Vector3(transform.position.x,transform.position.y-8,
           transform.position.z), transform.rotation, 0); 
           networkView.RPC("clearBildEnemy", uLink.RPCMode.Others); 
           itemManager.itemsAvatar.renderer.enabled=false; 
           itemManager.mineMe=false;                    
       }
   }
}

In diesem Fall wird geprüft ob der Spieler sich auf dem Boden befindet nachdem er die rechte Maustaste gedrückt hat. Wenn er nun auch wirklich die Mine über seinem Kopf schweben hat mineMe==true wird eine Prefab mineAusloesbar instanziiert, das Symbol des Avatars gelöscht: "clearBildEnemy" und renderer.enabled=false.


Mine Objekt
Nachdem die Mine nun liegt, hat der Spieler der sie gelegt hat 2 Sekunden Zeit wegzulaufen. Danach kann er selbst von ihr getroffen werden.
Erkennbar ist die Mine nicht, sie taucht nur gelegentlich durch ein Flackern der Textur auf. 

Fernkampf

Thursday, November 21, 2013

Fernkampf

In meinem Game soll es möglich sein, den Gegner mit einer Fernkampfattacke zu anzugreifen. Das soll jedoch recht schwierig sein, sodass der Fernkampf in Kombination mit Items wie z.B. der Mine eine höhere Trefferquote hat.


Das heißt, dass die Fernkampfattacke eine Spawnzeit benötigt um den Fernkämpfer eine kurze Zeit bewegungsunfähig zu machen. Somit ist gewährleistet, dass man nicht unendlich viele Male hintereinander schießen kann und der Gegner keine Chance mehr hat zu entkommen.
Sobald die Spawnzeit um ist, fliegt das gespawnte Item los. Bei einer Kollision mit einem anderen Objekt wird das Fernkampfitem zerstört. Falls das getroffene Objekt der Gegner oder man selbst war, werden Lebenspunkte abgezogen und die Bewegungsunfähigkeit tritt ein. Man benötigt demnach eine kurze Erholzeit.

Fernkampfitems

Wenn man den Fernkampf mit Items, welche zufällig im Spiel spawnen, kombiniert hat man also eine höhere Trefferwahrscheinlichkeit und man muss taktisch vorgehen:
Der Gegner kann dem Fernkampf relativ leicht während der Spawnzeit entkommen, also muss ich entweder darauf warten, dass er in eine Mine tritt, oder ihn zuvor mit einer Bombe oder einem Boxhandschuh außer Gefecht setzen. Danach trifft die Fernkampfattacke mit höherer Wahrscheinlichkeit, da mein Gegner während der Spawnzeit noch benommen ist und nicht weglaufen kann.

(Welche Items es geben wird und wie sie Funktionieren, werde ich in den kommenden Posts beschreiben.)

Nun aber noch zur Programmierung des Fernkampfes:


Sobald ein Spieler die Fernkampftaste drückt, wird ein Objekt instanziiert:

if(Input.GetKeyDown(KeyCode.Keypad1))
{
    fernkampfObject = uLink.Network.Instantiate(
        fernkampfPrefab, 
        new Vector3(RPCTest.clickedPlayer.transform.position.x-10,
        RPCTest.clickedPlayer.transform.position.y,
        RPCTest.clickedPlayer.transform.position.z), 
        transform.rotation, 0
    );
}

Danach wird die Flugrichtung festgestellt indem geprüft wird in welche Richtung der Character schaut. Zum Schluss wird das Objekt mit transform.translate  in diese Richtung fortbewegt.

if(startFernkampf==true)
{
    if(RPCTest.flugRichtungLinks==false)
    {
      transform.Translate(Vector3.right *30*Time.smoothDeltaTime);
    }
    if(RPCTest.flugRichtungLinks==true)
    {
      transform.Translate(-Vector3.right *30*Time.smoothDeltaTime);   
    } 
}

Das Fernkampfobjekt hat zusätzlich ein Unterobjekt für die Texturen, genau wie die Playerobjekte auch. Auf diesem wird das gleiche Skript wie das für die Characteranimationen, welches in diesem Post zu finden ist, benutzt.

Leveldesign

Tuesday, October 22, 2013

Leveldesign

Mein Spiel wird zweidimensional, soll aber in einer dreidimensionalen Welt aufgebaut werden. Hierfür habe ich eine eigene Lösung gefunden, welche es mir ermöglicht auf einfache Weise verschiedene Ebenen zu begehen, jedoch die Zweidimensionalität dabei beizubehalten.


Bevor ich euch aber zeige wie das in Unity3D aussieht hier erstmal einen Einblick zur Gestaltung und Idee des Levels. 
Da in meinem Game gekämpft wird wollte ich auch eine entsprechende Atmosphäre erzeugen. Inspiriert hat mich hierbei ein Muay-Thai Boxstadion in Thailand, welches alt, dreckig und düster war. Es war ziemlich verraucht, es wurde gewettet und die "Nummerngirls" waren meiner Meinung nach noch nicht alt genug um Nummerngirls zu sein. Die Stimmung dort war einmalig für mich und hat sich eingeprägt. Mehr zur Atmosphäre und grafischen Gestaltung möchte ich aber noch nicht verraten, zumal diese im Moment auch noch gar nicht fertig ausgearbeitet sind.
Wichtiger für diesen Post ist der Levelaufbau.

In dem besagten Stadion waren mehrere Ebenen zu sehen. Die einheimischen Menschen, welche direkt am Ring mit Klappstühlen saßen, die "VIP"-Sitzplätze, welche erhöht angelegt waren, ganz oben in einem Glasräumchen saßen die Musiker, welche die typische Thai-Musik spielten. Zudem hat mich interessiert wie es hinter den Kulissen aussah, ob es überhaupt so etwas wie einen Trainings- oder Umkleideraum gab oder ob sich diese schlicht und einfach im Hinterhof befinden, was ich mir bei dieser Kultur sehr gut vorstellen kann. Da ich diese Informationen nicht habe, kann ich mir hier gestalterisch freien Lauf lassen.
Daraus ergibt sich mein erster Entwurf:




Ich habe eine Hauptebene (Klappstuhlebene) welche in der Mitte und als erste auf dem Bildschirm zu sehen ist und worauf der Boxring als Hauptelement steht. Hier sind später vermutlich auch die Spawnpunkte der Charaktere.
Desweiteren kann man oben in die VIP-Lounge, in die Umkleidekabinen (wo sich später eventuell die Ziele für Capture The Flag Elemente befinden) und in den Keller wo man vielleicht besondere Items sammeln kann.

Da ich mit der Zeichnung zufrieden war und sich durch die gespiegelte y-Achse keine Unfairness bildet habe ich angefangen das Level mit einfachen Objekten in Unity3D umzusetzen.
Hierbei habe ich darauf geachtet, dass an Stellen wo die Ebene gewechselt wird auch eine Versetzung der Ebenen auf der z-Achse stattfindet.

 


Die rot gefärbten Objekte sind Trigger, auf welchen Skripte liegen, damit an dieser Stelle der Character nach vorn oder nach hinten gesetzt wird. Durch eine orthographische Kamera sieht man diesen Effekt später nicht mehr.
Erste Schritte

Tuesday, October 15, 2013

Erste Schritte

Da ich mir noch nicht genau ausmalen konnte was genau bei meinem Game-Projekt auf mich zu kommt, wollte ich zu erst ausprobieren, wie ich über ein Netzwerk "kommunizieren" kann bzw. wie Spieler Nr. 1 sieht, was Spieler Nr. 2 macht.


Während meiner Recherche bin ich auf ein Tutorial mit dem Unity3D Asset "Photon" gestoßen. 

Also habe ich mich bei exitgames registriert und Schritt für Schritt die Anweisungen befolgt.
Um ehrlich zu sein bin ich überrascht gewesen wie schnell ich begreifen konnte was der YouTuber erklärt hat.
Er hat vor allem gezeigt, wie man sich mit seinem Client zum Server verbindet und geschildert was sogenannte NetworkViews sind. Bald schon hatte ich 2 Clients mit jeweils einem simplen 3D-Objekt, welche ich hin und her schieben konnte, wobei der jeweils andere Client die Bewegung ebenfalls angezeigt hat. 

Euphorisch wie ich war, habe ich sofort daran weiter gearbeitet und meine eigenen Ideen eingebracht. Ich habe zwei Charaktere erstellt, welche auf einem Würfel und einer Plane beruhen, sich mit A,D und Space steuern ließen und darauf sogar eine Animation anzeigen lassen konnten (jedoch waren beide identisch). 


2 Charaktere mit identischer Animation 













Das ist mir zwar relativ schnell gelungen, jedoch bin ich nach ein paar Tagen auch an meine ersten Grenzen gestoßen.

Zum Beispiel: Wie schaffe ich es, dass jeder seine eigene Animation anzeigt und sie nicht identisch sind?
Zudem kam das Problem, dass Photon bei der kostenlosen Version mit einer Cloud arbeitet. Das heißt für mich grob gesagt: Die Information geht von meinem PC übers Internet in eine Cloud und von dort wird die Information bearbeitet und zurück an den zweiten Client gesendet. 
Demnach hätte ich mit einer schlechten Internetverbindung Verzögerungen gehabt.
Für die Prüfung habe ich eine solche Konstellation aufgrund der Gefahr eines Internet Abbruchs auf jeden Fall umgehen wollen!

Also musste eine neue Methode her und meine Euphorie war fürs erste etwas gedämpft...

Sunday, October 13, 2013

Meine Abschlussarbeit

Ich bin seit Oktober im 7. Semester an der Hochschule für Kunst, Design und Populäre Musik und arbeite nun an meiner Abschlussarbeit.Mein Ziel ist es im Februar ein funktionierendes 2D Multiplayer Fighting Game mit Capture The Flag Elementen programmiert und gestaltet zu haben, sodass sich an meiner Prüfung die Prüfer gegenseitig kloppen können!


Der Gedanke, ein Multiplayer-Game umzusetzen hatte ich schon im 4. Semester, da wir hier einen winzigen Einblick in eine Multiplayer-Demo im Unity3D Kurs hatten. Hier durfte sich jeder in das Netzwerk einklinken um Würfel hin und her zu schieben, was auch die anderen auf ihren Bildschirmen sehen konnten. 
Für mich war das eine sehr spannende Sache und ich hatte viele Ideen die ich gerne umsetzen wollte. Trotzdem hatte ich den Gedanken fürs erste verworfen, da andere Kurse und Projekte im Vordergrund standen. 

Als ich dann gegen Ende des 6. Semesters überlegte was ich denn als Abschlussthema behandeln könnte, fiel mir die Wahl nicht schwer. 
Fest stand für mich:

  1. es muss sich bewegen (ich habe mich schon des öfteren mit Video-Schnitt und Animationen beschäftigt und fand es gut)
  2. es muss unbedingt 2 dimensional sein (ich liebe 2D Charaktere)
  3. es muss vor allem Spaß machen und lustig sein (das ist einfach meine Art und es wird schließlich mein Spiel)
  4. ich will programmieren (hier empfinde ich mindestens genauso viel Spaß wie beim Erstellen von 2D Elementen)
  5. toll wäre es, wenn ich mit Unity3D arbeiten könnte (aus Unity3D bestanden meine letzten beiden Semester und ich kannte mich hier schon sehr gut aus)
  6. es muss etwas dabei sein was ich noch nicht kannte (um mich selbst herauszufordern)
  7. es muss innovativ sein

Zusammengesetzt ergibt sich dann mein eigenes 2D Multiplayer Fighting Game mit Capture The Flag Elementen!