Projectile Spread
by Derk Adams · 08/17/2006 (11:58 am) · 3 comments
Download Code File
Purpose:
I came to a point where I wanted to add variability to the weapon firing based on range. A simple server-side addition randomly selects the trajectory based on a cone from the player's eye.
Discussion:
This system projects a circle along the player's view to the maximum range of the weapon. It randomly selects an offset from center and a direction from center. This is then scaled to the eye vector and normalized for projectile use.
Comments:
There are many ways to determine the diameter of the circle, whether it be constant, as in my example, or based on the players speed or position.
I have shown it as an extension of the weapon object, but it can easily be made into a function that is called by all weapons.
Development Environment:
August 2006
Head 1.4
Win32
Single and Multi Player
Implementation:
ScriptFile: /server/scripts/crossbow.cs
Purpose:
I came to a point where I wanted to add variability to the weapon firing based on range. A simple server-side addition randomly selects the trajectory based on a cone from the player's eye.
Discussion:
This system projects a circle along the player's view to the maximum range of the weapon. It randomly selects an offset from center and a direction from center. This is then scaled to the eye vector and normalized for projectile use.
Comments:
There are many ways to determine the diameter of the circle, whether it be constant, as in my example, or based on the players speed or position.
I have shown it as an extension of the weapon object, but it can easily be made into a function that is called by all weapons.
Development Environment:
August 2006
Head 1.4
Win32
Single and Multi Player
Implementation:
ScriptFile: /server/scripts/crossbow.cs
function CrossbowImage::onFire(%this, %obj, %slot)
{
%projectile = %this.projectile;
// Decrement inventory ammo. The image's ammo state is update
// automatically by the ammo inventory hooks.
%obj.decInventory(%this.ammo,1);
// Determine initial projectile velocity based on the
// gun's muzzle point and the object's current velocity
%muzzleVector = %obj.getMuzzleVector(%slot);
//------- Projectile Spread -------
// These two variables can come from the datablock, a player function, or both, or static values.
%maxRange = 200; // game units
%spread = 4; // radius of circle at max range in game units (this decreases as the target is closer)
%randDist = getRandom(0,%spread*1000) / 1000; // random distance from center
%randDir = getRandom(0,62831) / 1000; // random direction on circle
%rvar = mSin(%randDir) * %randDist; // horizontal distance from center
%uvar = mCos(%randDir) * %randDist; // vertical distance from center
%muzzleTransform = %obj.getSlotTransform(%slot);
%aa = getWords(%muzzleTransform, 3, 6);
%tmat = VectorOrthoBasis(%aa);
%rv = getWords(%tmat, 0, 2); // Right Vector
%fv = getWords(%tmat, 3, 5); // Forward Vector
%uv = getWords(%tmat, 6, 8); // Up Vector
%roffset = VectorScale(%rv, %rvar); // scale horizontal vector by horizontal distance
%uoffset = VectorScale(%uv, %uvar); // scale vertical vector by vertical distance
// Combine for final vector
%muzzleVector = VectorScale(%muzzleVector, %maxRange);
%muzzleVector = VectorAdd(%muzzleVector, %roffset);
%muzzleVector = VectorAdd(%muzzleVector, %uoffset);
%muzzleVector = VectorNormalize(%muzzleVector);
//----- End Projectile Spread -----
%objectVelocity = %obj.getVelocity();
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, %projectile.muzzleVelocity),
VectorScale(%objectVelocity, %projectile.velInheritFactor));
// Create the projectile object
%p = new (%this.projectileType)() {
dataBlock = %projectile;
initialVelocity = %muzzleVelocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);
return %p;
}About the author
Recent Blogs
• Damage Texture with Transparency• Plan for Derk Adams
• Continuous Laser
• Plan for Derk Adams
• Plan for Derk Adams

Torque Owner Stephen
GearedMind Studio