用UMG蓝图方式实现3D血条
http://aigo.iteye.com/blog/2270026
参考自Epic官方项目StrategyGame
血条效果:
StrategyHUD.h
/**
* Draws health bar for specific actor.
*
* @param ForActor Actor for which the health bar is for.
* @param HealthPct Current Health percentage.
* @param BarHeight Height of the health bar
* @param OffsetY Y Offset of the health bar.
*/
void DrawHealthBar(AActor* ForActor, float HealthPct, int32 BarHeight, int OffsetY = 0) const;
StrategyHUD.cpp
void AStrategyHUD::DrawHealthBar(AActor* ForActor, float HealthPercentage, int32 BarHeight, int32 OffsetY) const
{
FBox BB = ForActor->GetComponentsBoundingBox();
FVector Center = BB.GetCenter();
FVector Extent = BB.GetExtent();
FVector2D Center2D = FVector2D(Canvas->Project(FVector(Center.X,Center.Y,Center.Z + Extent.Z)));
float ActorExtent = 40;
if (Cast<APawn>(ForActor) != NULL)
{
AStrategyChar* StrategyChar = Cast<AStrategyChar>(ForActor);
if( ( StrategyChar != NULL ) && ( StrategyChar->GetCapsuleComponent() != NULL ) )
{
ActorExtent = StrategyChar->GetCapsuleComponent()->GetScaledCapsuleRadius();
}
}
else if (Cast<AStrategyBuilding>(ForActor) != NULL)
{
Center2D = FVector2D(Canvas->Project(ForActor->GetActorLocation()));
ActorExtent = 60;
}
FVector Pos1 = Canvas->Project(FVector(Center.X,Center.Y - ActorExtent*2, Center.Z + Extent.Z));
FVector Pos2 = Canvas->Project(FVector(Center.X,Center.Y + ActorExtent*2, Center.Z + Extent.Z));
float HealthBarLength = (Pos2-Pos1).Size2D();
AStrategyPlayerController* MyPC = GetPlayerController();
IStrategyTeamInterface* ActorTeam = Cast<IStrategyTeamInterface>(ForActor);
UTexture2D* HealthBarTexture = EnemyTeamHPTexture;
if (ActorTeam != NULL && MyPC != NULL && ActorTeam->GetTeamNum() == MyPC->GetTeamNum())
{
HealthBarTexture = PlayerTeamHPTexture;
}
float X = Center2D.X - HealthBarLength/2;
float Y = Center2D.Y + OffsetY;
FCanvasTileItem TileItem( FVector2D( X, Y ), HealthBarTexture->Resource, FVector2D( HealthBarLength * HealthPercentage, BarHeight ), FLinearColor::White );
TileItem.BlendMode = SE_BLEND_Translucent;
TileItem.UV1 = FVector2D(HealthPercentage, 1.0f);
Canvas->DrawItem( TileItem );
//Fill the rest of health with gray gradient texture
X = Center2D.X-HealthBarLength/2 + HealthBarLength * HealthPercentage;
Y = Center2D.Y + OffsetY;
TileItem.Position = FVector2D( X, Y );
TileItem.Texture = BarFillTexture->Resource;
TileItem.UV1 = FVector2D(1.0f, 1.0f);
TileItem.Size = FVector2D( HealthBarLength * (1.0f - HealthPercentage), BarHeight );
TileItem.SetColor(FLinearColor(0.5f, 0.5f, 0.5f, 0.5f));
Canvas->DrawItem( TileItem );
}