u4初步使用整理(二)

一个例子
角色利用碰撞捡取物品,直接画在hud上做的背包ui,可拖拽.
有点需要注意,获取的鼠标位置是以viewport大小为基准,游戏中的hud坐标系(0,0)是以非黑边处第一个像素点,如果满viewport显示,则与鼠标坐标系一致。
u4初步使用整理(二)_第1张图片

    #pragma once

    #include "GameFramework/HUD.h"
    #include "MyHUD.generated.h"

    /**
     * 
     */

    struct Message
    {
        FString message;
        float time;
        UTexture2D *pTex;
        FColor color;
        Message()
        {
            time = 5.f;
            color = FColor::White;
        }
        Message(FString iMessage, float iTime, FColor iColor, UTexture2D *tTex)
        {
            message = iMessage;
            time = iTime;
            color = iColor;
            pTex = tTex;
        }
    };

    struct Icon
    {
        FString name;
        UTexture2D *tex;
        Icon()
        {
            name = TEXT("unknown");
            tex = 0;
        }
        Icon(FString &iName, UTexture2D *iTex)
        {
            name = iName;
            tex = iTex;
        }
    };

    struct Widget
    {
        Icon icon;
        FVector2D pos, size;
        Widget(Icon iIcon)
        {
            icon = iIcon;
        }
        bool hit(FVector2D p);

        float left() { return pos.X; }
        float right() { return pos.X + size.X; }
        float top() { return pos.Y; }
        float bottom() { return pos.Y + size.Y; }
    };


    UCLASS()
    class BASICPROJ_API AMyHUD : public AHUD
    {
        GENERATED_BODY()

    public:
        UPROPERTY(EditAnywhere, Category = HUDFont)
        UFont *hudFont;
        TArray<Message> messages;
        TArray<Widget> widgets;

    public:
        void addMessage(Message msg);
        void DrawHealthBar();
        void DrawWidgets();
        void ClearWidgets();
        void AddWidget(Widget widget);
        void MouseClicked();
        void MouseMoved();

    private:
        virtual  void DrawHUD() override;

    private:
        Widget *holdWidget;

    };

    void  AMyHUD::DrawHUD()
    {
        Super::DrawHUD();
        DrawHealthBar();
        for (int i = messages.Num() - 1; i >= 0; --i)
        {
            float outputWidth, ouputHeight, pad = 10.f;
            GetTextSize(messages[i].message, outputWidth, ouputHeight, hudFont, 1.f);
            float messageH = ouputHeight + 2.f * pad;
            float x = 0.f, y = i * messageH;
            DrawTexture(messages[i].pTex, x, y, messageH, messageH, 0, 0, 1, 1);
            DrawRect(FLinearColor::Blue, x, y, outputWidth, messageH);
            DrawText(messages[i].message, messages[i].color, x + pad, y + pad, hudFont);
            messages[i].time -= GetWorld()->GetDeltaSeconds();
            if (messages[i].time < 0)
            {
                messages.RemoveAt(i);
            }
        }
        DrawWidgets();
    }

    void AMyHUD::addMessage(Message msg)
    {
        messages.Add(msg);
    }

    void AMyHUD::DrawHealthBar()
    {
        AAvatar *avatar = Cast<AAvatar>(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
        float barWidth = 200, barHeight = 50, barPad = 12, barMargin = 50;
        float percHp = avatar->Hp / avatar->MaxHp;
        DrawRect(FLinearColor(0, 0, 0, 1), Canvas->SizeX - barWidth -
            barPad - barMargin, Canvas->SizeY - barHeight - barPad -
            barMargin, barWidth + 2 * barPad, barHeight + 2 * barPad);
        DrawRect(FLinearColor(1 - percHp, percHp, 0, 1), Canvas->SizeX
            - barWidth - barMargin, Canvas->SizeY - barHeight - barMargin,
            barWidth*percHp, barHeight);
    }

    void AMyHUD::DrawWidgets()
    {
        for (int i = 0; i < widgets.Num(); ++i)
        {
            DrawTexture(widgets[i].icon.tex, widgets[i].pos.X, widgets[i].pos.Y, widgets[i].size.X,
                widgets[i].size.Y, 0, 0, 1, 1);
            DrawText(widgets[i].icon.name, FLinearColor::Yellow, widgets[i].pos.X, widgets[i].pos.Y, hudFont, .6f, false);
        }
    }

    void AMyHUD::AddWidget(Widget widget)
    {
        FVector2D start(0, 0), pad(12, 12);
        widget.size = FVector2D(100, 100);
        widget.pos = start;
        for (int i = 0; i < widgets.Num(); ++i)
        {
            widget.pos.X += widget.size.X + pad.X;
            if (widget.pos.X + widget.size.X > 800)
            {
                widget.pos.X = start.X;
                widget.pos.Y += widget.size.Y + pad.Y;
            }
        }

        widgets.Add(widget);
    }

    void AMyHUD::ClearWidgets()
    {
        for (int i = widgets.Num() - 1; i >= 0; --i)
        {
            widgets.RemoveAt(i);
        }
    }

    void AMyHUD::MouseClicked()
    {
        static FVector2D mouse;

        APlayerController *pController = GetWorld()->GetFirstPlayerController();
        pController->GetMousePosition(mouse.X, mouse.Y);
        for (int i = 0; i < widgets.Num(); ++i)
        {
            if (widgets[i].hit(mouse))
            {
                holdWidget = &widgets[i];
                return ;
            }
        }
    }

    void AMyHUD::MouseMoved()
    {
        static FVector2D lastMouse;
        FVector2D thisMouse, dMouse;
        APlayerController *pController = GetWorld()->GetFirstPlayerController();
        pController->GetMousePosition(thisMouse.X, thisMouse.Y);
        dMouse = thisMouse - lastMouse;

        float time = pController->GetInputKeyTimeDown(EKeys::LeftMouseButton);
        if (time > 0.f && holdWidget)
        {
            holdWidget->pos.X += dMouse.X;
            holdWidget->pos.Y += dMouse.Y;
        }
        lastMouse = thisMouse;
    }

    bool Widget::hit(FVector2D p)
    {
        int a = left();
        int b = right();
        int c = top();
        int d = bottom();
        GEngine->ClearOnScreenDebugMessages();
        FString textt = FString::Printf(TEXT("mousex=%f, mousey=%f \nLEFT=%f right = %f top = %f bo= %f"), p.X, p.Y, left(), right(), top(), bottom());
        GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Yellow, textt);
        return p.X > a && p.X <b && p.Y > c && p.Y < d;
    }

    // Called to bind functionality to input
    void AAvatar::SetupPlayerInputComponent(class UInputComponent* InputComponent)
    {
        check(InputComponent);
        Super::SetupPlayerInputComponent(InputComponent);
        InputComponent->BindAxis("Forward", this, &AAvatar::MoveForward);
        InputComponent->BindAxis("Strafe", this, &AAvatar::MoveRight);
        InputComponent->BindAxis("left", this, &AAvatar::MoveRight);
        InputComponent->BindAxis("back", this, &AAvatar::MoveForward);
        InputComponent->BindAxis("Yaw", this, &AAvatar::Yaw);
        InputComponent->BindAxis("Pitch", this, &AAvatar::Pitch);
        InputComponent->BindAction("Bag",IE_Pressed, this, &AAvatar::OpenBag);
        InputComponent->BindAction("MouseClickedLMB", IE_Pressed, this,  &AAvatar::MouseClicked);
    }

    void AAvatar::MoveForward( float fAmount )
    {
        if (Controller && fAmount)
        {
            FVector fVec = GetActorForwardVector();
            AddMovementInput(fVec, fAmount);
        }
    }

    void AAvatar::MoveRight( float fAmount )
    {
        if (Controller && fAmount)
        {
            FVector right = GetActorRightVector();
            AddMovementInput(right, fAmount);
        }
    }

    void AAvatar::Yaw(float f)
    {
        if (InventoryShowing)
        {
            APlayerController *pController = GetWorld()->GetFirstPlayerController();
            AMyHUD *hud = Cast<AMyHUD>(pController->GetHUD());
            hud->MouseMoved();
            return;
        }
        AddControllerYawInput(200.f * f * GetWorld()->GetDeltaSeconds());
    }

    void AAvatar::Pitch(float f)
    {
        if (InventoryShowing)
        {
            APlayerController *pController = GetWorld()->GetFirstPlayerController();
            AMyHUD *hud = Cast<AMyHUD>(pController->GetHUD());
            hud->MouseMoved();
            return;
        }
        AddControllerPitchInput(200.f * -f * GetWorld()->GetDeltaSeconds());

    }

    void AAvatar::OpenBag()
    {
        APlayerController *pController = GetWorld()->GetFirstPlayerController();
        AMyHUD *hud = Cast<AMyHUD>(pController->GetHUD());
        if (InventoryShowing)
        {
            hud->ClearWidgets();
            InventoryShowing = false;
            pController->bShowMouseCursor = false;
            return;
        }
        InventoryShowing = true;
        pController->bShowMouseCursor = true;
        for (TMap<FString, BagItem>::TIterator it = BackPack.CreateIterator(); it; ++it)
        {
            FString fs = it->Key + FString::Printf(TEXT("X %d"), it->Value.iNum);
            UTexture2D *tex;
            tex = it->Value.pICon;
            hud->AddWidget(Widget(Icon(fs, tex)));
        }
    }

    void AAvatar::PickUp(APickItem *item)
    {
        if (BackPack.Find(item->Name))
        {
            BackPack[item->Name].iNum += item->Quantity;
        }
        else
        {
            BagItem bitem;
            bitem.iNum = item->Quantity;
            bitem.pICon = item->Icon;
            BackPack.Add(item->Name, bitem);
        }
    }

    void AAvatar ::MouseClicked()
    {
        APlayerController *pController = GetWorld()->GetFirstPlayerController();
        AMyHUD *hud = Cast<AMyHUD>(pController->GetHUD());
        hud->MouseClicked();
    }

你可能感兴趣的:(u4初步使用整理(二))