Link Eagle command info buttons to pedia (#8405)

* Link Eagle command info buttons to pedia

* Add tooltip to command pedia button

* Show command help on info hover

* Avoid toggling command help on hover

* Let command info button receive hover events

* Handle command info hover on icon

* Show command help on explicit hover

* Use local command info hover help

* Place command info help over map

* Refine command info hover placement

* Initialize command info popup before hover

* Place command help above command panel

* Use screen coordinates for command help placement

* Separate command hover help from warnings

* Add dedicated command info panel

* Show command help text in compact panel

* Simplify command help text layout

* Fit command help text within its card

* Size command help to its content
This commit is contained in:
2026-07-10 22:02:29 -07:00
committed by GitHub
parent 8e30daa63b
commit 25e1fd4f90
11 changed files with 1480 additions and 37 deletions
@@ -252,6 +252,7 @@ GameObject:
- component: {fileID: 6683023299962816235}
- component: {fileID: 8717522325687258930}
- component: {fileID: 200015323249856589}
- component: {fileID: 7077778108703359210}
m_Layer: 0
m_Name: Button
m_TagString: Untagged
@@ -374,6 +375,19 @@ MonoBehaviour:
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!114 &7077778108703359210
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2875629466417529807}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d809e028e4e54409bfb770ee807c0011, type: 3}
m_Name:
m_EditorClassIdentifier:
commandPanelController: {fileID: 7324589276743348464}
--- !u!1 &3310209433701943861
GameObject:
m_ObjectHideFlags: 0
@@ -522,6 +536,7 @@ GameObject:
- component: {fileID: 4684711845071233999}
- component: {fileID: 6807986872688972641}
- component: {fileID: 6087500686782489476}
- component: {fileID: 6087500686782489477}
m_Layer: 0
m_Name: Image
m_TagString: Untagged
@@ -586,6 +601,19 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &6087500686782489477
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6757486595306481428}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d809e028e4e54409bfb770ee807c0011, type: 3}
m_Name:
m_EditorClassIdentifier:
commandPanelController: {fileID: 7324589276743348464}
--- !u!1 &7551289278932657012
GameObject:
m_ObjectHideFlags: 0
@@ -0,0 +1,18 @@
using UnityEngine;
using UnityEngine.EventSystems;
namespace eagle {
public class CommandInfoButtonHoverController : MonoBehaviour,
IPointerEnterHandler,
IPointerExitHandler {
public CommandPanelController commandPanelController;
public void OnPointerEnter(PointerEventData eventData) {
commandPanelController.InfoButtonHovered();
}
public void OnPointerExit(PointerEventData eventData) {
commandPanelController.InfoButtonExited();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d809e028e4e54409bfb770ee807c0011
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using common.GUIUtils;
using Eagle0.Tutorial;
using Net.Eagle0.Eagle.Api;
using TMPro;
using UnityEngine;
@@ -10,6 +9,220 @@ using UnityEngine.UI;
namespace eagle {
public class CommandPanelController : MonoBehaviour {
private const string Eagle0pediaCommandsBaseUrl = "https://pedia.eagle0.net/commands/";
private static readonly Dictionary<
AvailableCommand.SealedValueOneofCase,
string> Eagle0pediaCommandAnchors = new() {
{ AvailableCommand.SealedValueOneofCase.AlmsCommand, "alms" },
{ AvailableCommand.SealedValueOneofCase.ApprehendOutlawCommand, "apprehend-outlaw" },
{ AvailableCommand.SealedValueOneofCase.ArmTroopsCommand, "arm-troops" },
{ AvailableCommand.SealedValueOneofCase.AttackDecisionCommand, "attack-decision" },
{ AvailableCommand.SealedValueOneofCase.BattleAftermathDecisionCommand,
"battle-aftermath-decision" },
{ AvailableCommand.SealedValueOneofCase.ControlWeatherAvailableCommand,
"control-weather" },
{ AvailableCommand.SealedValueOneofCase.DeclineQuestCommand, "decline-quest" },
{ AvailableCommand.SealedValueOneofCase.DefendCommand, "defend" },
{ AvailableCommand.SealedValueOneofCase.DiplomacyCommand, "diplomacy" },
{ AvailableCommand.SealedValueOneofCase.DivineCommand, "divine" },
{ AvailableCommand.SealedValueOneofCase.ExileVassalCommand, "exile-vassal" },
{ AvailableCommand.SealedValueOneofCase.FeastCommand, "feast" },
{ AvailableCommand.SealedValueOneofCase.HandleCapturedHeroCommand,
"handle-captured-hero" },
{ AvailableCommand.SealedValueOneofCase.HandleRiotCrackDownAvailableCommand,
"handle-riot" },
{ AvailableCommand.SealedValueOneofCase.HandleRiotDoNothingAvailableCommand,
"handle-riot" },
{ AvailableCommand.SealedValueOneofCase.HandleRiotGiveAvailableCommand, "handle-riot" },
{ AvailableCommand.SealedValueOneofCase.HeroGiftCommand, "hero-gift" },
{ AvailableCommand.SealedValueOneofCase.ImproveCommand, "improve" },
{ AvailableCommand.SealedValueOneofCase.IssueOrdersCommand, "issue-orders" },
{ AvailableCommand.SealedValueOneofCase.ManagePrisonerCommand, "manage-prisoners" },
{ AvailableCommand.SealedValueOneofCase.MarchCommand, "march" },
{ AvailableCommand.SealedValueOneofCase.OrganizeTroopsCommand, "organize-troops" },
{ AvailableCommand.SealedValueOneofCase.PleaseRecruitMeCommand, "please-recruit-me" },
{ AvailableCommand.SealedValueOneofCase.ReconCommand, "recon" },
{ AvailableCommand.SealedValueOneofCase.RecruitHeroesCommand, "recruit-heroes" },
{ AvailableCommand.SealedValueOneofCase.ResolveAllianceOfferCommand,
"resolve-alliance-offer" },
{ AvailableCommand.SealedValueOneofCase.ResolveBreakAllianceCommand,
"resolve-break-alliance" },
{ AvailableCommand.SealedValueOneofCase.ResolveInvitationCommand,
"resolve-invitation" },
{ AvailableCommand.SealedValueOneofCase.ResolveRansomOfferCommand,
"resolve-ransom-offer" },
{ AvailableCommand.SealedValueOneofCase.ResolveTributeCommand, "resolve-tribute" },
{ AvailableCommand.SealedValueOneofCase.ResolveTruceOfferCommand,
"resolve-truce-offer" },
{ AvailableCommand.SealedValueOneofCase.RestCommand, "rest" },
{ AvailableCommand.SealedValueOneofCase.ReturnCommand, "return" },
{ AvailableCommand.SealedValueOneofCase.SendSuppliesCommand, "send-supplies" },
{ AvailableCommand.SealedValueOneofCase.StartEpidemicCommand, "start-epidemic" },
{ AvailableCommand.SealedValueOneofCase.SuppressBeastsCommand, "suppress-beasts" },
{ AvailableCommand.SealedValueOneofCase.SwearBrotherhoodCommand, "swear-kinship" },
{ AvailableCommand.SealedValueOneofCase.TradeCommand, "trade" },
{ AvailableCommand.SealedValueOneofCase.TrainCommand, "train" },
{ AvailableCommand.SealedValueOneofCase.TravelCommand, "travel" },
};
private readonly struct CommandInfo {
public readonly string Title;
public readonly string Text;
public CommandInfo(string title, string text) {
Title = title;
Text = text;
}
}
private static readonly Dictionary<
AvailableCommand.SealedValueOneofCase,
CommandInfo> CommandInfos = new() {
{ AvailableCommand.SealedValueOneofCase.AlmsCommand,
new CommandInfo(
"Give Alms",
"Spend food to raise support in the province. Paladins are especially effective at this.") },
{ AvailableCommand.SealedValueOneofCase.ApprehendOutlawCommand,
new CommandInfo(
"Apprehend Outlaw",
"Send a hero to deal with an outlaw disrupting the province.") },
{ AvailableCommand.SealedValueOneofCase.ArmTroopsCommand,
new CommandInfo(
"Arm Troops",
"Improve battalion armament by spending available resources.") },
{ AvailableCommand.SealedValueOneofCase.AttackDecisionCommand,
new CommandInfo(
"Attack Decision",
"Choose how to resolve the strategic battle decision before tactical combat begins.") },
{ AvailableCommand.SealedValueOneofCase.BattleAftermathDecisionCommand,
new CommandInfo("Battle Aftermath", "Choose what to do after a battle has ended.") },
{ AvailableCommand.SealedValueOneofCase.ControlWeatherAvailableCommand,
new CommandInfo(
"Control Weather",
"Use a suitable hero to affect the weather in a province.") },
{ AvailableCommand.SealedValueOneofCase.DeclineQuestCommand,
new CommandInfo("Decline Quest", "Refuse the quest currently being offered.") },
{ AvailableCommand.SealedValueOneofCase.DefendCommand,
new CommandInfo(
"Defend",
"Assign heroes and battalions to defend a province and choose a fallback route.") },
{ AvailableCommand.SealedValueOneofCase.DiplomacyCommand,
new CommandInfo(
"Diplomacy",
"Send a diplomatic offer or demand to another faction.") },
{ AvailableCommand.SealedValueOneofCase.DivineCommand,
new CommandInfo(
"Divine",
"Ask a diviner for information about the world or another faction.") },
{ AvailableCommand.SealedValueOneofCase.ExileVassalCommand,
new CommandInfo(
"Exile Vassal",
"Remove a vassal from your faction, forcing them out of your service.") },
{ AvailableCommand.SealedValueOneofCase.FeastCommand,
new CommandInfo(
"Feast",
"Spend food and gold to improve loyalty and morale among your heroes.") },
{ AvailableCommand.SealedValueOneofCase.HandleCapturedHeroCommand,
new CommandInfo(
"Handle Captured Hero",
"Choose whether to recruit, imprison, exile, execute, or return a captured hero.") },
{ AvailableCommand.SealedValueOneofCase.HandleRiotCrackDownAvailableCommand,
new CommandInfo(
"Handle Riot",
"Crack down on a riot. This may restore order, but it is harsh.") },
{ AvailableCommand.SealedValueOneofCase.HandleRiotDoNothingAvailableCommand,
new CommandInfo("Handle Riot", "Ignore a riot and accept the consequences.") },
{ AvailableCommand.SealedValueOneofCase.HandleRiotGiveAvailableCommand,
new CommandInfo("Handle Riot", "Give resources to the populace to calm a riot.") },
{ AvailableCommand.SealedValueOneofCase.HeroGiftCommand,
new CommandInfo("Give to Hero", "Give gold to a hero to improve loyalty.") },
{ AvailableCommand.SealedValueOneofCase.ImproveCommand,
new CommandInfo(
"Improve Province",
"Use a hero to improve agriculture, economy, infrastructure, or devastation in the province.") },
{ AvailableCommand.SealedValueOneofCase.IssueOrdersCommand,
new CommandInfo(
"Issue Orders",
"Give standing orders that influence how a faction or force behaves.") },
{ AvailableCommand.SealedValueOneofCase.ManagePrisonerCommand,
new CommandInfo(
"Manage Prisoners",
"Release, move, exile, execute, or return imprisoned heroes.") },
{ AvailableCommand.SealedValueOneofCase.MarchCommand,
new CommandInfo(
"March",
"Move heroes, battalions, gold, and food from one province to another.") },
{ AvailableCommand.SealedValueOneofCase.OrganizeTroopsCommand,
new CommandInfo(
"Organize Troops",
"Create, merge, split, or disband battalions in the province.") },
{ AvailableCommand.SealedValueOneofCase.PleaseRecruitMeCommand,
new CommandInfo(
"Recruit Offer",
"Respond to a hero who wants to join your faction.") },
{ AvailableCommand.SealedValueOneofCase.ReconCommand,
new CommandInfo("Recon", "Send a hero to gather information about a province.") },
{ AvailableCommand.SealedValueOneofCase.RecruitHeroesCommand,
new CommandInfo(
"Recruit Heroes",
"Spend gold to recruit available heroes into your faction.") },
{ AvailableCommand.SealedValueOneofCase.ResolveAllianceOfferCommand,
new CommandInfo(
"Alliance Offer",
"Accept or reject another faction's alliance offer.") },
{ AvailableCommand.SealedValueOneofCase.ResolveBreakAllianceCommand,
new CommandInfo(
"Break Alliance",
"Resolve a diplomatic request to end an alliance.") },
{ AvailableCommand.SealedValueOneofCase.ResolveInvitationCommand,
new CommandInfo(
"Invitation",
"Accept or reject an invitation involving one of your heroes.") },
{ AvailableCommand.SealedValueOneofCase.ResolveRansomOfferCommand,
new CommandInfo(
"Ransom Offer",
"Accept or reject a ransom offer for imprisoned heroes.") },
{ AvailableCommand.SealedValueOneofCase.ResolveTributeCommand,
new CommandInfo(
"Tribute Demand",
"Respond to another faction's demand for tribute.") },
{ AvailableCommand.SealedValueOneofCase.ResolveTruceOfferCommand,
new CommandInfo("Truce Offer", "Accept or reject another faction's truce offer.") },
{ AvailableCommand.SealedValueOneofCase.RestCommand,
new CommandInfo(
"Rest",
"Let heroes recover vigor and prepare for future commands.") },
{ AvailableCommand.SealedValueOneofCase.ReturnCommand,
new CommandInfo(
"Return",
"Bring a hero back from their current assignment or situation.") },
{ AvailableCommand.SealedValueOneofCase.SendSuppliesCommand,
new CommandInfo(
"Send Supplies",
"Send food or gold to another province with a selected hero.") },
{ AvailableCommand.SealedValueOneofCase.StartEpidemicCommand,
new CommandInfo(
"Start Epidemic",
"Use a suitable hero to unleash disease in a province.") },
{ AvailableCommand.SealedValueOneofCase.SuppressBeastsCommand,
new CommandInfo(
"Suppress Beasts",
"Send a hero to deal with beasts threatening a province.") },
{ AvailableCommand.SealedValueOneofCase.SwearBrotherhoodCommand,
new CommandInfo(
"Swear Kinship",
"Bind heroes together to improve their relationship and loyalty.") },
{ AvailableCommand.SealedValueOneofCase.TradeCommand,
new CommandInfo(
"Trade",
"Exchange food and gold using the province's buy and sell prices.") },
{ AvailableCommand.SealedValueOneofCase.TrainCommand,
new CommandInfo("Train", "Have a hero train to improve their abilities.") },
{ AvailableCommand.SealedValueOneofCase.TravelCommand,
new CommandInfo("Travel", "Move a hero between provinces without moving an army.") },
};
public EagleGameController mainController;
public CommandSelector _selector;
@@ -33,8 +246,10 @@ namespace eagle {
public IGameModel Model { get; set; }
public ErrorHandler errorHandler;
public CommandWarningPanelController commandWarningPanelController;
public CommandWarningPanelController commandInfoPanelController;
private AvailableCommand _availableCommand;
private bool _commandInfoShowing;
public AvailableCommand AvailableCommand {
get => _availableCommand;
private
@@ -70,7 +285,7 @@ namespace eagle {
public void SetAvailableCommandAndSelector(AvailableCommand cmd, CommandSelector sel) {
// Check if command help is currently showing before changing selector
bool helpWasShowing = IsCommandHelpShowing();
bool helpWasShowing = _commandInfoShowing;
AvailableCommand = cmd;
Selector = sel;
@@ -95,38 +310,46 @@ namespace eagle {
}
}
/// <summary>
/// Returns true if a command help panel is currently showing.
/// </summary>
private bool IsCommandHelpShowing() {
var activeId = TutorialManager.Instance?.ActiveSequenceId;
return activeId != null && activeId.StartsWith("command_");
}
/// <summary>
/// Shows help for the current command (used when switching commands while help is open).
/// </summary>
private void ShowCurrentCommandHelp() {
if (Selector == null) return;
string tutorialId = GetCurrentCommandTutorialId();
if (tutorialId != null) { TutorialManager.Instance?.ShowCommandHelp(tutorialId); }
var info = GetCurrentCommandInfo();
commandInfoPanelController.SetInfo(info.Title, info.Text, (RectTransform)transform);
_commandInfoShowing = true;
}
/// <summary>
/// Gets the tutorial ID for the current command.
/// </summary>
private string GetCurrentCommandTutorialId() {
if (Selector == null) return null;
var commandName = Selector.CommandType.ToString();
if (commandName.EndsWith("Command")) {
commandName = commandName.Substring(0, commandName.Length - "Command".Length);
private void ToggleCurrentCommandHelp() {
if (_commandInfoShowing) {
commandInfoPanelController.ClearWarning();
_commandInfoShowing = false;
} else {
ShowCurrentCommandHelp();
}
var snakeCase = System.Text.RegularExpressions.Regex.Replace(
commandName,
"([a-z])([A-Z])",
"$1_$2");
return $"command_{snakeCase.ToLower()}";
}
public void InfoButtonHovered() {
if (Selector == null) return;
ShowCurrentCommandHelp();
}
public void InfoButtonExited() {
if (!_commandInfoShowing) return;
commandInfoPanelController.ClearWarning();
_commandInfoShowing = false;
}
private CommandInfo GetCurrentCommandInfo() {
if (Selector != null && CommandInfos.TryGetValue(Selector.CommandType, out var info)) {
return info;
}
return new CommandInfo(
Selector?.HeaderString ?? "Command",
"Open the command reference for complete details.");
}
public List<CommandSelector> AppropriateSelectors(AvailableCommand cmd) =>
@@ -164,12 +387,13 @@ namespace eagle {
public void Update() {
// '?' key (Shift + /) toggles help panel when a command is selected
if (Selector != null && GameInput.QuestionMarkPressed()) { InfoButtonClicked(); }
if (Selector != null && GameInput.QuestionMarkPressed()) { ToggleCurrentCommandHelp(); }
}
public void PointerEnteredCommitButton() {
if (Selector != null) {
if (!Selector.EnableCommitButton) {
_commandInfoShowing = false;
if (string.IsNullOrEmpty(Selector.DisabledCommitButtonReason)) {
commandWarningPanelController.SetWarning(
"Invalid",
@@ -180,6 +404,7 @@ namespace eagle {
Selector.DisabledCommitButtonReason);
}
} else if (Selector.WarnOnCommitButton) {
_commandInfoShowing = false;
commandWarningPanelController.SetWarning(
"Are you sure?",
Selector.CommitWarningText);
@@ -190,13 +415,21 @@ namespace eagle {
public void PointerExitedCommitButton() { commandWarningPanelController.ClearWarning(); }
/// <summary>
/// Called when the info button is clicked. Shows help for the current command.
/// Called when the info button is clicked. Opens the full command reference.
/// </summary>
public void InfoButtonClicked() {
if (Selector == null) return;
string tutorialId = GetCurrentCommandTutorialId();
if (tutorialId != null) { TutorialManager.Instance?.ShowCommandHelp(tutorialId); }
string url = GetCurrentCommandPediaUrl();
if (url != null) { Application.OpenURL(url); }
}
private string GetCurrentCommandPediaUrl() {
if (Selector == null) return null;
return Eagle0pediaCommandAnchors.TryGetValue(Selector.CommandType, out var anchor)
? $"{Eagle0pediaCommandsBaseUrl}#{anchor}"
: Eagle0pediaCommandsBaseUrl;
}
public void OnGUI() {
@@ -221,8 +454,10 @@ namespace eagle {
if (infoButton != null) { infoButton.gameObject.SetActive(true); }
if (disableWarningPanel) {
MainQueue.Q.EnqueueForNextUpdate(
() => { commandWarningPanelController.ClearWarning(); });
MainQueue.Q.EnqueueForNextUpdate(() => {
commandWarningPanelController.ClearWarning();
_commandInfoShowing = false;
});
}
}
} catch (Exception e) {
@@ -0,0 +1,984 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &58495604
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 58495605}
- component: {fileID: 58495607}
- component: {fileID: 58495608}
- component: {fileID: 58495606}
m_Layer: 0
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!224 &58495605
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 58495604}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0.00004119873}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 972466483}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -28}
m_SizeDelta: {x: -36, y: -76}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &58495606
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 58495604}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: -1
m_PreferredHeight: -1
m_FlexibleWidth: 1
m_FlexibleHeight: 1
m_LayoutPriority: 1
--- !u!222 &58495607
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 58495604}
m_CullTransparentMesh: 0
--- !u!114 &58495608
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 58495604}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "Four score and seven years ago our fathers brought forth upon this continent,
a new nation, conceived in Liberty, and dedicated to the proposition that all
men are created equal.\nNow we are engaged in a great civil war, testing whether
that nation, or any nation so conceived and so dedicated, can long endure. We
are met on a great battle-field of that war. We have come to dedicate a portion
of that field, as a final resting place for those who here gave their lives that
that nation might live. It is altogether fitting and proper that we should do
this.\n\nBut, in a larger sense, we can not dedicate\u2014we can not consecrate\u2014we
can not hallow\u2014this ground. The brave men, living and dead, who struggled
here, have consecrated it, far above our poor power to add or detract. The world
will little note, nor long remember what we say here, but it can never forget
what they did here. It is for us the living, rather, to be dedicated here to
the unfinished work which they who fought here have thus far so nobly advanced.
It is rather for us to be here dedicated to the great task remaining before us\u2014that
from these honored dead we take increased devotion to that cause for which they
gave the last full measure of devotion\u2014that we here highly resolve that
these dead shall not have died in vain\u2014that this nation, under God, shall
have a new birth of freedom\u2014and that government of the people, by the people,
for the people, shall not perish from the earth.\n\n--\nAt this second appearing
to take the oath of the presidential office, there is less occasion for an extended
address than there was at the first. Then a statement, somewhat in detail, of
a course to be pursued, seemed fitting and proper. Now, at the expiration of
four years, during which public declarations have been constantly called forth
on every point and phase of the great contest which still absorbs the attention,
and engrosses the enerergies of the nation, little that is new could be presented.
The progress of our arms, upon which all else chiefly depends, is as well known
to the public as to myself; and it is, I trust, reasonably satisfactory and encouraging
to all. With high hope for the future, no prediction in regard to it is ventured.\n\nOn
the occasion corresponding to this four years ago, all thoughts were anxiously
directed to an impending civil-war. All dreaded it -- all sought to avert it.
While the inaugeral address was being delivered from this place, devoted altogether
to saving the Union without war, insurgent agents were in the city seeking to
destroy it without war -- seeking to dissole the Union, and divide effects, by
negotiation. Both parties deprecated war; but one of them would make war rather
than let the nation survive; and the other would accept war rather than let it
perish. And the war came.\n\nOne eighth of the whole population were colored
slaves, not distributed generally over the Union, but localized in the Southern
half part of it. These slaves constituted a peculiar and powerful interest. All
knew that this interest was, somehow, the cause of the war. To strengthen, perpetuate,
and extend this interest was the object for which the insurgents would rend the
Union, even by war; while the government claimed no right to do more than to
restrict the territorial enlargement of it. Neither party expected for the war,
the magnitude, or the duration, which it has already attained. Neither anticipated
that the cause of the conflict might cease with, or even before, the conflict
itself should cease. Each looked for an easier triumph, and a result less fundamental
and astounding. Both read the same Bible, and pray to the same God; and each
invokes His aid against the other. It may seem strange that any men should dare
to ask a just God's assistance in wringing their bread from the sweat of other
men's faces; but let us judge not that we be not judged. The prayers of both
could not be answered; that of neither has been answered fully. The Almighty
has His own purposes. \"Woe unto the world because of offences! for it must needs
be that offences come; but woe to that man by whom the offence cometh!\" If we
shall suppose that American Slavery is one of those offences which, in the providence
of God, must needs come, but which, having continued through His appointed time,
He now wills to remove, and that He gives to both North and South, this terrible
war, as the woe due to those by whom the offence came, shall we discern therein
any departure from those divine attributes which the believers in a Living God
always ascribe to Him? Fondly do we hope -- fervently do we pray -- that this
mighty scourge of war may speedily pass away. Yet, if God wills that it continue,
until all the wealth piled by the bond-man's two hundred and fifty years of unrequited
toil shall be sunk, and until every drop of blood drawn with the lash, shall
be paid by another drawn with the sword, as was said f[our] three thousand years
ago, so still it must be said \"the judgments of the Lord, are true and righteous
altogether\"\n\nWith malice toward none; with charity for all; with firmness
in the right, as God gives us to see the right, let us strive on to finish the
work we are in; to bind up the nation's wounds; to care for him who shall have
borne the battle, and for his widow, and his orphan -- to achieve and cherish
a lasting peace among ourselves and with the world. to do all which may achieve
and cherish a just, and a lasting peace, among ourselves, and with the world.
all nations.\n\n"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: ec2736df0379a45bfa7349b652fd07d6, type: 2}
m_sharedMaterial: {fileID: 1026247389042360723, guid: ec2736df0379a45bfa7349b652fd07d6,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4278190080
m_fontColor: {r: 0, g: 0, b: 0, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 22
m_fontSizeBase: 22
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 1
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &312788434
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 312788435}
- component: {fileID: 312788437}
- component: {fileID: 312788436}
m_Layer: 0
m_Name: Handle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!224 &312788435
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 312788434}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1571989322}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.89239186}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 20, y: 20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &312788436
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 312788434}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &312788437
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 312788434}
m_CullTransparentMesh: 0
--- !u!1 &872978101
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 872978102}
- component: {fileID: 872978105}
- component: {fileID: 872978104}
- component: {fileID: 872978103}
m_Layer: 0
m_Name: Scroll View
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 0
--- !u!224 &872978102
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 872978101}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2139237571}
- {fileID: 1554185316}
m_Father: {fileID: 972466483}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -28}
m_SizeDelta: {x: -32, y: -82}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &872978103
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 872978101}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Content: {fileID: 935480733}
m_Horizontal: 0
m_Vertical: 1
m_MovementType: 2
m_Elasticity: 0.1
m_Inertia: 1
m_DecelerationRate: 0.135
m_ScrollSensitivity: 10
m_Viewport: {fileID: 2139237571}
m_HorizontalScrollbar: {fileID: 0}
m_VerticalScrollbar: {fileID: 1554185317}
m_HorizontalScrollbarVisibility: 2
m_VerticalScrollbarVisibility: 2
m_HorizontalScrollbarSpacing: -3
m_VerticalScrollbarSpacing: -3
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
--- !u!114 &872978104
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 872978101}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 0}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &872978105
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 872978101}
m_CullTransparentMesh: 0
--- !u!1 &935480732
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 935480733}
- component: {fileID: 935480735}
- component: {fileID: 935480734}
m_Layer: 0
m_Name: Content
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!224 &935480733
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 935480732}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 58495605}
m_Father: {fileID: 2139237571}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &935480734
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 935480732}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 5
m_Right: 5
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 1
m_ChildScaleWidth: 0
m_ChildScaleHeight: 0
m_ReverseArrangement: 0
--- !u!114 &935480735
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 935480732}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &972466481
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 972466483}
- component: {fileID: 972466485}
- component: {fileID: 972466484}
- component: {fileID: 972466482}
m_Layer: 0
m_Name: Command Info Panel
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 0
--- !u!114 &972466482
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 972466481}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6a522d3d61f4f4545b383b9533992a17, type: 3}
m_Name:
m_EditorClassIdentifier:
canvas: {fileID: 0}
mapController: {fileID: 0}
textField: {fileID: 58495608}
title: {fileID: 2065074679}
imagesAndNamesContainer: {fileID: 0}
firstImage: {fileID: 0}
firstName: {fileID: 0}
secondImage: {fileID: 0}
secondName: {fileID: 0}
thirdImage: {fileID: 0}
thirdName: {fileID: 0}
nextButton: {fileID: 0}
--- !u!224 &972466483
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 972466481}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2065074681}
- {fileID: 872978102}
- {fileID: 58495605}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &972466484
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 972466481}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.99215686, g: 0.80784315, b: 0.93333334, a: 0.85882354}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &972466485
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 972466481}
m_CullTransparentMesh: 0
--- !u!1 &1554185315
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1554185316}
- component: {fileID: 1554185319}
- component: {fileID: 1554185318}
- component: {fileID: 1554185317}
m_Layer: 0
m_Name: Scrollbar Vertical
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 0
--- !u!224 &1554185316
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1554185315}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1571989322}
m_Father: {fileID: 872978102}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 3, y: 0}
m_Pivot: {x: 1, y: 1}
--- !u!114 &1554185317
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1554185315}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 312788436}
m_HandleRect: {fileID: 312788435}
m_Direction: 2
m_Value: 1.0000001
m_Size: 0.10760812
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
m_Calls: []
--- !u!114 &1554185318
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1554185315}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1554185319
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1554185315}
m_CullTransparentMesh: 0
--- !u!1 &1571989321
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1571989322}
m_Layer: 0
m_Name: Sliding Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!224 &1571989322
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1571989321}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 312788435}
m_Father: {fileID: 1554185316}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -20, y: -20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &2065074678
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2065074681}
- component: {fileID: 2065074680}
- component: {fileID: 2065074679}
m_Layer: 0
m_Name: Title Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!114 &2065074679
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2065074678}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: A thing happened!
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: ec2736df0379a45bfa7349b652fd07d6, type: 2}
m_sharedMaterial: {fileID: 1026247389042360723, guid: ec2736df0379a45bfa7349b652fd07d6,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4278190080
m_fontColor: {r: 0, g: 0, b: 0, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 36
m_fontSizeBase: 36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_characterHorizontalScale: 1
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 00000000
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 1
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &2065074680
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2065074678}
m_CullTransparentMesh: 0
--- !u!224 &2065074681
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2065074678}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 972466483}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -20}
m_SizeDelta: {x: 0, y: 36}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &2139237570
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2139237571}
- component: {fileID: 2139237574}
- component: {fileID: 2139237573}
- component: {fileID: 2139237572}
m_Layer: 0
m_Name: Viewport
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 2147483647
m_IsActive: 1
--- !u!224 &2139237571
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2139237570}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 935480733}
m_Father: {fileID: 872978102}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!114 &2139237572
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2139237570}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ShowMaskGraphic: 0
--- !u!114 &2139237573
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2139237570}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &2139237574
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2139237570}
m_CullTransparentMesh: 0
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e42cfb09bd114e0e977be539621cc201
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -111,8 +111,8 @@ namespace eagle {
_model = model;
_availableCommand = ac;
SetUpUI();
// Note: Command tutorials are now shown via info button instead of automatic popups.
// See CommandPanelController.InfoButtonClicked() for the new flow.
// Note: Command tutorials are now opened explicitly instead of automatic popups.
// See CommandPanelController.ShowCurrentCommandHelp() for the help-panel flow.
}
}
}
@@ -1,11 +1,55 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace eagle {
using ProvinceId = Int32;
public class CommandWarningPanelController : PopupPanelController {
private static readonly Color InfoBackgroundColor = new(0.78f, 0.80f, 0.82f, 0.98f);
private RectTransform _rectTransform;
private Image _background;
private Vector2 _defaultAnchorMin;
private Vector2 _defaultAnchorMax;
private Vector2 _defaultAnchoredPosition;
private Vector2 _defaultPivot;
private Vector2 _defaultSizeDelta;
private Color _defaultBackgroundColor;
public override bool BlocksInteraction => false;
private void Awake() { InitializeCachedFields(); }
private void InitializeCachedFields() {
if (_rectTransform != null) return;
_rectTransform = (RectTransform)transform;
_background = GetComponent<Image>();
_defaultAnchorMin = _rectTransform.anchorMin;
_defaultAnchorMax = _rectTransform.anchorMax;
_defaultAnchoredPosition = _rectTransform.anchoredPosition;
_defaultPivot = _rectTransform.pivot;
_defaultSizeDelta = _rectTransform.sizeDelta;
_defaultBackgroundColor = _background.color;
}
public void SetWarning(string title, string text) {
InitializeCachedFields();
RestoreDefaultPlacement();
PopupInfos = new List<PopupInfo> { new PopupInfo {
titleText = title,
mainText = text,
affectedProvinceIds = new List<ProvinceId>()
} };
SetUpPanel();
}
public void SetInfo(string title, string text, RectTransform placementTarget) {
InitializeCachedFields();
PlaceInfoCard(placementTarget, title, text);
_background.color = InfoBackgroundColor;
PopupInfos = new List<PopupInfo> { new PopupInfo {
titleText = title,
mainText = text,
@@ -20,5 +64,63 @@ namespace eagle {
SetUpPanel();
}
}
private void RestoreDefaultPlacement() {
InitializeCachedFields();
_rectTransform.anchorMin = _defaultAnchorMin;
_rectTransform.anchorMax = _defaultAnchorMax;
_rectTransform.anchoredPosition = _defaultAnchoredPosition;
_rectTransform.pivot = _defaultPivot;
_rectTransform.sizeDelta = _defaultSizeDelta;
_background.color = _defaultBackgroundColor;
}
private void PlaceInfoCard(RectTransform target, string titleText, string bodyText) {
InitializeCachedFields();
var parent = _rectTransform.parent as RectTransform;
Vector3[] corners = new Vector3[4];
target.GetWorldCorners(corners);
var targetCanvas = target.GetComponentInParent<Canvas>();
var targetCamera = targetCanvas.renderMode == RenderMode.ScreenSpaceOverlay
? null
: targetCanvas.worldCamera;
var parentCanvas = parent.GetComponentInParent<Canvas>();
var parentCamera = parentCanvas.renderMode == RenderMode.ScreenSpaceOverlay
? null
: parentCanvas.worldCamera;
var bottomLeftScreen =
RectTransformUtility.WorldToScreenPoint(targetCamera, corners[0]);
var topRightScreen = RectTransformUtility.WorldToScreenPoint(targetCamera, corners[2]);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
parent,
bottomLeftScreen,
parentCamera,
out var bottomLeft);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
parent,
topRightScreen,
parentCamera,
out var topRight);
var size = topRight - bottomLeft;
var width = Mathf.Min(size.x - 32f, 760f);
var titleHeight = title.GetPreferredValues(titleText, width, 0f).y;
var bodyHeight = textField.GetPreferredValues(bodyText, width - 36f, 0f).y;
var maxHeight = Mathf.Max(200f, Mathf.Min(size.y * 0.8f, 320f));
var height = Mathf.Clamp(titleHeight + bodyHeight + 96f, 200f, maxHeight);
var margin = 18f;
_rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
_rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
_rectTransform.pivot = new Vector2(0.5f, 0.5f);
_rectTransform.anchoredPosition =
new Vector2(bottomLeft.x + size.x / 2f, topRight.y + margin + height / 2f);
_rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, width);
_rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
}
}
}
}
@@ -20,6 +20,7 @@ namespace eagle {
void Update() {
bool enable = false;
bool blocksInteraction = false;
PopupPanelController topmostActive = null;
// GetComponentsInChildren returns in hierarchy order; for direct children of `panel`,
@@ -27,10 +28,11 @@ namespace eagle {
foreach (var controller in panel.GetComponentsInChildren<PopupPanelController>()) {
bool hasInfo = controller.HasInfo;
enable = enable || hasInfo;
blocksInteraction = blocksInteraction || (hasInfo && controller.BlocksInteraction);
controller.gameObject.SetActive(hasInfo);
if (hasInfo) topmostActive = controller;
}
modalBlocker.SetActive(enable);
modalBlocker.SetActive(blocksInteraction);
panel.SetActive(enable);
if (topmostActive != null) {
@@ -59,4 +61,4 @@ namespace eagle {
// }
}
}
}
}
@@ -44,6 +44,7 @@ namespace eagle {
}
public bool HasInfo => PopupInfos.Count > 0;
public virtual bool BlocksInteraction => true;
/// <summary>
/// Provinces the currently displayed popup wants highlighted on the map.
@@ -1489,6 +1489,7 @@ RectTransform:
m_Children:
- {fileID: 264866237}
- {fileID: 604968799}
- {fileID: 817263945010001003}
m_Father: {fileID: 333844767}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -2356,6 +2357,11 @@ PrefabInstance:
propertyPath: commandWarningPanelController
value:
objectReference: {fileID: 972466482}
- target: {fileID: 8023117543167758928, guid: 7c4a3d4c82fcc4ea99f89afc50397fb1,
type: 3}
propertyPath: commandInfoPanelController
value:
objectReference: {fileID: 817263945010001002}
- target: {fileID: 8537954466009178725, guid: 7c4a3d4c82fcc4ea99f89afc50397fb1,
type: 3}
propertyPath: factionPopup
@@ -2471,6 +2477,55 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 4263c2dff8577344814ecd7f6f156c4f, type: 3}
--- !u!1001 &817263945010001001
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 1687917611}
m_Modifications:
- target: {fileID: 972466482, guid: e42cfb09bd114e0e977be539621cc201, type: 3}
propertyPath: canvas
value:
objectReference: {fileID: 1687917612}
- target: {fileID: 972466482, guid: e42cfb09bd114e0e977be539621cc201, type: 3}
propertyPath: mapController
value:
objectReference: {fileID: 779596829}
- target: {fileID: 972466483, guid: e42cfb09bd114e0e977be539621cc201, type: 3}
propertyPath: m_Name
value: Command Info Panel
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: e42cfb09bd114e0e977be539621cc201, type: 3}
--- !u!1 &817263945010001004 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 972466481, guid: e42cfb09bd114e0e977be539621cc201,
type: 3}
m_PrefabInstance: {fileID: 817263945010001001}
m_PrefabAsset: {fileID: 0}
--- !u!114 &817263945010001002 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 972466482, guid: e42cfb09bd114e0e977be539621cc201,
type: 3}
m_PrefabInstance: {fileID: 817263945010001001}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 817263945010001004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6a522d3d61f4f4545b383b9533992a17, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!224 &817263945010001003 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 972466483, guid: e42cfb09bd114e0e977be539621cc201,
type: 3}
m_PrefabInstance: {fileID: 817263945010001001}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &8377000000000000001
PrefabInstance:
m_ObjectHideFlags: 0