Jump to content
Unity Insider Forum
Sign in to follow this  
AgentCodeMonkey

RPG Basics - Abilities - Teil 3

Recommended Posts

Hallo zusammen,

 

Beim letzten Mal haben ich ja gezeigt wie man seine Fähigkeiten mit einem "Cooldown" versehen kann. In dieser Runde werde ich euch zeigen, wie man grundlegend ein Kampfsystem angehen kann. Dabei sei wie immer gesagt, dass es sich um das Prinzip handelt und das Ganze natürlich weiter ausgebaut werden kann (und muss).

 

Ziel ist es am Ende zwei Testattacken nutzen zu können, die mit einem Cooldown versehen sind. Diese Attacken machen anhand von unterschiedlichen Charakterwerten Schaden am Gegner. Dinge wie Animationen und der damit verbundene Zeitversatz zwischen Auslösen der Attacke und der verzögerten übermittlung des Schadenswertes werden komplett vernachlässigt.(der Schaden sollte ja nicht schon am Gegner abgezogen werden, während der Angreifer erst zum Schlag ausholt)

 

Wer das Tutorial nachvollziehen möchte, sollte vorher Teil 1 und Teil 2 gemacht haben.

 

Zuerst einmal müssen wir klarstellen, wen wir angreifen. Dafür erweitern wir das Player.cs ganz simpel um

public GameObject target;

.

 

Cool sind auch ein paar klassische RPG-Werte mit denen man arbeiten kann. Die kommen ebenfalls in die Player.cs

 

AttackStat strength;
AttackStat agility;
int healthpoints = 100;

 

AttackStat ist ein enum und sieht folgendermaßen aus:

 

public enum AttackStat
{
Strength,
Agility,
Intellect
//...Spirit, Will.... etc
}

 

schreibt es im Script üBER die Player-Klasse in Player.cs. Enums eigenen sich für solche Dinge recht gut, da sich hier ein definierter Name und ein Wert an einer Stelle speichern lassen.

 

Außerdem muss noch die Start Methode angepasst werden und wird um folgende Zeile erweitert:

 

	strength = (AttackStat)10;
	agility = (AttackStat)10;
	healthpoints = 110;

 

Für ein Kampfsystem brauchen wir natürlich noch: Attacken. Was sind Kämpfe schon ohne Attacken?! :)

 

Dafür legen wir eine neues C#-Script an und nennen es Attack

 

using UnityEngine;
using System.Collections;
public class Attack
{
}

 

Dieses Script dient als Basisklasse und natürlich können spezielle Attacken davon erben. Für den Anfang reicht aber dieses eine Script.

 

Um die Attacken nutzen zu können legen wir nun noch eine Variable in der Player.cs an

 

 

Attack _attack;

 

und initialisieren sie in der Start Methode mit

 

 

_attack = new Attack();

 

 

 

Jetzt kann zwar eine Instanz von Attack erzeugt werden, aber was sollte da mit schon passieren? es braucht noch eine kleine Methode und ein paar Variablen.

 

using UnityEngine;
using System.Collections;

public class Attack
{
public int baseDamage = 10; // Basisschaden der attacke
public void attack(Player attacker, Player defender, float _damageMultiplier, AttackStat _stat)
{
	defender.DoDamage((int)(baseDamage + attacker.GetStatValue(_stat) * _damageMultiplier));
}
}

 

Was genau ist DoDamage und GetStatValue?

 

Ersteres ist nichts anderes als eine einfache Methode, die unsere Healthpoints in Player.cs bearbeitet:

 

 

public void DoDamage(int _damage)
{
	if (healthpoints > 0)
	{
		healthpoints -= _damage;
	}
	else
		healthpoints = 0;
}

 

 

GetStatValue sieht folgendermaßen aus:

 

public int GetStatValue(AttackStat s)
{
	switch (s)
	{
		case AttackStat.Strength:
			return (int)AttackStat.Strength;
		case AttackStat.Agility:
			return (int)AttackStat.Agility;
		default: return 1;
	}
}

 

Um das Ganze zu vereinfachen gibt GetStatValue anhand des AttackStat dessen Wert zurück. Hier wäre Platz für Formeln, oder besser noch ein Aufruf eines Scripts, das aus dem AttackStat einen neuen Wert wie AttackPower berechnet und zurückgeben kann! In unserem Fall ist es nur der Strength-Wert, also 10.

 

Wenn also der Attacker seine Attacke auslöst, wird in der Attack-Klasse anhand dessen Werte berechet, welchen Schaden der Defender (der Angegriffene/Verteidiger) bekommt. Auch hier lässt sich noch viel machen, zb. um den Schaden anhand eines Wertes des Defenders zu verringern.

 

Soetwas kann dann so aussehen: (bitte nicht in das Script einfügen)

 defender.DoDamage((int)(baseDamage + attacker.GetStatValue(_stat) * _damageMultiplier) - defender.GetStatValue(AttackStat.DamageReduce)); 

DamageReduce muss dann jedoch im enum angelegt werden und natürlich initialisiert werden!

 

Damit die Attacken nun bei Knopfdruck aktiviert werden, bzw die Schadenswerte auch an den Defender übermittelt werden, muss die attack-Methode ausgelöst werden.

Dies geschieht in Player.cs, in der Update-Methode und zwar dann, wenn der Knopf gedrückt wurde und der CoolDown bei 0 ist.

 

_attack.attack(this, target.GetComponent<Player>(), ABILITIES["Mortal Strike"]._damageModifier, strength);

wir übergeben "this", also die Player.cs aus der die Attacke ausgelöst wird, das Player.cs-Script des Ziels, den Modifier der Fähigkeit und den Wert, der die Attacke beeinflusst.

 

Gleiches gilt für die andere Attacke:

 

 _attack.attack(this, target.GetComponent<Player>(), ABILITIES["Heroic Strike"]._damageModifier, agility);

 

 

Nun Geht es an Testen und dafür kopieren wir das GameObject des Spielers und nennen es Defender. Für die Qick and Dirty Variante habe ich anfangs drei bools in die Player.cs genommen:

 

 

public bool useAbilities = true;
public bool showHealth = true;
public bool showCooldowns = true;

 

 

stellt diese im Inspector beim Player auf: useAbilities = true; showHealth = false und showCooldowns = true;

 

Beim Defender stellt alles auf false, bis auf showHealth, das sollte true sein,

 

 

 

Die OnGUI-Methode muss nun noch angepasst werden, denn sonst sehen wir ja nichts.

 

void OnGUI()
{
	if (showCooldowns)
	{
		GUILayout.Label("press key 1 or 2");
		foreach (KeyValuePair<string, Ability> _kvp in ABILITIES)
		{
			GUILayout.Label("attackers CoolDown :" + _kvp.Value._name + " ready in: " + _kvp.Value._coolDownTimer.ToString());
		}
	}
	if (showHealth)
	{
		GUILayout.BeginArea(new Rect(50, 125, 250, 250));
		GUILayout.Label("Defenders Health :" + healthpoints.ToString());
		GUILayout.EndArea();
	}
}

 

Nun muss beim Player der Defender in den GameObject-Slot des Inspector gezogen werden und andersherum, damit wir auch ein target haben.

 

Nun sollte dem Defender Healthpoints abgezogen werden, wenn man die Attacken ausführt :)

 

Hier der Dropbox-Link. zur aktuellsten Version 1_7

 

Und viel Spass beim erweitern dieses Systems :)

Edited by AgentCodeMonkey
  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...