Download

Homing projectile in c++, what am i missing here?

So i need my projectile to home on to a moving character. shouldn’t be too hard, right?

Well i must be missing something incredibly basic then.



ADirectProjectile::ADirectProjectile()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	CollisionComp = CreateDefaultSubobject<USphereComponent>( TEXT( "SphereComp" ) );
	CollisionComp->InitSphereRadius( 5.0f );
	CollisionComp->BodyInstance.SetCollisionProfileName( "Projectile" );
	CollisionComp->OnComponentHit.AddDynamic( this, &ADirectProjectile::OnHit );

	CollisionComp->SetWalkableSlopeOverride( FWalkableSlopeOverride( WalkableSlope_Unwalkable, 0.f ) );
	CollisionComp->CanCharacterStepUpOn = ECB_No;

	RootComponent = CollisionComp;

	ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>( TEXT( "ProjectileComp" ) );
	ProjectileMovement->UpdatedComponent = CollisionComp;
	ProjectileMovement->InitialSpeed = 1500.f;
	ProjectileMovement->MaxSpeed = 1500.f;
	ProjectileMovement->bRotationFollowsVelocity = true;
	ProjectileMovement->bShouldBounce = false;
	ProjectileMovement->bInitialVelocityInLocalSpace = true;
	ProjectileMovement->bIsHomingProjectile = true;
	ProjectileMovement->HomingAccelerationMagnitude = 200.f;

	InitialLifeSpan = 0.f;
}

// Called when the projectile is spawned.
void ADirectProjectile::BeginPlay()
{
	Super::BeginPlay();

	APVPCharacter* Caster = Cast<APVPCharacter>( this->GetOwner() );
	if( Caster != NULL )
	{
		mTargetCharacter = Caster->GetSelectedEnemyChar();
		if( mTargetCharacter != NULL )
		{
			ProjectileMovement->HomingTargetComponent = mTargetCharacter->GetCollisionCapsule();
		}
	}
}


So basically when the actor is spawned, it gets the target character, and then sets the homing target to their collision capsule. this is working.

The behavior of the projectile is incorrect though, it travels in a straight line, while the root component rotates so that it’s always facing the target, it never actually adjusts its directional movement to match its new rotation, it seems.

Any ideas?

So a couple of things I’ve found with homing projectiles.

The homing acceleration magnitude has to be more than or equal too the speed of the projectile, otherwise it literally doesn’t work. I wrote my missiles like this (avoided the native code altogether, since I’m not convinced by it). I still have to make Omega a pretty large value so I’d like to rework this again to be honest and make it more predictable and make a bit more sense when tuning it…



void ABZGame_Missile::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	if (Role == ROLE_Authority)
	{
		if (TargetActor.IsValid())
		{
			FVector WantedDir = (TargetActor->GetActorLocation() - GetActorLocation()).GetSafeNormal();
			if (bLeadTarget)
			{
				WantedDir += TargetActor->GetVelocity() * WantedDir.Size() / MovementComp->MaxSpeed;
			}

			MovementComp->Velocity += WantedDir * OmegaTurn * DeltaSeconds;
			MovementComp->Velocity = MovementComp->Velocity.GetSafeNormal() * MovementComp->MaxSpeed;
		}
	}
}


Hmmm

Even that doesn’t work. This is leading me to believe i may be missing a bool somewhere.

My solution for this:

never ever use a movement component, and calculate everything myself. it meant i had to work out replication slightly differently, but at least it works now!

Well the advantage of the Component is that you can share it across lots of different objects, but yeah mine is actually done in the main class itself as well. I aim to change that though…

Are you sure the target is set correctly? i ask this because you’re doing a this->GetOwner() on the projectile, which I would assume isn’t an actual character. Also make sure that the position of the target is actually changing. So my suggestion is to step over the code for begin play, then print out the values of your mTargetCharacter to see if its valid, has a valid position etc. Then at least you know that the target isn’t the cause.

I’m trying to this too but i don’t know how begin with this, can you help me with questions or code please?

I’ve just noticed why, basically the Homing Magnitude needs to be equal too or greater than the Initial Velocity for it to have any real affect, I struggled with this for ages too. I’m not a fan of the calculation to be honest, I’d like to do a better one where the magnitude is a ‘turn’ value instead of an acceleration.