Add cinematic startup credits

This commit is contained in:
2026-05-17 20:02:22 -07:00
parent 879a4805c5
commit 075689dce4
7 changed files with 337 additions and 6 deletions
+1
View File
@@ -710,6 +710,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
- [ ] Add footstep placeholders. - [ ] Add footstep placeholders.
- [ ] Add gathering sounds. - [ ] Add gathering sounds.
- [ ] Add fire sounds. - [ ] Add fire sounds.
- [ ] Add forest-fire risk and spread from irresponsible campfire and open-flame placement, including server-authoritative ignition checks, vegetation fuel rules, suppression hooks, and save/load support.
- [ ] Add weather sounds. - [ ] Add weather sounds.
- [ ] Add wildlife sounds. - [ ] Add wildlife sounds.
- [ ] Add UI sounds. - [ ] Add UI sounds.
+1 -1
View File
@@ -3,7 +3,7 @@ ProjectID=1C37CF214211E5FA6177D497FE103AC4
ProjectName=Agrarian ProjectName=Agrarian
ProjectDisplayedTitle=NSLOCTEXT("[/Script/EngineSettings]", "AgrarianProjectDisplayedTitle", "Agrarian") ProjectDisplayedTitle=NSLOCTEXT("[/Script/EngineSettings]", "AgrarianProjectDisplayedTitle", "Agrarian")
ProjectDebugTitleInfo=NSLOCTEXT("[/Script/EngineSettings]", "AgrarianProjectDebugTitle", "Agrarian - Development Build") ProjectDebugTitleInfo=NSLOCTEXT("[/Script/EngineSettings]", "AgrarianProjectDebugTitle", "Agrarian - Development Build")
ProjectVersion=0.1.E-investor.20260517 ProjectVersion=0.1.H-investor.20260517
Description=Persistent generational civilization survival prototype. Description=Persistent generational civilization survival prototype.
CompanyName=Agrarian Studio CompanyName=Agrarian Studio
CompanyDistinguishedName=Agrarian Studio CompanyDistinguishedName=Agrarian Studio
+1 -1
View File
@@ -19,7 +19,7 @@ set "DX12_LAUNCHER=%PACKAGE_DIR%\Start Agrarian Demo - DX12.cmd"
set "DX11_LAUNCHER=%PACKAGE_DIR%\Start Agrarian Demo - Compatibility DX11.cmd" set "DX11_LAUNCHER=%PACKAGE_DIR%\Start Agrarian Demo - Compatibility DX11.cmd"
set "PREREQ_LAUNCHER=%PACKAGE_DIR%\Install Prerequisites.cmd" set "PREREQ_LAUNCHER=%PACKAGE_DIR%\Install Prerequisites.cmd"
set "README_FILE=%PACKAGE_DIR%\README-Investor-Demo.txt" set "README_FILE=%PACKAGE_DIR%\README-Investor-Demo.txt"
set "DEMO_VERSION=Investor Demo v0.1.E - Build 2026.05.17" set "DEMO_VERSION=Investor Demo v0.1.H - Build 2026.05.17"
> "%DEFAULT_LAUNCHER%" echo @echo off > "%DEFAULT_LAUNCHER%" echo @echo off
>> "%DEFAULT_LAUNCHER%" echo cd /d "%%~dp0" >> "%DEFAULT_LAUNCHER%" echo cd /d "%%~dp0"
@@ -0,0 +1,60 @@
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
REQUIRED = {
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeActor.h": [
"float NoticeDurationSeconds = 24.0f;",
"Investor Demo v0.1.H - Build 2026.05.17",
],
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.h": [
"virtual void NativeConstruct() override;",
"DrawCinematicCredits",
"DrawCreditIllustration",
"CreditsStartTimeSeconds",
"Investor Demo v0.1.H - Build 2026.05.17",
],
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.cpp": [
"Nathan Slaven",
"Lead Developer",
"Hunter Slaven",
"Junior Developer",
"Lisa Reiley",
"Quality Control",
"River Slaven",
"Alpha Game Tester",
"Fisher Slaven",
"Beta Game Tester",
"Cherished individuals, Pacificao seed funding, and Lina Family Investment Funds",
"SlamSeconds",
"DrawCreditIllustration",
],
ROOT / "Config" / "DefaultGame.ini": [
"ProjectVersion=0.1.H-investor.20260517",
],
ROOT / "Scripts" / "InstallWindowsDemoLaunchers.bat": [
"DEMO_VERSION=Investor Demo v0.1.H - Build 2026.05.17",
],
ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md": [
"Add forest-fire risk and spread from irresponsible campfire and open-flame placement",
],
}
def main():
missing = []
for path, snippets in REQUIRED.items():
text = path.read_text(encoding="utf-8")
for snippet in snippets:
if snippet not in text:
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
if missing:
raise SystemExit("Startup credits verification failed:\n" + "\n".join(missing))
print("PASS: startup credits sequence and forest-fire roadmap follow-up are present.")
if __name__ == "__main__":
main()
@@ -20,10 +20,10 @@ public:
TSubclassOf<UAgrarianDemoNoticeWidget> NoticeWidgetClass; TSubclassOf<UAgrarianDemoNoticeWidget> NoticeWidgetClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo", meta = (ClampMin = "1.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo", meta = (ClampMin = "1.0"))
float NoticeDurationSeconds = 9.0f; float NoticeDurationSeconds = 24.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.E - Build 2026.05.17")); FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.H - Build 2026.05.17"));
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution")); FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution"));
@@ -2,9 +2,43 @@
#include "AgrarianDemoNoticeWidget.h" #include "AgrarianDemoNoticeWidget.h"
#include "Engine/World.h"
#include "Rendering/DrawElements.h" #include "Rendering/DrawElements.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
namespace
{
struct FAgrarianCreditCard
{
const TCHAR* Name;
const TCHAR* Role;
FLinearColor AccentColor;
int32 IllustrationIndex;
float HoldSeconds;
};
const FAgrarianCreditCard CreditCards[] = {
{ TEXT("Nathan Slaven"), TEXT("Lead Developer"), FLinearColor(0.70f, 0.90f, 0.46f, 1.0f), 0, 2.05f },
{ TEXT("Hunter Slaven"), TEXT("Junior Developer"), FLinearColor(0.36f, 0.72f, 0.96f, 1.0f), 1, 2.05f },
{ TEXT("Lisa Reiley"), TEXT("Quality Control"), FLinearColor(0.95f, 0.72f, 0.42f, 1.0f), 2, 2.05f },
{ TEXT("River Slaven"), TEXT("Alpha Game Tester"), FLinearColor(0.56f, 0.82f, 0.66f, 1.0f), 3, 2.05f },
{ TEXT("Fisher Slaven"), TEXT("Beta Game Tester"), FLinearColor(0.56f, 0.62f, 0.98f, 1.0f), 4, 2.05f },
{ TEXT("Funding"), TEXT("Cherished individuals, Pacificao seed funding, and Lina Family Investment Funds"), FLinearColor(0.92f, 0.84f, 0.54f, 1.0f), 5, 3.0f },
};
float SmoothStep(float Value)
{
const float ClampedValue = FMath::Clamp(Value, 0.0f, 1.0f);
return ClampedValue * ClampedValue * (3.0f - (2.0f * ClampedValue));
}
}
void UAgrarianDemoNoticeWidget::NativeConstruct()
{
Super::NativeConstruct();
CreditsStartTimeSeconds = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f;
}
int32 UAgrarianDemoNoticeWidget::NativePaint( int32 UAgrarianDemoNoticeWidget::NativePaint(
const FPaintArgs& Args, const FPaintArgs& Args,
const FGeometry& AllottedGeometry, const FGeometry& AllottedGeometry,
@@ -17,7 +51,7 @@ int32 UAgrarianDemoNoticeWidget::NativePaint(
LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
const FVector2D Size = AllottedGeometry.GetLocalSize(); const FVector2D Size = AllottedGeometry.GetLocalSize();
const float PanelWidth = FMath::Min(860.0f, Size.X - 96.0f); const float PanelWidth = FMath::Min(860.0f, FMath::Max(320.0f, Size.X - 96.0f));
const float PanelHeight = 210.0f; const float PanelHeight = 210.0f;
const FVector2D PanelPosition((Size.X - PanelWidth) * 0.5f, 42.0f); const FVector2D PanelPosition((Size.X - PanelWidth) * 0.5f, 42.0f);
@@ -46,6 +80,8 @@ int32 UAgrarianDemoNoticeWidget::NativePaint(
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, DemoNotice, PanelPosition.Y + 126.0f, NoticeFont, FLinearColor(0.78f, 0.82f, 0.75f, 1.0f)); DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, DemoNotice, PanelPosition.Y + 126.0f, NoticeFont, FLinearColor(0.78f, 0.82f, 0.75f, 1.0f));
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, CopyrightNotice, PanelPosition.Y + 158.0f, NoticeFont, FLinearColor(0.66f, 0.70f, 0.64f, 1.0f)); DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, CopyrightNotice, PanelPosition.Y + 158.0f, NoticeFont, FLinearColor(0.66f, 0.70f, 0.64f, 1.0f));
DrawCinematicCredits(OutDrawElements, LayerId, AllottedGeometry);
return LayerId; return LayerId;
} }
@@ -72,3 +108,208 @@ void UAgrarianDemoNoticeWidget::DrawCenteredText(
ESlateDrawEffect::None, ESlateDrawEffect::None,
Color); Color);
} }
void UAgrarianDemoNoticeWidget::DrawTextAt(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry,
const FText& Text,
const FVector2D& Position,
float Width,
const FSlateFontInfo& Font,
const FLinearColor& Color) const
{
FSlateDrawElement::MakeText(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(FMath::Max(96.0f, Width), Font.Size + 18.0f), FSlateLayoutTransform(FVector2f(Position))),
Text,
Font,
ESlateDrawEffect::None,
Color);
}
void UAgrarianDemoNoticeWidget::DrawCinematicCredits(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const
{
const UWorld* World = GetWorld();
if (!World)
{
return;
}
const FVector2D Size = AllottedGeometry.GetLocalSize();
const float Elapsed = World->GetTimeSeconds() - CreditsStartTimeSeconds;
const float IntroDelay = 0.55f;
const float SlamSeconds = 0.28f;
const float ExitSeconds = 0.48f;
const float GapSeconds = 0.16f;
float Cursor = IntroDelay;
int32 ActiveIndex = INDEX_NONE;
float LocalTime = 0.0f;
for (int32 Index = 0; Index < UE_ARRAY_COUNT(CreditCards); ++Index)
{
const float CardDuration = SlamSeconds + CreditCards[Index].HoldSeconds + ExitSeconds + GapSeconds;
if (Elapsed >= Cursor && Elapsed < Cursor + CardDuration)
{
ActiveIndex = Index;
LocalTime = Elapsed - Cursor;
break;
}
Cursor += CardDuration;
}
if (ActiveIndex == INDEX_NONE)
{
return;
}
const FAgrarianCreditCard& Card = CreditCards[ActiveIndex];
const bool bEntering = LocalTime < SlamSeconds;
const bool bExiting = LocalTime > SlamSeconds + Card.HoldSeconds;
const float EnterAlpha = bEntering ? SmoothStep(LocalTime / SlamSeconds) : 1.0f;
const float ExitAlpha = bExiting ? 1.0f - SmoothStep((LocalTime - SlamSeconds - Card.HoldSeconds) / ExitSeconds) : 1.0f;
const float Alpha = FMath::Clamp(EnterAlpha * ExitAlpha, 0.0f, 1.0f);
const float ImpactOvershoot = bEntering ? FMath::Sin((LocalTime / SlamSeconds) * PI) * 28.0f : 0.0f;
const float PanelWidth = FMath::Min(1120.0f, FMath::Max(420.0f, Size.X - 112.0f));
const float PanelHeight = FMath::Min(330.0f, FMath::Max(220.0f, Size.Y - 340.0f));
const FVector2D TargetPosition((Size.X - PanelWidth) * 0.5f, FMath::Max(275.0f, (Size.Y - PanelHeight) * 0.5f + 72.0f));
const float EnterOffset = bEntering ? FMath::Lerp(-Size.X * 0.85f, ImpactOvershoot, SmoothStep(LocalTime / SlamSeconds)) : 0.0f;
const float ExitOffset = bExiting ? FMath::Lerp(0.0f, Size.X * 0.9f, SmoothStep((LocalTime - SlamSeconds - Card.HoldSeconds) / ExitSeconds)) : 0.0f;
const FVector2D PanelPosition(TargetPosition.X + EnterOffset + ExitOffset, TargetPosition.Y);
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(Size), FSlateLayoutTransform(FVector2f::ZeroVector)),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.0f, 0.0f, 0.0f, 0.34f * Alpha));
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(PanelWidth, PanelHeight), FSlateLayoutTransform(FVector2f(PanelPosition))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.015f, 0.018f, 0.014f, 0.92f * Alpha));
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(PanelWidth, 5.0f), FSlateLayoutTransform(FVector2f(PanelPosition))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(Card.AccentColor.R, Card.AccentColor.G, Card.AccentColor.B, Alpha));
const FVector2D ArtSize(FMath::Min(275.0f, PanelWidth * 0.32f), PanelHeight - 64.0f);
const FVector2D ArtPosition(PanelPosition.X + 32.0f, PanelPosition.Y + 32.0f);
DrawCreditIllustration(OutDrawElements, LayerId, AllottedGeometry, ArtPosition, ArtSize, Card.IllustrationIndex, Card.AccentColor, Alpha);
const float TextX = ArtPosition.X + ArtSize.X + 42.0f;
const float TextWidth = PanelPosition.X + PanelWidth - TextX - 36.0f;
const FSlateFontInfo NameFont = FCoreStyle::GetDefaultFontStyle("Bold", ActiveIndex == 5 ? 46 : 56);
const FSlateFontInfo RoleFont = FCoreStyle::GetDefaultFontStyle("Regular", ActiveIndex == 5 ? 22 : 28);
const FSlateFontInfo LabelFont = FCoreStyle::GetDefaultFontStyle("Regular", 16);
const float NameY = PanelPosition.Y + (ActiveIndex == 5 ? 76.0f : 92.0f);
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(Card.Name), FVector2D(TextX, NameY), TextWidth, NameFont, FLinearColor(0.94f, 0.98f, 0.88f, Alpha));
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(Card.Role), FVector2D(TextX + 4.0f, NameY + 76.0f), TextWidth, RoleFont, FLinearColor(Card.AccentColor.R, Card.AccentColor.G, Card.AccentColor.B, Alpha));
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Agrarian startup credits")), FVector2D(TextX + 6.0f, PanelPosition.Y + PanelHeight - 58.0f), TextWidth, LabelFont, FLinearColor(0.64f, 0.70f, 0.60f, 0.82f * Alpha));
}
void UAgrarianDemoNoticeWidget::DrawCreditIllustration(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry,
const FVector2D& Position,
const FVector2D& Size,
int32 IllustrationIndex,
const FLinearColor& AccentColor,
float Alpha) const
{
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(Size), FSlateLayoutTransform(FVector2f(Position))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.07f, 0.08f, 0.065f, 0.96f * Alpha));
const FVector2D Center = Position + (Size * 0.5f);
const FLinearColor SoftAccent(AccentColor.R, AccentColor.G, AccentColor.B, 0.28f * Alpha);
const FLinearColor StrongAccent(AccentColor.R, AccentColor.G, AccentColor.B, Alpha);
auto DrawBox = [&](const FVector2D& BoxPosition, const FVector2D& BoxSize, const FLinearColor& Color)
{
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(BoxSize), FSlateLayoutTransform(FVector2f(BoxPosition))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
Color);
};
auto DrawLine = [&](const TArray<FVector2f>& Points, const FLinearColor& Color, float Thickness)
{
FSlateDrawElement::MakeLines(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(),
Points,
ESlateDrawEffect::None,
Color,
true,
Thickness);
};
DrawBox(Position + FVector2D(16.0f, 16.0f), FVector2D(Size.X - 32.0f, Size.Y - 32.0f), FLinearColor(0.0f, 0.0f, 0.0f, 0.22f * Alpha));
if (IllustrationIndex == 0)
{
DrawBox(Center + FVector2D(-72.0f, -46.0f), FVector2D(144.0f, 82.0f), SoftAccent);
DrawBox(Center + FVector2D(-62.0f, -36.0f), FVector2D(124.0f, 62.0f), FLinearColor(0.02f, 0.03f, 0.025f, Alpha));
DrawLine({ FVector2f(Center.X - 42.0f, Center.Y - 8.0f), FVector2f(Center.X - 8.0f, Center.Y - 28.0f), FVector2f(Center.X + 42.0f, Center.Y + 18.0f) }, StrongAccent, 4.0f);
DrawBox(Center + FVector2D(-34.0f, 48.0f), FVector2D(68.0f, 10.0f), StrongAccent);
}
else if (IllustrationIndex == 1)
{
DrawLine({ FVector2f(Center.X, Center.Y + 58.0f), FVector2f(Center.X, Center.Y - 48.0f) }, StrongAccent, 5.0f);
DrawLine({ FVector2f(Center.X, Center.Y - 8.0f), FVector2f(Center.X - 48.0f, Center.Y - 42.0f), FVector2f(Center.X - 74.0f, Center.Y - 20.0f) }, StrongAccent, 5.0f);
DrawLine({ FVector2f(Center.X, Center.Y + 2.0f), FVector2f(Center.X + 52.0f, Center.Y - 34.0f), FVector2f(Center.X + 80.0f, Center.Y - 10.0f) }, StrongAccent, 5.0f);
DrawBox(Center + FVector2D(-84.0f, 64.0f), FVector2D(168.0f, 8.0f), SoftAccent);
}
else if (IllustrationIndex == 2)
{
DrawBox(Center + FVector2D(-58.0f, -74.0f), FVector2D(116.0f, 148.0f), FLinearColor(0.93f, 0.88f, 0.72f, 0.22f * Alpha));
DrawBox(Center + FVector2D(-34.0f, -88.0f), FVector2D(68.0f, 20.0f), StrongAccent);
DrawLine({ FVector2f(Center.X - 32.0f, Center.Y - 26.0f), FVector2f(Center.X - 12.0f, Center.Y - 6.0f), FVector2f(Center.X + 42.0f, Center.Y - 48.0f) }, StrongAccent, 5.0f);
DrawBox(Center + FVector2D(-34.0f, 28.0f), FVector2D(68.0f, 5.0f), StrongAccent);
}
else if (IllustrationIndex == 3)
{
DrawBox(Center + FVector2D(-72.0f, -28.0f), FVector2D(144.0f, 56.0f), SoftAccent);
DrawLine({ FVector2f(Center.X - 70.0f, Center.Y), FVector2f(Center.X - 18.0f, Center.Y - 58.0f), FVector2f(Center.X + 32.0f, Center.Y + 44.0f), FVector2f(Center.X + 78.0f, Center.Y - 18.0f) }, StrongAccent, 5.0f);
DrawBox(Center + FVector2D(-16.0f, -16.0f), FVector2D(32.0f, 32.0f), FLinearColor(0.92f, 0.96f, 0.86f, 0.80f * Alpha));
}
else if (IllustrationIndex == 4)
{
DrawBox(Center + FVector2D(-64.0f, -58.0f), FVector2D(128.0f, 116.0f), SoftAccent);
DrawLine({ FVector2f(Center.X - 44.0f, Center.Y - 8.0f), FVector2f(Center.X - 8.0f, Center.Y + 28.0f), FVector2f(Center.X + 54.0f, Center.Y - 36.0f) }, StrongAccent, 5.0f);
DrawBox(Center + FVector2D(-74.0f, 74.0f), FVector2D(148.0f, 8.0f), StrongAccent);
DrawBox(Center + FVector2D(-74.0f, -82.0f), FVector2D(148.0f, 8.0f), StrongAccent);
}
else
{
DrawLine({ FVector2f(Center.X, Center.Y + 72.0f), FVector2f(Center.X, Center.Y - 36.0f) }, StrongAccent, 5.0f);
DrawLine({ FVector2f(Center.X, Center.Y - 12.0f), FVector2f(Center.X - 52.0f, Center.Y - 50.0f), FVector2f(Center.X - 80.0f, Center.Y - 28.0f) }, StrongAccent, 5.0f);
DrawLine({ FVector2f(Center.X, Center.Y - 6.0f), FVector2f(Center.X + 52.0f, Center.Y - 54.0f), FVector2f(Center.X + 84.0f, Center.Y - 28.0f) }, StrongAccent, 5.0f);
DrawBox(Center + FVector2D(-92.0f, 78.0f), FVector2D(184.0f, 8.0f), SoftAccent);
DrawBox(Center + FVector2D(-48.0f, 56.0f), FVector2D(96.0f, 8.0f), StrongAccent);
}
}
+30 -1
View File
@@ -12,11 +12,13 @@ class AGRARIANGAME_API UAgrarianDemoNoticeWidget : public UUserWidget
GENERATED_BODY() GENERATED_BODY()
public: public:
virtual void NativeConstruct() override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText Motto = FText::FromString(TEXT("What survives after you are gone?")); FText Motto = FText::FromString(TEXT("What survives after you are gone?"));
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.E - Build 2026.05.17")); FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.H - Build 2026.05.17"));
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution")); FText DemoNotice = FText::FromString(TEXT("Beta prototype build - not for public distribution"));
@@ -35,6 +37,8 @@ protected:
bool bParentEnabled) const override; bool bParentEnabled) const override;
private: private:
float CreditsStartTimeSeconds = 0.0f;
void DrawCenteredText( void DrawCenteredText(
FSlateWindowElementList& OutDrawElements, FSlateWindowElementList& OutDrawElements,
int32& LayerId, int32& LayerId,
@@ -43,4 +47,29 @@ private:
float Y, float Y,
const FSlateFontInfo& Font, const FSlateFontInfo& Font,
const FLinearColor& Color) const; const FLinearColor& Color) const;
void DrawTextAt(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry,
const FText& Text,
const FVector2D& Position,
float Width,
const FSlateFontInfo& Font,
const FLinearColor& Color) const;
void DrawCinematicCredits(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const;
void DrawCreditIllustration(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry,
const FVector2D& Position,
const FVector2D& Size,
int32 IllustrationIndex,
const FLinearColor& AccentColor,
float Alpha) const;
}; };