|
-
Hit Detection fernkampf
Hey leute,
Ich hab mal eins theoretische Frage da ich mich demnächst damit beschäftigen will.
Und zwar will ich eine neuen fernkampf machen.
Sprich sowas sie Steine werfen zb.
Die Animationen erstellen, oder die Steine dazu sind kein Problem. Meine Frage ist eher ob/wie ich dir Flugbahn festlegen kann und wo ich festlege wann das geschoss trifft (einen Hit auslöst) .
Danke schonmal im voraus
-
Hier muss doch jemand irgendwas wissen
-
Zitat von Ska-Ara
Hey leute,
Ich hab mal eins theoretische Frage da ich mich demnächst damit beschäftigen will.
Und zwar will ich eine neuen fernkampf machen.
Sprich sowas sie Steine werfen zb.
Die Animationen erstellen, oder die Steine dazu sind kein Problem. Meine Frage ist eher ob/wie ich dir Flugbahn festlegen kann und wo ich festlege wann das geschoss trifft (einen Hit auslöst) .
Danke schonmal im voraus
Das ist nicht ganz so einfach. Prinzipiell solltest du dir die Skripte zum freien Zielen anschauen, allerdings kennt sich damit wohl kaum jemand aus, weil es noch sehr neu ist
-
Leider muss ich sagen, dass die Skripte vom freien Zielen da nicht viel weiterhelfen werden. Was meiner Erkenntnis nach aber für so etwas nötig wäre ist, dass man solch ein Wurfitem zum richtigen Zeitpunkt während der Wurfanimation mit einer Projektil-AI [1] versieht. Kollisionsverhalten wird dem Wurfitem dann automatisch über die Projektil-AI beigebracht. Schaden wahrscheinlich auch (wird von der Item-Instanz des Wurfitems bestimmt).
Optional kann man dann die Flugbahn etwas anpassen, wie das in G2 Free Aim der Fall ist, damit die Wurfwaffe nicht schnur-gerade fliegt.
Trotzdem denke ich nicht, dass das so einfach sein wird. Z.B. weiss ich nicht ob man das Item vorher noch selbst an die richtige Position in die Welt einfügen muss.
[1] Dazu müsste man zu erst ein Objekt der Klasse oCAIArrow erstellen und dieses dann an das Wurfitem koppeln mit 0x6A10E0 oCAIArrow::SetupAIVob.
Hier etwas Code, wie das aussehen könnte.
Code:
const int oCItem___CreateNewInstance = 7423040; //0x714440
const int oCItem__oCItem = 7411152; //0x7115D0
const int oCWorld__AddVobAsChild = 7863856; //0x77FE30
const int zCVob__GetRigidBody = 6285664; //0x5FE960
const int oCAIArrow___CreateNewInstance = 6958528; //0x6A2DC0
const int oCAIArrow__SetupAIVob = 6951136; //0x6A10E0
/*
* Funktion aufrufen wenn ein NPC eine Wurfwaffe wirft
* slf ist der werfende NPC, z.B. VLK_987_HansWurst
* itemInstance ist die Item-Instanz, z.B. ItRw_Wurfwaffe
*
* Bemerkungen zu diesem Code:
* - Die Items verursachen weder Schaden noch Reaktion, kollidieren aber.
* - Nach Kollision verhaelt sich die Physik etwas merkwuerdig.
* - Wurfrichtung wird am Node ZS_RightHand ausgerichtet.
* - Die Items werden mit diesem Code nicht von Gothic entfernt und bleiben
* in der Welt liegen. Genau so wenig wird deren AI zerstoert, was ziemlich
* auf die Performance geht und womoeglich Speicherlecks verursacht.
*/
func void throwWeapon(var C_Npc slf, var int itemInstance) {
// Hat der NPC überhaupt die Wurfwaffe im Inventar
if (!Npc_HasItems(slf, itemInstance)) {
return;
};
Npc_RemoveInvItems(slf, itemInstance, 1); // Eine Waffe wird weggeworfen
// other = Gegner, slf = Werfer
Npc_GetTarget(slf);
var int othPtr; othPtr = 0;
if (Hlp_IsValidNpc(other)) {
if (!C_NpcIsDown(other)) { // Separate If-Abfrage, weil Gothic sonst Warnungen wirft
othPtr = _@(other);
};
}; // Else: Ziel wird durch Richtung von ZS_RightHand bestimmt!
// Erstelle Item
const int call = 0;
if (CALL_Begin(call)) {
CALL__cdecl(oCItem___CreateNewInstance); // Das hier allokiert laesst Gothic den Speicher selbst verwalten
call = CALL_End();
};
var int itmPtr; itmPtr = CALL_RetValAsPtr();
const int call2 = 0; const int one = 1;
if (CALL_Begin(call2)) {
CALL_IntParam(_@(one)); // Anzahl
CALL_IntParam(_@(itemInstance));
CALL__thiscall(_@(itmPtr), oCItem__oCItem);
call2 = CALL_End();
};
MEM_WriteString(itmPtr+16, ConcatStrings("PRJ_", slf.name)); // zCVob._zCObject_objectName
// Füge Item in die Welt ein
var int vobtreePtr; vobtreePtr = _@(MEM_Vobtree);
var int worldPtr; worldPtr = _@(MEM_World);
const int call3 = 0;
if (CALL_Begin(call3)) {
CALL_PtrParam(_@(vobtreePtr));
CALL_PtrParam(_@(itmPtr));
CALL__thiscall(_@(worldPtr), oCWorld__AddVobAsChild);
call3 = CALL_End();
};
MEM_WriteInt(itmPtr+260, 3105); // zCVob.bitfield[0] Ich weiss nicht mehr genau welche Flags das sind, aber wichtig
// Erstelle Projektil-AI
const int call4 = 0;
if (CALL_Begin(call4)) {
CALL__cdecl(oCAIArrow___CreateNewInstance); // Das hier allokiert laesst Gothic den Speicher selbst verwalten
call4 = CALL_End();
};
var int aiPtr; aiPtr = CALL_RetValAsPtr();
// Verknüpfe die AI mit dem Item
var int slfPtr; slfPtr = _@(slf);
const int call5 = 0;
if (CALL_Begin(call5)) {
CALL_PtrParam(_@(othPtr)); // Drittes Argument: Ziel
CALL_PtrParam(_@(slfPtr)); // Zweites Argument: Ursprung
CALL_PtrParam(_@(itmPtr)); // Erstes Argument: Item
CALL__thiscall(_@(aiPtr), oCAIArrow__SetupAIVob);
call5 = CALL_End();
};
// Optional: Flugbahn anpassen (angepasst aus G2 Free Aim)
// RigidBody holen/erstellen
const int call7 = 0;
if (CALL_Begin(call7)) {
CALL__thiscall(_@(itmPtr), zCVob__GetRigidBody); // Get ridigBody this way, it will be properly created
call7 = CALL_End();
};
var int rBody; rBody = CALL_RetValAsInt(); // zCRigidBody*
// Gravitation setzen aber noch nicht aktivieren
MEM_WriteInt(rBody+236, castToIntf(0.1)); // zCRigidBody.gravity
// Gravitation nach 200 ms starten
FF_ApplyOnceExtData(throwWeaponApplyGravity, 200, 1, rBody);
};
/* Diese Funktion ist aus G2 Free Aim kopiert */
func void throwWeaponApplyGravity(var int rigidBody) {
if (!rigidBody) || (!MEM_ReadInt(rigidBody)) { return; };
if (MEM_ReadInt(rigidBody+188) == FLOATNULL) // zCRigidBody.velocity[3]
&& (MEM_ReadInt(rigidBody+192) == FLOATNULL)
&& (MEM_ReadInt(rigidBody+196) == FLOATNULL) { return; }; // Do not add gravity if projectile already stopped moving
MEM_WriteByte(rigidBody+256, 1); // Turn on gravity (zCRigidBody.bitfield)
};
Diese Funktion könnte man aufrufen, wenn der Spieler eine Taste drückt (für NPCs sollte der Code auch gehen). Z.B. so:
Code:
func void throwingAbility() { // Aufgerufen wenn man eine bestimmte Taste drückt
throwWeapon(hero, ItRw_Wurfwaffe);
};
Auch wenn das ganz schön verfeinert aussieht, habe ich den Code gerade einfach runtergeschrieben und habe keine Ahnung, ob das so funktionieren könnte. Ausserdem fehlt noch einiges, z.B. eine Eingrenzung wann der Spieler Wurfwaffen werfen darf (nicht im Menu, nicht in Dialogen, nicht während dem Fernkampf, ...). Auf jeden Fall solltest du, bevor du dich ran setzt deine Animationen zu erstellen, erst einen Weg finden, mit dem die Wurfmechanik tatsächlich geht.
Geändert von mud-freak (03.03.2017 um 20:19 Uhr)
Grund: Code aktualisiert
-
Heisst aber von haus aus könnte Gothic sowas nicht machen?
Man braucht dazu Ikarus/Lego?
-
Zitat von Ska-Ara
Heisst aber von haus aus könnte Gothic sowas nicht machen?
Man braucht dazu Ikarus/Lego?
Der Code von mud-freak braucht prinzipiell erstmal nur Ikarus.
Ob es auch ohne geht, weiß ich nicht. Im Endeffekt (abgesehen von der Flugbahn) sollte sich das sicherlich auch durch geänderte Animationen etc. erreichen lassen.
-
Daaaaaaaann.. teste ich mal rum. Danke erstmal für den ganzen Input!
-
Ich glaub ich hab dich falsch verstanden. Dir geht es darum den bestehenden Fernkampf zu ersetzen? Sprich anstatt einem Bogen zu spannen und abzuschiessen, wirft man ein Wurfmesser? Wenn ja, brauchst du dir um Kollsion keine Gedanken zu machen. Das macht Gothic dann automatisch.
Du müsstest also die Armbrust animation "überschreiben" (bei Bögen will Gothic noch die Spannanimation auf den Bogen anwenden, wo es zu Problemen kommen könnte). Da müsstest du ein Wurfmesseritem erstellen das man anlegen kann und ein zweites als Munition. Das erste Wurfmesseritem erstellst du als Armbrust und setzt als Munition die Wurfmessermunitionsinstanz. Das sollte es schon gewesen sein.
Dann ist natürlich nur das Problem, wie du das im Inventar am geschicktesten anzeigen lassen willst (vielleicht kannst du das Munitionsitem jeweils erst beim Werfen erstellen) und du müsstest immer ein Animationsoverlay an und ausschalten, je nachdem ob man ein Wurfmesser oder eine Armbrust anlegt.
-
-
Hier noch einige Dinge, die mir einfallen, die du vorher in Betracht ziehen solltest.
- Die Rotation von Projektilen passt sich nicht die Flugbahn an. D.h. wenn du eine Krümmung der Flugbahn einbaust, bleibt ein Speer in der gleichen Ausrichtung, wie er abgeworfen wurde und wird nicht etwa mit der Speerspitze zu erst im Boden aufkommen.
- Genauso dreht sich ein Projektil auch nicht mit. D.h. Wurfmesser fliegen mit der Spitze nach vorn was sicherlich etwas merkwürdig aussehen könnte.
- Bisher ist mir noch keine verlässliche Methode bekannt, die Fluggeschwindigkeit für individuelle Projektile zu bestimmen (damit meine ich, falls Steine z.B. schneller fliegen sollen als Speere). Siemekk hat zwar hier die Fluggeschwindigkeit geändert, allerdings verändert er da die Masse des Projektils, nicht dessen Geschwindigkeit. Das hat einige unschöne Seiteneffekte und würde ich nicht empfehlen.
- Ich fürchte auch ohne Änderung der Flugbahn kommst du um Ikarus nicht herum, wenn du vernünftige Handhabung des Equippens, Ziehens und Wegsteckens der Waffen und deren Munition einbauen möchtest.
Das zähle ich nur auf, damit du vielleicht mit den Wurfitems anfängst und es etwas testest bevor du dich an die Animationen setzt.
EDIT: Der Code oben funktioniert übrigens nur halb, aber er ist ein guter Ansatz, falls mal jemand Wurfwaffen auf Knopfdruck einbauen will (so zu sagen als Sekundärwaffe, wie in Risen 2 die Wurfmesser). Hier die Einschränkungen die ich feststellen konnte:
- Die Items verursachen weder Schaden noch Reaktion, kollidieren aber.
- Nach Kollision verhaelt sich die Physik etwas merkwuerdig.
- Wurfrichtung wird am Node ZS_RightHand ausgerichtet.
- Die Items werden mit diesem Code nicht von Gothic entfernt und bleiben in der Welt liegen. Genau so wenig wird deren AI zerstoert, was ziemlich auf die Performance geht und womoeglich Speicherlecks verursacht.
Geändert von mud-freak (03.03.2017 um 20:18 Uhr)
Grund: Einschränkungen aufgelistet
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|
|