Hi guys
Im using a sample script by Ryan Medeiros his site can be found
here
I modified it and it compiled fine. Now my question is how do i use this
script to influence objects?
My level has two cylinders and i need the to attract and repel based on the
script. However i do not know how to attach the script to the objects. Any
pointers would be great. Thanks
here is the source
/**
* MagneticComponent
*
* This component provides the mechanism to have magnetism physics
* within unreal. It can be attached to any actor and then configured
* to have the desired magnetic properties.
*
* Used currently with Pawns, KActors, InterpActors and Projectiles.
* Magnetic "Fields" (directional rather than radial effect) are
* handled seperately.
*
* The force uses a linear model (rather than a more "real" quadratic
* model), because we found linear to feel better than quadratic fall-
* off.
*
* Major properties are:
* magnetState - red, blue or neutral
* radius - max distance this magnet affects others
* power - how "strong" the magnet is
*/
class PFG_MagneticComponent extends ActorComponent
hidecategories(Object);
enum EMagnetType
{
MT_Player,
MT_Static, // InterpActors or placed magnets
MT_Movable, // Standard KActor Magnet
MT_Magba, // Enemy type
MT_Projectile
};
enum EMagnetState
{
MS_Neutral,
MS_Red,
MS_Blue
};
var(Magnet) EMagnetState magnetState;
var(Magnet) interp float radius;
var(Magnet) interp float power;
var(Magnet) interp float damping <UIMin=0.0 | UIMax=1.0>;
var(Affects) bool bMovables;
var(Affects) bool bMagbas;
var(Affects) bool bPlayer;
var(Affects) bool bProjectiles;
var(AffectedBy) bool bByPlayer;
var(AffectedBy) bool bByStatics;
var(AffectedBy) bool bByFields;
var(AffectedBy) bool bByMovables;
var(AffectedBy) bool bByMagbas;
var(AffectedBy) bool bByProjectiles;
var float deltaSpeed;
var const float maxViscousDamping;
var bool hasViscDampingApplied;
var bool bAffectsOthersOnly;
var bool bEnabled;
var bool bAffectPlayer;
var EMagnetType mType;
/**
* This function should be called within Tick of
* every magnet which affects the physics of others
* @param dt DeltaTime from calling function
*/
simulated function AffectOthers(float dt)
{
local Actor other;
local GamePawn otherPawn;
local KActor otherMagnet;
local UDKProjectile otherProjectile;
local Vector direction, velProj;
local float magnitude, dist, viscDamp, normDist;
local PFG_MagneticComponent otherComponent, tmp;
if(!bEnabled || MagnetState==MS_Neutral || Owner == none || (Pawn(Owner) != none && Pawn(Owner).Health <= 0) )
return;
foreach Owner.CollidingActors( class'Actor', other, Radius)
{
// Three classes of objects can be magnets. And for some reason Unreal gives the Owner back as well.
if( Owner != other && (GamePawn(other) != none || KActor(other) != none || UDKProjectile(other) != none) )
{
otherComponent = none;
foreach other.ComponentList( class'PFG_MagneticComponent', tmp )
otherComponent = tmp;
otherPawn = GamePawn(other);
otherMagnet = KActor(other);
otherProjectile = UDKProjectile(other);
/**
* This is basically a big matrix that allows Level Designers to choose
* what each magnet affects and disable other magnets affecting it. I'm
* a little disappointed by how ugly/large of an if block it is, but
* offers our designers explicit control.
*/
if( ( otherComponent == none || otherComponent.MagnetState == MS_Neutral ) ||
( otherComponent.bAffectsOthersOnly ) ||
( !otherComponent.bEnabled ) ||
( otherComponent.mType == MT_Player && !bPlayer ) ||
( otherComponent.mType == MT_Magba && !bMagbas ) ||
( otherComponent.mType == MT_Movable && !bMovables) ||
( otherComponent.mType == MT_Projectile && !bProjectiles ) ||
( mType == MT_Player && !otherComponent.bByPlayer ) ||
( mType == MT_Static && !otherComponent.bByStatics ) ||
( mType == MT_Movable && !otherComponent.bByMovables ) ||
( mType == MT_Magba && !otherComponent.bByMagbas ) ||
( mType == MT_Projectile && !otherComponent.bByProjectiles ) )
continue;
dist = VSize(other.Location - Owner.Location);
if(dist < 1.6f)
{
// Too close together, simply attach. For U shaped magnets.
// Co-op direction and velProj to prevent extra variables.
direction = (Owner.Location - other.Location)*0.5f + other.Location;
velProj = (other.Velocity + Owner.Velocity)*0.5f;
otherComponent.hasViscDampingApplied = true;
other.SetLocation( direction );
Owner.SetLocation( direction );
other.Velocity = velProj;
Owner.Velocity = velProj;
continue;
}
magnitude = (power * otherComponent.power) / dist;
/**
* Viscous damping
* Use viscous damping in order to prevent physics craziness when
* two magnets are consistently colliding between frames. Without
* this system, magnets tend to become unstable when attracted and
* next to each other.
*/
if( otherProjectile == none && (dist < 80 || otherComponent.hasViscDampingApplied) )
{
// Quadratic falloff
viscDamp = maxViscousDamping * ( 1 - (dist*dist/6400) );
// Pawns and KActors must be handled seperately, as below.
if( otherPawn != none && !otherComponent.hasViscDampingApplied)
otherPawn.AddVelocity( -viscDamp*otherPawn.Velocity, otherPawn.Location, None );
else if( otherMagnet != none && !otherComponent.hasViscDampingApplied)
otherMagnet.ApplyImpulse(otherMagnet.Velocity,
-viscDamp * VSize(otherMagnet.Velocity), otherMagnet.Location );
// Scale magnitude by the amount of viscous damping applied
magnitude *= 1-viscDamp-(0.1);
otherComponent.hasViscDampingApplied = true;
}
if(otherComponent.MagnetState != MagnetState)
direction = (Owner.Location - other.Location); // Pull
else
direction = (other.Location - Owner.Location); // Push
if( dist < 100 )
{
// A quick-fix to prevent flying characters.
direction.Z = 0;
normDist = VSize(direction);
magnitude *= normDist/dist;
if(normDist != 0)
direction /= normDist;
}
else
direction = Normal(direction);
/**
* Note:
* The 30 and 50 are used as scaling factors below. Pawns react
* differently through AddVelocity() than KActors do through
* ApplyImpluse(). These are left high (ie not 3 & 5) so that
* level designers can work with smaller numbers and to balance
* with projectiles.
*/
if( otherPawn != none )
{
otherPawn.SetPhysics(PHYS_Falling); // Allows upward physics
otherPawn.AddVelocity( direction*(magnitude*dt*30), otherPawn.Location, None );
}
else if( otherMagnet != none )
{
otherMagnet.ApplyImpulse( direction, magnitude*dt*50, otherMagnet.Location );
}
/*else if ( otherProjectile != none )
//{
// if (otherProjectile.Owner != none && !ML_ENMY_MagRay(otherProjectile.Owner).bAimsInZ) direction.Z = 0;
// otherProjectile.Velocity += direction * magnitude * dt * otherProjectile.Speed * deltaSpeed;
}
*/
/**
* Regular damping
* Applied along the line of effect between
* two magnets.
*/
if( dist >= 60 )
{
velProj = ProjectOnTo( other.Velocity , direction);
velProj *= -damping;
magnitude = VSize(velProj);
if( magnitude != 0 )
{
if( otherPawn != none )
otherPawn.AddVelocity( -direction*magnitude*dt, otherPawn.Location, None );
else if( otherMagnet != none)
otherMagnet.ApplyImpulse( velProj, magnitude*dt, otherMagnet.Location);
}
}
}
}
}
function bool IsOpposite(EMagnetState Other)
{
return (Other == MS_Blue && MagnetState == MS_Red) || (Other == MS_Red && MagnetState == MS_Blue);
}
DefaultProperties
{
TickGroup=TG_PreAsyncWork
damping = 0.04
magnetState=MS_Neutral
bAffectsOthersOnly=false
bEnabled=true
Radius=512.0
power=50.0
deltaSpeed=0.15f
maxViscousDamping = 0.8
hasViscDampingApplied = false
bMovables = true
bMagbas = true
bPlayer = true
bProjectiles = true
bByPlayer = true
bByStatics = true
bByFields = true
bByMovables = true
bByMagbas = true
bByProjectiles = true
}