Simple Sword Collision
by Andy Hawkins · in Torque Game Engine · 05/22/2006 (3:22 am) · 8 replies
I've found Dreamer's Melee system and the "Hand to Hand Combat, Locational Damage and Collision and More." tut on GG but this is like 60 pages and a mod to the engine.
Is there a simple way to detect sword hits?
I had this idea.
1) Get the frames in the animation where the sword should actually hit something - like when it's striking forward.
2) Do a ray check or proximty check from the characters direction to the length of the sword and see if it's colliding with any other character
3) Do damage.
I don't think this idea would work on a server though.
Can anyone point me in the right direction please?
Is there a simple way to detect sword hits?
I had this idea.
1) Get the frames in the animation where the sword should actually hit something - like when it's striking forward.
2) Do a ray check or proximty check from the characters direction to the length of the sword and see if it's colliding with any other character
3) Do damage.
I don't think this idea would work on a server though.
Can anyone point me in the right direction please?
#2
05/22/2006 (4:57 am)
Quote:We use this method for a knife quite effectively. You'll be surprised what you can achieve, quite simply, when you know how to set up the weapon state system.
Maybe you could have the fists/sword fire an invisible projectile at a very short distance from the player.
#3
This is our state setup for a repair gun with the ability to heal the player using it, other players you target with it and any vehicles within range.
05/22/2006 (5:04 am)
This example doesn't help you with your specific task, however it does serve as a good example of how flexible the weapon state system is when you know how to use it.This is our state setup for a repair gun with the ability to heal the player using it, other players you target with it and any vehicles within range.
// Initial start up state stateName[0] = "Activate"; stateTransitionOnTimeout[0] = "ActivateReady"; stateTimeoutValue[0] = 0.25; stateName[1] = "ActivateReady"; stateScript[1] = "onActivateReady"; stateSpinThread[1] = Stop; stateTransitionOnAmmo[1] = "Ready"; stateTransitionOnNoAmmo[1] = "ActivateReady"; stateName[2] = "Ready"; stateSpinThread[2] = Stop; stateTransitionOnNoAmmo[2] = "Deactivate"; stateTransitionOnTriggerDown[2] = "Validate"; stateName[3] = "Validate"; stateTransitionOnTimeout[3] = "Validate"; stateTimeoutValue[3] = 0.2; stateEnergyDrain[3] = 3; stateSpinThread[3] = SpinUp; stateScript[3] = "onValidate"; stateIgnoreLoadedForReady[3] = true; stateTransitionOnLoaded[3] = "Repair"; stateTransitionOnNoAmmo[3] = "Deactivate"; stateTransitionOnTriggerUp[3] = "Deactivate"; stateName[4] = "Repair"; stateSound[4] = RepairPackFireSound; stateScript[4] = "onRepair"; stateSpinThread[4] = FullSpeed; stateAllowImageChange[4] = false; stateSequence[4] = "activate"; stateFire[4] = true; stateEnergyDrain[4] = 9; stateTimeoutValue[4] = 0.2; stateTransitionOnTimeOut[4] = "Repair"; stateTransitionOnNoAmmo[4] = "Deactivate"; stateTransitionOnTriggerUp[4] = "Deactivate"; stateTransitionOnNotLoaded[4] = "Validate"; stateName[5] = "Deactivate"; stateScript[5] = "onDeactivate"; stateSpinThread[5] = SpinDown; stateSequence[5] = "activate"; stateDirection[5] = false; stateTimeoutValue[5] = 0.2; stateTransitionOnTimeout[5] = "ActivateReady";
#4
05/22/2006 (5:11 am)
I have done exactly what you mentioned Andy. Don't have the code on hand for you, but its definately do-able, on the server.
#5
This is my simple melee setup for a weapon (in this case a copper dagger which you may find as a good base..
This defines the weapon, generates a swing sequence (assuming you have one) and merges the anim with whatever elseis going on, generates an audio emitter for the sound and also a couple of particle effects for blood splatters on a hit and then deletes them all to make it clean again.
You'll need to get a swing sequence and get sounds etc to complete this, but the basics are here and you could comment out the swings, sounds and splats for now to get started and demonstrates the generation of an eye vector to get a close range hit on a mob :)
then you just need a melee command in default bind such as
I have left out all the usual stuff about adding to inv etc to get the weapon in game but hope this helps :)
Regards
Graham Evans
(Project Endeavour)
05/22/2006 (7:15 am)
Hi Andy..This is my simple melee setup for a weapon (in this case a copper dagger which you may find as a good base..
This defines the weapon, generates a swing sequence (assuming you have one) and merges the anim with whatever elseis going on, generates an audio emitter for the sound and also a couple of particle effects for blood splatters on a hit and then deletes them all to make it clean again.
You'll need to get a swing sequence and get sounds etc to complete this, but the basics are here and you could comment out the swings, sounds and splats for now to get started and demonstrates the generation of an eye vector to get a close range hit on a mob :)
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Weapon Item. This is the item that exists in the world, i.e. when it's
// been dropped, thrown or is acting as re-spawnable item. When the weapon
// is mounted onto a shape, the Copper_SaiImage is used.
datablock ItemData(Copper_Sai)
{
category = "Weapon";
className = "Weapon";
shapeFile = "~/data/shapes/sai/copper/sai.dts";
mass = 1;
elasticity = 0.2;
friction = 0.6;
orbitdist = 1;
emap = true;
pickUpName = "Copper Sai";
image = Copper_SaiImage;
};
datablock ShapeBaseImageData(Copper_SaiImage)
{
shapeFile = "~/data/shapes/sai/copper/sai.dts";
emap = true;
mountPoint = 0;
offset = "0 0 0";
//eyeOffset = "0.4 0.4 -0.6";
eyeOffset = "0 0 0";
damage = 10;
correctMuzzleVector = false;
className = "WeaponImage";
item = Copper_Sai;
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateName[1] = "Activate";
stateSequence[1] = "Activate";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.1;
stateName[2] = "Ready";
stateTransitionOnTriggerDown[2] = "Fire";
stateName[3] = "Fire";
stateSequence[3] = "Fire";
statescript[3] = "OnFire";
stateTransitionOnTimeout[3] = "Ready";
stateTimeoutValue[3] = 1.5;
};
function Copper_SaiImage::OnFire(%this, %obj, %slot)
{
%knifesound = new AudioEmitter()
{
position = %obj.position;
fileName = "~/data/sound/fx/staffslash.wav";
description = AudioClose3d; //for loud sound
preload = false;
};
%this.killit = %this.schedule(1000,"KillCopperSaiSound",%knifesound);
%player = %obj.client.player;
%player.playThread(1,"stab");
%this.PlaySchedule = schedule( 1000, 0, stopplay, %this, %player);
// ~~~~ chose vector from player with short range to see if hit ~~~~~~~
%eye = %player.getEyeVector();
%vec = vectorScale(%eye, 3); // distance we can hit from
%start = %player.getEyeTransform();
%end = VectorAdd(%start,%vec);
%found = ContainerRayCast (%start, %end, $TypeMasks::PlayerObjectType, %player);
// ~~~~~ if we got a target then damage it and create a hit sound ~~~~~~~~~~~~~
if (%found>0)
{
// ~~~~~~ hit sound emitter create ~~~~~~~~~~~
%hitsound = new AudioEmitter()
{
position = %obj.position;
fileName = "~/data/sound/fx/knifehit.wav";
description = AudioClose3d; //for loud sound
preload = false;
};
%this.killit = %this.schedule(2000,"KillCopperSaiSound",%hitsound);
%mypos = %obj.getposition();
%transform = %found.getTransform();
%posX = getWord(%transform, 0);
%posY = getWord(%transform, 1);
%posZ = getWord(%transform, 2);
%posX = %posX;
%posY = %posY;
%posZ = %posZ + 1.5;
%posZ2 = %posZ + 0.5;
%position = %posX SPC %posY SPC %posZ SPC 0 SPC 0 SPC 0 SPC 1;
%position2 = %posX SPC %posY SPC %posZ2 SPC 0 SPC 0 SPC 0 SPC 1;
//~~~~~ create blood splats from hit ~~~~~~~~~~~~
%this.blood1 = %this.schedule(250,"CopperSaibloodfx",%position);
%this.blood2 = %this.schedule(500,"CopperSaibloodfx",%position2);
%theirpos = %found.getposition();
%vector = VectorSub(%theirpos, %mypos);
%vector = VectorNormalize(%vector);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Damage 10 on Copper sai. min 5 max 15 base from Copper_SaiImage datablock
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%lowerdamage = %this.damage - 5;
%upperdamage = %this.damage + 5;
%hitdamage = getRandom(%lowerdamage,%upperdamage); // random 15 - 25
//~~~~~ APPLY DAMAGE ~~~~~~~~~~~~~~~~~~~~~
%found.getDataBlock().damage(%found, %obj, %vector, %hitdamage, "Melee");
}
}
//~~~~ stop animation after one swing ~~~~~~~
function stopplay(%this,%player)
{
%player.stopThread(1);
}
//~~~~~ kill hit sound ~~~~~~~~~~~~
function Copper_SaiImage::KillCopperSaiSound(%this, %soundtokill)
{
%soundtokill.delete();
}
//~~~~~ generate blood splat ~~~~~~~~
function Copper_SaiImage::CopperSaibloodFX(%this, %pos)
{
%bloodobj = new ParticleEmitterNode() {
position = %pos;
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "RedBloodSplatEmitterNode";
emitter = "RedBloodSplatEmitter";
velocity = "7";
};
%bloodobj.schedule(1000, "delete");
}then you just need a melee command in default bind such as
function Melee(%val)
{
$mvTriggerCount0++;
}
moveMap.bind( keyboard, n, Melee );I have left out all the usual stuff about adding to inv etc to get the weapon in game but hope this helps :)
Regards
Graham Evans
(Project Endeavour)
#6
05/22/2006 (7:22 am)
@Graham - excellent - thanks very much, this will do nicely :)
#7
Thanks in advance,
05/23/2006 (8:56 am)
Hum... any ideia how can I implement a melee system in tutorial.base ? I already added the gun and damage(with the tutorial of codesampler). Thanks in advance,
#8
05/23/2006 (9:51 am)
I believe grahams code would do that.
Torque 3D Owner iHugMedia