Download

Flying Ragdolls

This isn’t really problem, but I just want the bots to burn, not fly away like rockets!

In the image the molotov has just landed. The result as you may see, ragdolls blasted in all directions. I wouldn’t mind so much if that was the result of the grenades. Here’s all the projectile code, but I think the problem can be fixed with a defaultproperties setting. Which defaultproperty setting I don’t know. Maybe you know? Have some clues? I’ve messed around and messed around with it, as one does but no change XD.

The log just fyi (irrelevant because I think it’s the result of the molly explosion tossing the ragdoll into the hinterland. Sometimes it’s ugly with what looks to be single pixels stretching forever as the ragdoll whirls into the distance - again, more annoying than a problem) :[0174.29] Log: Octree Warning (AddPrimitive): SkeletalMeshComponent_108 (Owner: uedpiekfz-weaponstest.TheWorld:PersistentLevel.KFZzCivFemB_12) Outside World.



simulated function PostBeginPlay()
{
    Super.PostBeginPlay();
    SetTimer(2.5+FRand()*0.5,false);                  //Molotov begins unarmed
    RandSpin(20000);//100000);
}

function Init(vector Direction)
{
    SetRotation(Rotator(Direction));
    Velocity = Speed * Direction;
    TossZ = TossZ + (FRand() * TossZ / 4.0) - (TossZ / 5.0);   //prev: 4.0 5.0 and was too curly
    Velocity.Z += TossZ;
    Acceleration = AccelRate * Normal(Velocity);
}
//  Explode
simulated function Timer()
{
    KFZPawn(Instigator).MakeNoise(21.0, 'GunFire');
    Explode(Location, vect(0,0,1));
    Spawn(class'VolumeFireKFZ',,,);
}
// Give a little bounce
simulated event HitWall(vector HitNormal, Actor Wall, PrimitiveComponent WallComp)
{
    bBlockedByInstigator = true;
    if ( WorldInfo.NetMode != NM_DedicatedServer )
    {
        PlaySound(ImpactSound, false,,true,,false);
        }
         // check to make sure we didn't hit a pawn
        if ( Pawn(Wall) == none )
        {
            Velocity = 0.75*(( Velocity dot HitNormal ) * HitNormal * -2.0 + Velocity);
            Speed = VSize(Velocity);  

                if (Velocity.Z > 400)  
                {
                    Velocity.Z = 0.5 * (400 + Velocity.Z);
            }
        // If we hit a pawn or we are moving too slowly, explod

                    if ( Speed < 20 || Pawn(Wall) != none )
                    {
                        ImpactedActor = Wall;
                        SetPhysics(PHYS_None);
                    }
        }
        else if (Wall != Instigator )     // Hit a different pawn, just explode
        {
            Explode(Location, HitNormal);
            bSuppressExplosionFX = true;
            ImpactedActor = none;
            super.HitWall(HitNormal,Wall,WallComp);
    }
}

// When a Molotov enters the water, kill effects/velocity and let it sink
simulated function PhysicsVolumeChange( PhysicsVolume NewVolume )
{
    if ( WaterVolume(NewVolume) != none )
    {
        Velocity *= 0.25;
    }
    Super.PhysicsVolumeChange(NewVolume);
}

simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{//Gaz661
    super.ProcessTouch(Other, HitLocation, HitNormal);  //trying to silence Molotov explode which happens when Civs burn

    if (DamageRadius > 0.0)
    {
//        Explode( HitLocation, HitNormal ); COMMented but still molly explode sound on Damage
        Spawn(class'VolumeFireKFZ',,,);
        SetTimer(23.0,false,'Shutdown');  ///3.0
        bSuppressExplosionFX = true;
        Other.TakeDamage(Damage,InstigatorController,HitLocation,MomentumTransfer * Normal(Velocity), MyDamageType,, self);
    }
    else
    {       Spawn(class'VolumeFireKFZ',,,);
        Other.TakeDamage(10,InstigatorController,HitLocation,MomentumTransfer * Normal(Velocity), MyDamageType,, self);
        SetTimer(1.0,false,'Shutdown');//Shutdown();
    }
}

simulated function Explode(vector HitLocation, vector HitNormal)
{
    if (Damage>0 && DamageRadius>0)
    {
        if ( Role == ROLE_Authority )
            MakeNoise(21.0);
        if ( !bShuttingDown )
        {
            ProjectileHurtRadius(HitLocation, HitNormal );
        }
    }
    SpawnExplosionEffects(HitLocation, HitNormal);

    ShutDown();
}
//////////////////////////////////
simulated function Shutdown()
{
    local vector HitLocation, HitNormal;

    bShuttingDown=true;
    HitNormal = normal(Velocity * -1);
    Trace(HitLocation,HitNormal,(Location + (HitNormal*-32)), Location + (HitNormal*32),true,vect(0,0,0));

    SetPhysics(PHYS_None);

    if (ProjEffects!=None)
    {
        ProjEffects.DeactivateSystem();
    }

    if (WorldInfo.NetMode != NM_DedicatedServer && !bSuppressExplosionFX)
    {
        SpawnExplosionEffects(Location, HitNormal);
    }

    HideProjectile();
    SetCollision(false,false);

    // If we have to wait for effects, tweak the death conditions

    if (bWaitForEffects)
    {
        if (bNetTemporary)
        {
            if ( WorldInfo.NetMode == NM_DedicatedServer )
            {
                // We are on a dedicated server and not replicating anything nor do we have effects so destroy right away
///                Destroy();
            }
            else
            {
                // We can't die right away but make sure we don't replicate to anyone
///                RemoteRole = ROLE_None;
                // make sure we leave enough lifetime for the effect to play
                LifeSpan = FMax(LifeSpan, 35.0); //how long?!
            }
        }
        else
        {
            bTearOff = true;
            if (WorldInfo.NetMode == NM_DedicatedServer)
            {
                LifeSpan = 0.35;
            }
            else
            {
                // make sure we leave enough lifetime for the effect to play
                LifeSpan = FMax(LifeSpan, 35.0);
            }
        }
    }
    else
    {
        Destroy();
    }
}
//-----------------------------------------//
simulated function SpawnExplosionEffects(vector HitLocation, vector HitNormal)
{
    local vector LightLoc, LightHitLocation, LightHitNormal;
    local vector Direction;
    local ParticleSystemComponent ProjExplosion;
    local Actor EffectAttachActor;
    local MaterialInstanceTimeVarying MITV_Decal;

    if (WorldInfo.NetMode != NM_DedicatedServer)
    {
        if (ProjectileLight != None)
        {
            DetachComponent(ProjectileLight);
            ProjectileLight = None;
        }
        if (ProjExplosionTemplate != None && EffectIsRelevant(Location, false, MaxEffectDistance))
        {
            // Disabling for the demo to prevent explosions from attaching to the pawn...
//            EffectAttachActor = (bAttachExplosionToVehicles || (UTVehicle(ImpactedActor) == None)) ? ImpactedActor : None;
            EffectAttachActor = None;
            if (!bAdvanceExplosionEffect)
            {
                ProjExplosion = WorldInfo.MyEmitterPool.SpawnEmitter(ProjExplosionTemplate, HitLocation, rotator(HitNormal), EffectAttachActor);
            }
            else
            {
                Direction = normal(Velocity - 2.0 * HitNormal * (Velocity dot HitNormal)) * Vect(1,1,0);
                ProjExplosion = WorldInfo.MyEmitterPool.SpawnEmitter(ProjExplosionTemplate, HitLocation, rotator(Direction), EffectAttachActor);
                ProjExplosion.SetVectorParameter('Velocity',Direction);
                ProjExplosion.SetVectorParameter('HitNormal',HitNormal);
            }
            SetExplosionEffectParameters(ProjExplosion);

            if ( !WorldInfo.bDropDetail && ((ExplosionLightClass != None) || (ExplosionDecal != none)) && ShouldSpawnExplosionLight(HitLocation, HitNormal) )
            {
                if ( ExplosionLightClass != None )
                {
                    if (Trace(LightHitLocation, LightHitNormal, HitLocation + (0.25 * ExplosionLightClass.default.TimeShift[0].Radius * HitNormal), HitLocation, false) == None)
                    {
                        LightLoc = HitLocation + (0.25 * ExplosionLightClass.default.TimeShift[0].Radius * (vect(1,0,0) >> ProjExplosion.Rotation));
                    }
                    else
                    {
                        LightLoc = HitLocation + (0.5 * VSize(HitLocation - LightHitLocation) * (vect(1,0,0) >> ProjExplosion.Rotation));
                    }

                    UDKEmitterPool(WorldInfo.MyEmitterPool).SpawnExplosionLight(ExplosionLightClass, LightLoc, EffectAttachActor);
                }

                // this code is mostly duplicated in:  UTGib, UTProjectile, UTVehicle, UTWeaponAttachment be aware when updating
                if (ExplosionDecal != None && Pawn(ImpactedActor) == None )
                {
                    if( MaterialInstanceTimeVarying(ExplosionDecal) != none )
                    {
                        // hack, since they don't show up on terrain anyway
                        if ( Terrain(ImpactedActor) == None )
                        {
                        MITV_Decal = new(self) class'MaterialInstanceTimeVarying';
                        MITV_Decal.SetParent( ExplosionDecal );

                        WorldInfo.MyDecalManager.SpawnDecal(MITV_Decal, HitLocation, rotator(-HitNormal), DecalWidth, DecalHeight, 10.0, FALSE );
                        //here we need to see if we are an MITV and then set the burn out times to occur
                        MITV_Decal.SetScalarStartTime( DecalDissolveParamName, DurationOfDecal );
                    }
                    }
                    else
                    {
                        WorldInfo.MyDecalManager.SpawnDecal( ExplosionDecal, HitLocation, rotator(-HitNormal), DecalWidth, DecalHeight, 10.0, true );
                    }
                }
            }
        }

        if (ExplosionSound != None && !bSuppressSounds)
        {
            PlaySound(ExplosionSound, true);
        }

        bSuppressExplosionFX = true; // so we don't get called again
    }
}

defaultproperties
{
    ProjFlightTemplate=ParticleSystem'KFTex6_effects.mesheffectstuff.MollyProjectile'
    ProjExplosionTemplate=ParticleSystem'KFTex6_effects.Particles.MollyHitExp'
    ExplosionLightClass=class'KFZ.MollyMuzzLight'
    MaxExplosionLightDistance=+4000.0
    speed=1000
    MaxSpeed=1200.0
    Damage=10.0
    DamageRadius=290
    MomentumTransfer=1
    MyDamageType=class'KFZ.DamageBurning'//DamageMolotov'
    LifeSpan=35.0 ///3.0

ExplosionSound=SoundCue'KFTex4.TheCues.MollyHit'//SoundCue'A_Weapon_RocketLauncher.Cue.A_Weapon_RL_Impact_Cue'
ExplosionDecal=MaterialInstanceTimeVarying'KFTex6_effects2.texs.MollyFuel_mic'//MaterialInstanceTimeVarying'WP_RocketLauncher.Decals.MITV_WP_RocketLauncher_Impact_Decal01'
ImpactSound=SoundCue'KFTex4.TheCues.BottleRoll'//SoundCue'KFTex4.TheCues.GlassSmash'
    DecalWidth=512.0
    DecalHeight=512.0
    DurationOfDecal=1.0f
//DecalDissolveParamName="DissolveAmount"

    bCollideWorld=true
    bBounce=true
    TossZ=+245.0
    Physics=PHYS_Falling
    CheckRadius=36.0

    bNetTemporary=False  //s/be true?
    bWaitForEffects=false
    CustomGravityScaling=1.2 // 0.500

/******* trying to suppress explosion sounds when player takesDamage
    Begin Object Class=AmbientSoundComponentKFZoff name=MollyExplodeSound
    SoundCue=SoundCue'KFTex4.Monsters.DroneAmb'
    End Object
    MollyExplode=MollyExplodeSound
    Components.Add(MollyExplodeSound)
*************/
}


Do your dead pawns have a physics asset? Have you tried playing with the mass scale?

Thanks Nathaniel3W. I have grenades and other projectiles but I don’t get the same result. I’m nervous about changing Mass Scale settings which I’ve always left at default. Er, the initial pic makes the situation look worse than it is. The flying tends to happen after a few minutes and when throwing a molotov into a group of bots.

The third pic there is one bot flying off.

I was thinking Momentum Transfer… ah, it’s something I’m going to keep fiddling with. If I can find this thread again, I’ll report back if I get a result. Thx again, Nathaniel3W.