Attaching Camera to Projectile

Hello guys.

Could anyone please tell me or give me an idea of how can I attach a camera to a projectile dynamically (custom weapon class) so we can have a kind of cool slow-mo sniper bullet camera effect on which the camera follows the projectile untill it hits the enemy similar to this (forget the x-ray, is too much complicated :D):

Here are my sniper riffle classes.

class UTWeap_GOWSniper extends UTWeapon;

defaultproperties
{

//visual properties///////////////////////////////
PlayerViewOffset=(X=-1.0,Y=0.0,Z=3.0)
//x -> distance from camera
//y -> horizontal position
//z -> vertical position

Begin Object class=AnimNodeSequence Name=MeshSequenceA
    bCauseActorAnimEnd=true
End Object

Begin Object Name=FirstPersonMesh
    SkeletalMesh=SkeletalMesh'WP_GOW.Mesh.WP_GOWSniper_P1'
    FOV=60
    Animations=MeshSequenceA
    AnimSets(0)=AnimSet'WP_SniperRifle.Anims.K_WP_SniperRifle_1P_Base'
    bForceUpdateAttachmentsInTick=True
    Scale=0.7000000
End Object

Begin Object Name=PickupMesh
    SkeletalMesh=SkeletalMesh'WP_GOW.Mesh.WP_GOWSniper_P3'
    Scale=0.9000000
End Object

ArmsAnimSet=AnimSet'WP_SniperRifle.Anims.K_WP_SniperRifle_1P_Arms'

PivotTranslation=(Y=0.0)

//this controls the projectile spawn position
FireOffset=(X=0,Y=10,Z=-10)
//x -> distance from camera
//y -> horizontal position (negative value moves to left)
//z -> vertical position    

//visual properties///////////////////////////////

//ammo properties
MaxAmmoCount=150
AmmoCount=50

//weapons in udk ultimate are ballistic, i.e, they trully shoot real bullets, projectiles which are controlled by physics properties
//here the properties of the bullet are controlled by the class UTProj_Enforcer
WeaponFireTypes(0)=EWFT_Projectile
WeaponProjectiles(0)=class'UTProj_GOWSniper'

//sounds
//WeaponEquipSnd=SoundCue'WP_SniperRifle.Sounds.A_Weapon_Sniper_Raise01_Cue'
WeaponPutDownSnd=SoundCue'WP_SniperRifle.Sounds.A_Weapon_Sniper_Lower01_Cue'
WeaponFireSnd(0)=SoundCue'WP_SniperRifle.Sounds.A_Weapon_Sniper_FireLayer01_Cue'
//PickupSound=SoundCue'WP_SniperRifle.Sounds.A_Weapon_Sniper_Raise01_Cue'

//muzzleflash
MuzzleFlashSocket=MuzzleFlashSocket
MuzzleFlashPSCTemplate=ParticleSystem'WP_Enforcers.Effects.P_WP_Enforcers_MuzzleFlash_fix'

//ammo fire speed functions///////////////////////////////
FireInterval(0)=1
FireInterval(1)=1
//ammo fire speed functions///////////////////////////////

//CrosshairImage=Copy texture from Content Browser
CrossHairCoordinates=(U=128,V=0,UL=64,VL=64)

//<DO NOT MODIFY>
Mesh=FirstPersonMesh
DroppedPickupMesh=PickupMesh
PickupFactoryMesh=PickupMesh
AttachmentClass=Class'UTAttachment_GOWSniper'

//custom zoom properties to simulate iron sights effect
DefaultProperties
{

bZoomedFireMode(0)=0
bZoomedFireMode(1)=1

ZoomedTargetFOV=15.0
ZoomedRate=9000
}
//custom zoom properties to simulate iron sights effect

}

And here is the projectile:

class UTProj_GOWSniper extends UTProjectile;

simulated function PostBeginPlay()
{
// force ambient sound if not vehicle game mode
bImportantAmbientSound = !WorldInfo.bDropDetail;
Super.PostBeginPlay();
}

defaultproperties
{
//this is the visual representation of the bullet, which is a particle system based on the rocket launcher
//I just changed the mesh by a bullet mesh (case) and the trail effect to simulate a bullet tracer
ProjFlightTemplate=ParticleSystem’WP_Enforcers.Effects.Bullet_fix’

ProjExplosionTemplate=ParticleSystem'WP_Enforcers.Effects.P_WP_Enforcer_Impact'
ExplosionDecal=MaterialInstanceConstant'WP_Enforcers.Decals.MI_WP_Enforcer_Impact_Decal01'
DecalWidth=12.0
DecalHeight=12.0
Speed=8500.0
MaxSpeed=0
Damage=300.0
MomentumTransfer=10000
MyDamageType=class'UTDmgType_GOWSniper'
LifeSpan=8.0
RotationRate=(Roll=50000)
bCollideWorld=true
CheckRadius=42.0
bCheckProjectileLight=true
bWaitForEffects=true
bAttachExplosionToVehicles=false

}

If your are using CalcCamera in your player class, you can override the values of out_camloc and out_camloc (and out_camfov) from the tick of your projectile class.

For example, in your player class:

var vector override_camloc;
var rotator override_camrot;

in the calccamera function:

if (override_camloc != vect(0,0,0)
{
out_camloc = override_camloc;
out_camrot = override_camrot;
return true;
}

and in the tick event of your projectile class, where P = yourplayerclass(getalocalplayercontroller().Pawn);

P.override_camloc = location;
P.override_camrot = rotation;

To return to the normal view, P.override_camloc = vect(0,0,0);

Thanks dude for the tips, trully thanks :D, however I am not using calccamera because whenever you use this function you can`t have camera animations, like stated on UDN:

“Implementing Pawn.CalcCamera() is useful for simple and straightforward camera modes. The tradeoff is that some functionality may not be fully functional via this method, including post process effects or camera animations.”

I am using a third person camera with execution animations and a custom camera animation (GOW Chainsaw): https://www.youtube.com/watch?v=V3BqY_-v1QE

So is possible to do this without using CalcCamera?

These are my main gametype classes. I based these classes on mouglis custom camera tutorial: http://www.moug-portfolio.info/udk-camera-basics/

class UDKUltimate extends UTTeamGame;

defaultproperties
{
bDelayedStart=false //We want to jump straight into the game

bScoreTeamKills=true
bMustJoinBeforeStart=false
bTeamGame=True
TeamAIType(0)=class’UTGame.UTTeamAI’
TeamAIType(1)=class’UTGame.UTTeamAI’
EndMessageWait=1
TeammateBoost=+0.3
FriendlyFireScale=+0.0
bMustHaveMultiplePlayers=true
FlagKillMessageName=TAUNT

DefaultPawnClass=class’UDKUltimate.UDKUltimatePawn’
PlayerControllerClass=class’UDKUltimate.UDKUltimatePlayerController’
Acronym=“AI”
MapPrefixes[0]=“AI”

OnlineGameSettingsClass=class’UTGame.UTGameSettingsDM’
MidgameScorePanelTag=TDMPanel
}

//////////////////////////////////////////////////////////////////////////////////////////////////

class UDKUltimatePawn extends UTPawn;

//this variable will store the animation node chainsaw attack
//this animation is setup on the Animtree
var AnimNodePlayCustomAnim ChainsawAnim;

//this function will find the animation node and store this to another variable
//this variable will be called by the weapon code
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
{
super.PostInitAnimTree(SkelComp);

if (SkelComp == Mesh)
{
ChainsawAnim = AnimNodePlayCustomAnim(SkelComp.FindAnimNode(‘ChainsawAnim’));
}
}

//override to make player mesh visible by default
simulated event BecomeViewTarget( PlayerController PC )
{
local UTPlayerController UTPC;

Super.BecomeViewTarget(PC);

if (LocalPlayer(PC.Player) != None)
{
UTPC = UTPlayerController(PC);
if (UTPC != None)
{
//set player controller to behind view and make mesh visible
//since we are not using the Pawn.CalcCamera() function so camera animations (chainsaw execution, i.e) will work normally
UTPC.SetBehindView(true);
SetMeshVisibility(UTPC.bBehindView);
}
}
}

defaultproperties
{
Health=300
HealthMax=300

bPhysRigidBodyOutOfWorldCheck=TRUE
bRunPhysicsWithNoController=true

LeftFootControlName=LeftFootControl
RightFootControlName=RightFootControl
bEnableFootPlacement=true
MaxFootPlacementDistSquared=56250000.0 // 7500 squared
}

//////////////////////////////////////////////////////////////////////////////////////////////////

class UDKUltimatePlayerController extends UTPlayerController;

defaultproperties
{

CameraClass=class’UDKUltimate.UDKUltimateCamera’

}

//////////////////////////////////////////////////////////////////////////////////////////////////

class UDKUltimateCamera extends GamePlayerCamera;

protected function GameCameraBase FindBestCameraType(Actor CameraTarget)
{
//Add here the code that will figure out which cam to use.
return ThirdPersonCam; // We only have this camera
}

DefaultProperties
{
ThirdPersonCameraClass=class’UDKUltimate.UDKUltimateThirdPersonCamera’
}

//////////////////////////////////////////////////////////////////////////////////////////////////

class UDKUltimateThirdPersonCamera extends GameCameraBase;

var float ThirdPersonCamOffsetX;
var float ThirdPersonCamOffsetY;
var float ThirdPersonCamOffsetZ;
var Rotator CurrentCamOrientation;
var Rotator DesiredCamOrientation;

function UpdateCamera(Pawn P, GamePlayerCamera CameraActor, float DeltaTime, out TViewTarget OutVT)
{
local float Radius, Height;
local vector X,Y,Z;

P.GetAxes(DesiredCamOrientation,X,Y,Z); // We will be working with coordinates in pawn space, but rotated according to the Desired Rotation.

P.GetBoundingCylinder(Radius, Height); //Get the pawn’s height as a base for the Z offset.

OutVT.POV.Location = P.Location + ThirdPersonCamOffsetX * X + ThirdPersonCamOffsetY * Y + (Height+ThirdPersonCamOffsetZ) * Z;

if (DesiredCamOrientation != CurrentCamOrientation)
{
CurrentCamOrientation = RInterpTo(CurrentCamOrientation,DesiredCamOrientation,DeltaTime,10);
}
OutVT.POV.Rotation = CurrentCamOrientation;
}

function ProcessViewRotation( float DeltaTime, Actor ViewTarget, out Rotator out_ViewRotation, out Rotator out_DeltaRot )
{
DesiredCamOrientation = out_ViewRotation + out_DeltaRot;
}

DefaultProperties
{
ThirdPersonCamOffsetX=-80.0
ThirdPersonCamOffsetY=8.0
ThirdPersonCamOffsetZ=-32.0
}

//////////////////////////////////////////////////////////////////////////////////////////////////

Seems very similar to calccamera, try to insert this at the start of the function updatecamera:

if (override_camloc != vect(0,0,0)
{
OutVT.POV.Location = override_camloc;
OutVT.POV.Rotation = override_camrot;
return;
}

In this case the two override variables needs to be declared in the camera class, and get a reference from the projectile class to be able to modify.

Or declare the variables in the player class and then in the updatecamera function read the variables from there, using “yourplayerclass(getalocalplayercontroller().pawn)” and storing in a variable, for example.

Thanks bro, I will try your tips :smiley: