I've set this one on the back burner because it was never really a big priority, and I take a look at it every now and then but I just can't figure out the problem. So what the heck, I'm just gonna make a big 'ol post here with a lot of code and see if anyone has any ideas how to solve this.
The desired effect:
When the player attacks there is a visible sword-slash graphic that appears before him. It is visible for the exact duration of the portion of the attack that is actually damaging other actors, and then disappears.
The sword slash only appears some of the time. There is no pattern to when it does or does not, save that most of the time it does not. I might see it appear after five tries or after sixteen. I can stand, I can jump, I can move, I can spam the attack button, I can wait between attacks, there is nothing in my action that determines if it will work or not.
Curiously, the effect seems to be more/less successful depending upon the level I am testing it in.
When the pawn is spawned it creates a "melee actor" that is attached to itself at a desired offset. The melee actor is a simple static mesh of a rectangular billboard (with a custom collision) with the slash effect on it. This actor is what handles the actual damaging effects on other actors. When spawned the material is set to a "blank" image.
When the player attacks it triggers a sequence of timers. At the desired moment after the trigger the attached mesh is sent into it's active state where it damages other actors, and it's material is changed to the visible material. A moment later the next trigger sends the mesh into its inactive state, which switches the material back to the blank one.
I have also tried to make the mesh hidden instead of switching the material, but it has the same effect.
Player Melee Actor:
function AssignSword(PlayerMeleeActor SentActor)
`log("Assigning Sword to Player Controller...");
sword = SentActor;
exec function MeleeAttack()
if(pawn != None && !bPlayerInAttack)
//wind-up,animation starts (duration: 0.04)
setTimer(0.4, false, nameof(StopAttack) );
//Pitch, attack becomes active (duration: 0.01)
setTimer(0.04, false, nameof(MakeSwordActive) );
//cool-down, attack becomes inactive and animation finishes. (duration: 0.35)
setTimer(0.05, false, nameof(MakeSwordInert) );
class PlayerMeleeActor extends actor;
var actor Controller;
var actor OwnerPawn;
var StaticMeshComponent Mesh;
var int MeleeAttackDamage;
var vector AttackMomentum;
function setSwordController(actor SentActor)
`log("Assigning Controller to Player Melee Actor...");
Controller = SentActor;
function setOwningPawn(actor SentActor)
`log("Assigning Pawn to Player Melee Actor...");
OwnerPawn = SentActor;
function BeginState( Name PreviousStateName)
local Actor HitActor;
local vector Hitloc;
foreach TouchingActors(class 'actor', HitActor)
if (HitActor != OwnerPawn)
HitActor.TakeDamage(MeleeAttackDamage, Instigator.Controller, HitLoc, AttackMomentum, class'DamageType');
function EndState( Name NewStateName)
function touch(Actor TouchedActor, PrimitiveComponent OtherComp, vector HitLoc, vector HitNormal )
if (TouchedActor != OwnerPawn)
TouchedActor.TakeDamage(MeleeAttackDamage, Instigator.Controller, HitLoc, AttackMomentum, class'DamageType');
//gotostate('Inert'); //from an older version
auto state inert
// Add the static mesh component
Begin Object Class=StaticMeshComponent Name=MyStaticMeshComponent
As my code can attest, I'm pretty new to programming, so I welcome any advice.
function PossessedBy(Controller C, bool bVehicleTransition)
Sword = Spawn(class'PlayerMeleeActor');
MCPController = MCPlayerController(Controller);