Compare commits
23 Commits
4d3e9da172
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76a513b577 | ||
|
|
bec90a20a0 | ||
|
|
fbe588c854 | ||
|
|
4c110f98c0 | ||
|
|
cd0ef3c73a | ||
|
|
691c80343e | ||
|
|
2c283c6623 | ||
|
|
d0a16d1e44 | ||
|
|
e2fa430d50 | ||
| 0cb9be4070 | |||
| 3221488a9e | |||
| 43ea25b9e3 | |||
| b34e135610 | |||
| 24a09dac43 | |||
| cf44edc19a | |||
| 3c5507dd87 | |||
| 9ded503704 | |||
| 8ea4b173a3 | |||
| 3ff9819d78 | |||
|
|
94511923d5 | ||
|
|
2435f0d27f | ||
|
|
352ba8a27b | ||
|
|
501312e0c2 |
@@ -29,3 +29,8 @@ MonoBehaviour:
|
||||
SourcePrefabToOverride: {fileID: 0}
|
||||
SourceHashToOverride: 0
|
||||
OverridingTargetPrefab: {fileID: 0}
|
||||
- Override: 0
|
||||
Prefab: {fileID: 1170732337855516, guid: d086cbb30c7bb4ba3a58cb2024fa0b31, type: 3}
|
||||
SourcePrefabToOverride: {fileID: 0}
|
||||
SourceHashToOverride: 0
|
||||
OverridingTargetPrefab: {fileID: 0}
|
||||
|
||||
200
Editor/LobbyPanelBuilder.cs
Normal file
200
Editor/LobbyPanelBuilder.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
#if UNITY_EDITOR
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace MegaKoop.EditorTools
|
||||
{
|
||||
internal sealed class LobbyPanelBuilder
|
||||
{
|
||||
private readonly Transform _parent;
|
||||
|
||||
internal LobbyPanelBuilder(Transform parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
internal GameObject Build()
|
||||
{
|
||||
var panelLobby = UGUIBuilderUtils.CreatePanel(_parent, "Panel_Lobby", new Vector2(1100, 820));
|
||||
panelLobby.SetActive(false);
|
||||
|
||||
var lobbyContainer = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
panelLobby.transform,
|
||||
"Lobby_VLayout",
|
||||
16f,
|
||||
TextAnchor.UpperCenter,
|
||||
new RectOffset(24, 24, 24, 24));
|
||||
|
||||
var lobbyHeader = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Lobby_Header",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 10));
|
||||
UGUIBuilderUtils.CreateText(lobbyHeader.transform, "Text_LobbyTitle", "MULTIPLAYER LOBBY", 36, TextAnchor.MiddleLeft, new Color(0.7f, 1f, 0.7f), FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateText(lobbyHeader.transform, "Text_Status", "OFFLINE", 18, TextAnchor.MiddleRight, new Color(0.8f, 0.8f, 0.8f), FontStyles.Bold);
|
||||
|
||||
var codeGroup = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Lobby_CodeGroup",
|
||||
8f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(10, 10, 10, 10));
|
||||
UGUIBuilderUtils.CreateText(codeGroup.transform, "Text_LobbyCodeLabel", "LOBBY CODE", 16, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Bold);
|
||||
var codeRow = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
codeGroup.transform,
|
||||
"Lobby_CodeRow",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateText(codeRow.transform, "Text_LobbyCodeValue", "------", 44, TextAnchor.MiddleCenter, new Color(0.7f, 1f, 0.7f), FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateMenuButton(codeRow.transform, "Button_CopyCode", "COPY");
|
||||
UGUIBuilderUtils.CreateText(codeGroup.transform, "Text_LobbyCodeHint", "Share this code with friends to invite them", 12, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Normal);
|
||||
|
||||
var tabs = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Lobby_Tabs",
|
||||
0f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateMenuButton(tabs.transform, "Button_HostTab", "HOST LOBBY");
|
||||
UGUIBuilderUtils.CreateMenuButton(tabs.transform, "Button_JoinTab", "JOIN LOBBY");
|
||||
|
||||
var joinGroup = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Group_Join",
|
||||
10f,
|
||||
TextAnchor.UpperCenter,
|
||||
new RectOffset(10, 10, 10, 10));
|
||||
var joinRow = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
joinGroup.transform,
|
||||
"Join_Row",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateInputField(joinRow.transform, "Input_LobbyCode", "Enter 6-digit code...");
|
||||
UGUIBuilderUtils.CreateMenuButton(joinGroup.transform, "Button_Connect", "CONNECT");
|
||||
|
||||
var hostGroup = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Group_Host",
|
||||
10f,
|
||||
TextAnchor.UpperCenter,
|
||||
new RectOffset(10, 10, 10, 10));
|
||||
UGUIBuilderUtils.CreateDropdown(hostGroup.transform, "Dropdown_MaxPlayers", new[] { "2", "3", "4", "8" });
|
||||
UGUIBuilderUtils.CreateToggle(hostGroup.transform, "Toggle_PublicLobby", "Public", true);
|
||||
UGUIBuilderUtils.CreateMenuButton(hostGroup.transform, "Button_CreateLobby", "CREATE LOBBY");
|
||||
|
||||
var playersHeader = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Players_Header",
|
||||
10f,
|
||||
TextAnchor.MiddleLeft,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateText(playersHeader.transform, "Text_PlayersTitle", "PLAYERS", 20, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateText(playersHeader.transform, "Text_PlayerCount", "0/4", 18, TextAnchor.MiddleRight, new Color(0.7f, 1f, 0.7f), FontStyles.Bold);
|
||||
|
||||
var scroll = UGUIBuilderUtils.CreateScrollList(
|
||||
lobbyContainer.transform,
|
||||
out var playersContent,
|
||||
"Scroll_Players",
|
||||
"Viewport",
|
||||
"Content_PlayersList");
|
||||
UGUIBuilderUtils.CreateText(lobbyContainer.transform, "Empty_Players", "Waiting for players...", 16, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Italic);
|
||||
|
||||
var template = new GameObject("PlayerItemTemplate", typeof(RectTransform), typeof(HorizontalLayoutGroup));
|
||||
template.transform.SetParent(playersContent, false);
|
||||
var hlg = template.GetComponent<HorizontalLayoutGroup>();
|
||||
hlg.childAlignment = TextAnchor.MiddleLeft;
|
||||
hlg.spacing = 12;
|
||||
hlg.childControlWidth = false;
|
||||
hlg.childForceExpandWidth = true;
|
||||
var avatar = UGUIBuilderUtils.CreateImage(template.transform, "Image_Avatar", new Color(0.3f, 0.6f, 0.3f));
|
||||
var name = UGUIBuilderUtils.CreateText(template.transform, "Text_PlayerName", "Player", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
var status = UGUIBuilderUtils.CreateText(template.transform, "Text_PlayerStatus", "NOT READY", 14, TextAnchor.MiddleRight, new Color(0.8f, 0.8f, 0.8f), FontStyles.Bold);
|
||||
((RectTransform)avatar.transform).sizeDelta = new Vector2(40, 40);
|
||||
template.SetActive(false);
|
||||
|
||||
var hostControls = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Host_Controls",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateMenuButton(hostControls.transform, "Button_InviteFriends", "INVITE FRIENDS");
|
||||
UGUIBuilderUtils.CreateMenuButton(hostControls.transform, "Button_KickSelected", "KICK SELECTED");
|
||||
|
||||
var friendsOverlay = new GameObject("Panel_Friends", typeof(RectTransform), typeof(Image));
|
||||
friendsOverlay.transform.SetParent(panelLobby.transform, false);
|
||||
var ovRT = (RectTransform)friendsOverlay.transform;
|
||||
ovRT.anchorMin = Vector2.zero;
|
||||
ovRT.anchorMax = Vector2.one;
|
||||
ovRT.offsetMin = Vector2.zero;
|
||||
ovRT.offsetMax = Vector2.zero;
|
||||
var ovImg = friendsOverlay.GetComponent<Image>();
|
||||
ovImg.color = new Color(0, 0, 0, 0.55f);
|
||||
friendsOverlay.SetActive(false);
|
||||
|
||||
var closeBg = new GameObject("Button_CloseFriendsOverlay", typeof(RectTransform), typeof(Image), typeof(Button));
|
||||
closeBg.transform.SetParent(friendsOverlay.transform, false);
|
||||
var closeBgRT = (RectTransform)closeBg.transform;
|
||||
closeBgRT.anchorMin = Vector2.zero;
|
||||
closeBgRT.anchorMax = Vector2.one;
|
||||
closeBgRT.offsetMin = Vector2.zero;
|
||||
closeBgRT.offsetMax = Vector2.zero;
|
||||
var closeBgImg = closeBg.GetComponent<Image>();
|
||||
closeBgImg.color = new Color(0, 0, 0, 0);
|
||||
|
||||
var friendsWindow = UGUIBuilderUtils.CreatePanel(friendsOverlay.transform, "Friends_Window", new Vector2(900, 420));
|
||||
var friendsV = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
friendsWindow.transform,
|
||||
"Friends_VLayout",
|
||||
8f,
|
||||
TextAnchor.UpperCenter,
|
||||
new RectOffset(16, 16, 16, 16));
|
||||
UGUIBuilderUtils.CreateText(friendsV.transform, "Text_FriendsTitle", "INVITE FRIENDS", 24, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateText(friendsV.transform, "Text_FriendsHint", "Select a friend to send a Steam invite.", 12, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Normal);
|
||||
UGUIBuilderUtils.CreateScrollList(friendsV.transform, out var friendsContent, "Scroll_Friends", "Viewport", "Content_FriendsList");
|
||||
var vlgFriends = friendsContent.GetComponent<VerticalLayoutGroup>();
|
||||
if (vlgFriends)
|
||||
{
|
||||
Object.DestroyImmediate(vlgFriends);
|
||||
}
|
||||
var gridFriends = friendsContent.gameObject.AddComponent<GridLayoutGroup>();
|
||||
gridFriends.cellSize = new Vector2(72, 72);
|
||||
gridFriends.spacing = new Vector2(10, 10);
|
||||
gridFriends.startAxis = GridLayoutGroup.Axis.Horizontal;
|
||||
var csfFriends = friendsContent.GetComponent<ContentSizeFitter>();
|
||||
if (csfFriends == null)
|
||||
{
|
||||
csfFriends = friendsContent.gameObject.AddComponent<ContentSizeFitter>();
|
||||
}
|
||||
csfFriends.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
UGUIBuilderUtils.CreateText(friendsV.transform, "Empty_Friends", "No friends found.", 14, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Italic);
|
||||
var friendsFooter = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
friendsV.transform,
|
||||
"Friends_Footer",
|
||||
8f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateMenuButton(friendsFooter.transform, "Button_BackFromFriends", "BACK");
|
||||
|
||||
UGUIBuilderUtils.CreateMenuButton(lobbyContainer.transform, "Button_ToggleReady", "TOGGLE READY");
|
||||
|
||||
var footer = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
lobbyContainer.transform,
|
||||
"Lobby_Footer",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateMenuButton(footer.transform, "Button_StartGame", "START GAME");
|
||||
UGUIBuilderUtils.CreateMenuButton(footer.transform, "Button_LeaveLobby", "LEAVE LOBBY");
|
||||
UGUIBuilderUtils.CreateMenuButton(footer.transform, "Button_BackFromLobby", "BACK TO MENU");
|
||||
|
||||
return panelLobby;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Editor/LobbyPanelBuilder.cs.meta
Normal file
2
Editor/LobbyPanelBuilder.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46d584193d4545f45b0a8a344fa11093
|
||||
40
Editor/MainMenuPanelBuilder.cs
Normal file
40
Editor/MainMenuPanelBuilder.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
#if UNITY_EDITOR
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace MegaKoop.EditorTools
|
||||
{
|
||||
internal sealed class MainMenuPanelBuilder
|
||||
{
|
||||
private readonly Transform _parent;
|
||||
|
||||
internal MainMenuPanelBuilder(Transform parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
internal GameObject Build()
|
||||
{
|
||||
var panelMain = UGUIBuilderUtils.CreatePanel(_parent, "Panel_MainMenu", new Vector2(900, 800));
|
||||
|
||||
var mainContainer = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
panelMain.transform,
|
||||
"Main_VLayout",
|
||||
20f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(30, 30, 30, 30));
|
||||
|
||||
UGUIBuilderUtils.CreateText(mainContainer.transform, "Text_Title", "MEGA KOOP", 70, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateText(mainContainer.transform, "Text_Subtitle", "CO-OP ADVENTURE", 20, TextAnchor.MiddleCenter, new Color(0.8f, 0.8f, 0.8f), FontStyles.Normal);
|
||||
UGUIBuilderUtils.CreateSpacer(mainContainer.transform, 20f);
|
||||
|
||||
UGUIBuilderUtils.CreateMenuButton(mainContainer.transform, "Button_Multiplayer", "MULTIPLAYER");
|
||||
UGUIBuilderUtils.CreateMenuButton(mainContainer.transform, "Button_Settings", "SETTINGS");
|
||||
UGUIBuilderUtils.CreateMenuButton(mainContainer.transform, "Button_Quit", "QUIT GAME", isDanger: true);
|
||||
|
||||
return panelMain;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Editor/MainMenuPanelBuilder.cs.meta
Normal file
2
Editor/MainMenuPanelBuilder.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c43d178d57dd2ae4db117649aad9e5b7
|
||||
67
Editor/SettingsPanelBuilder.cs
Normal file
67
Editor/SettingsPanelBuilder.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
#if UNITY_EDITOR
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace MegaKoop.EditorTools
|
||||
{
|
||||
internal sealed class SettingsPanelBuilder
|
||||
{
|
||||
private readonly Transform _parent;
|
||||
|
||||
internal SettingsPanelBuilder(Transform parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
internal GameObject Build()
|
||||
{
|
||||
var panelSettings = UGUIBuilderUtils.CreatePanel(_parent, "Panel_Settings", new Vector2(900, 800));
|
||||
panelSettings.SetActive(false);
|
||||
|
||||
var settingsContainer = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
panelSettings.transform,
|
||||
"Settings_VLayout",
|
||||
16f,
|
||||
TextAnchor.UpperCenter,
|
||||
new RectOffset(30, 30, 30, 30));
|
||||
|
||||
UGUIBuilderUtils.CreateText(settingsContainer.transform, "Text_SettingsTitle", "SETTINGS", 48, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateSpacer(settingsContainer.transform, 10f);
|
||||
|
||||
var gfxGroup = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
settingsContainer.transform,
|
||||
"Graphics_Group",
|
||||
10f,
|
||||
TextAnchor.UpperLeft,
|
||||
new RectOffset(10, 10, 10, 10));
|
||||
UGUIBuilderUtils.CreateText(gfxGroup.transform, "Text_Graphics", "Graphics", 24, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateDropdown(gfxGroup.transform, "Dropdown_Quality", new[] { "Low", "Medium", "High", "Ultra" });
|
||||
UGUIBuilderUtils.CreateToggle(gfxGroup.transform, "Toggle_Fullscreen", "Fullscreen", true);
|
||||
UGUIBuilderUtils.CreateDropdown(gfxGroup.transform, "Dropdown_Resolution", new[] { "1280x720", "1920x1080", "2560x1440", "3840x2160" });
|
||||
|
||||
var audioGroup = UGUIBuilderUtils.CreateVerticalGroup(
|
||||
settingsContainer.transform,
|
||||
"Audio_Group",
|
||||
10f,
|
||||
TextAnchor.UpperLeft,
|
||||
new RectOffset(10, 10, 10, 10));
|
||||
UGUIBuilderUtils.CreateText(audioGroup.transform, "Text_Audio", "Audio", 24, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
UGUIBuilderUtils.CreateLabeledSlider(audioGroup.transform, "Master Volume", "Slider_MasterVolume", 0, 100, 100);
|
||||
UGUIBuilderUtils.CreateLabeledSlider(audioGroup.transform, "Music Volume", "Slider_MusicVolume", 0, 100, 80);
|
||||
UGUIBuilderUtils.CreateLabeledSlider(audioGroup.transform, "SFX Volume", "Slider_SFXVolume", 0, 100, 100);
|
||||
|
||||
var buttonsRow = UGUIBuilderUtils.CreateHorizontalGroup(
|
||||
settingsContainer.transform,
|
||||
"Settings_Buttons",
|
||||
10f,
|
||||
TextAnchor.MiddleCenter,
|
||||
new RectOffset(0, 0, 0, 0));
|
||||
UGUIBuilderUtils.CreateMenuButton(buttonsRow.transform, "Button_ApplySettings", "APPLY");
|
||||
UGUIBuilderUtils.CreateMenuButton(buttonsRow.transform, "Button_BackFromSettings", "BACK");
|
||||
|
||||
return panelSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Editor/SettingsPanelBuilder.cs.meta
Normal file
2
Editor/SettingsPanelBuilder.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f247737932b5ac4f83890f357d265f6
|
||||
432
Editor/UGUIBuilderUtils.cs
Normal file
432
Editor/UGUIBuilderUtils.cs
Normal file
@@ -0,0 +1,432 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace MegaKoop.EditorTools
|
||||
{
|
||||
internal static class UGUIBuilderUtils
|
||||
{
|
||||
internal static GameObject CreatePanel(Transform parent, string name, Vector2 size)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rt.pivot = new Vector2(0.5f, 0.5f);
|
||||
rt.sizeDelta = size;
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = new Color(0.13f, 0.13f, 0.13f, 0.95f);
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateVerticalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = new Vector2(0, 0);
|
||||
rt.anchorMax = new Vector2(1, 1);
|
||||
rt.offsetMin = Vector2.zero;
|
||||
rt.offsetMax = Vector2.zero;
|
||||
var vlg = go.GetComponent<VerticalLayoutGroup>();
|
||||
vlg.spacing = spacing;
|
||||
vlg.childAlignment = align;
|
||||
vlg.padding = padding;
|
||||
vlg.childForceExpandWidth = true;
|
||||
vlg.childControlWidth = true;
|
||||
vlg.childControlHeight = false;
|
||||
var fitter = go.GetComponent<ContentSizeFitter>();
|
||||
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateHorizontalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(HorizontalLayoutGroup));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = new Vector2(0, 0);
|
||||
rt.anchorMax = new Vector2(1, 0);
|
||||
rt.pivot = new Vector2(0.5f, 0.5f);
|
||||
rt.sizeDelta = new Vector2(0, 60);
|
||||
var hlg = go.GetComponent<HorizontalLayoutGroup>();
|
||||
hlg.spacing = spacing;
|
||||
hlg.childAlignment = align;
|
||||
hlg.padding = padding;
|
||||
hlg.childControlWidth = true;
|
||||
hlg.childForceExpandWidth = true;
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateText(Transform parent, string name, string text, int fontSize, TextAnchor anchor, Color color, FontStyles fontStyle)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement));
|
||||
go.transform.SetParent(parent, false);
|
||||
var tmp = go.GetComponent<TextMeshProUGUI>();
|
||||
tmp.text = text;
|
||||
tmp.fontSize = fontSize;
|
||||
tmp.color = color;
|
||||
tmp.alignment = MapAlignment(anchor);
|
||||
tmp.fontStyle = fontStyle;
|
||||
tmp.enableWordWrapping = false;
|
||||
tmp.raycastTarget = false;
|
||||
if (TMP_Settings.defaultFontAsset != null)
|
||||
{
|
||||
tmp.font = TMP_Settings.defaultFontAsset;
|
||||
}
|
||||
var le = go.GetComponent<LayoutElement>();
|
||||
le.minHeight = Mathf.Max(24, fontSize + 12);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(0, fontSize + 20);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static TextAlignmentOptions MapAlignment(TextAnchor anchor)
|
||||
{
|
||||
switch (anchor)
|
||||
{
|
||||
case TextAnchor.UpperLeft: return TextAlignmentOptions.TopLeft;
|
||||
case TextAnchor.UpperCenter: return TextAlignmentOptions.Top;
|
||||
case TextAnchor.UpperRight: return TextAlignmentOptions.TopRight;
|
||||
case TextAnchor.MiddleLeft: return TextAlignmentOptions.MidlineLeft;
|
||||
case TextAnchor.MiddleCenter: return TextAlignmentOptions.Midline;
|
||||
case TextAnchor.MiddleRight: return TextAlignmentOptions.MidlineRight;
|
||||
case TextAnchor.LowerLeft: return TextAlignmentOptions.BottomLeft;
|
||||
case TextAnchor.LowerCenter: return TextAlignmentOptions.Bottom;
|
||||
case TextAnchor.LowerRight: return TextAlignmentOptions.BottomRight;
|
||||
default: return TextAlignmentOptions.Center;
|
||||
}
|
||||
}
|
||||
|
||||
internal static GameObject CreateMenuButton(Transform parent, string name, string label, bool isDanger = false)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = isDanger ? new Color(0.5f, 0.15f, 0.15f, 0.9f) : new Color(0.25f, 0.5f, 0.25f, 0.9f);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(0, 48);
|
||||
var leBtn = go.AddComponent<LayoutElement>();
|
||||
leBtn.flexibleWidth = 1;
|
||||
leBtn.minHeight = 48;
|
||||
var text = CreateText(go.transform, "Text", label, 20, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
var textRT = (RectTransform)text.transform;
|
||||
textRT.anchorMin = new Vector2(0, 0);
|
||||
textRT.anchorMax = new Vector2(1, 1);
|
||||
textRT.offsetMin = Vector2.zero;
|
||||
textRT.offsetMax = Vector2.zero;
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateInputField(Transform parent, string name, string placeholder)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_InputField));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = new Color(0.1f, 0.1f, 0.1f, 0.9f);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(600, 50);
|
||||
var viewport = new GameObject("TextViewport", typeof(RectTransform));
|
||||
viewport.transform.SetParent(go.transform, false);
|
||||
var viewportRT = (RectTransform)viewport.transform;
|
||||
viewportRT.anchorMin = new Vector2(0, 0);
|
||||
viewportRT.anchorMax = new Vector2(1, 1);
|
||||
viewportRT.offsetMin = new Vector2(10, 6);
|
||||
viewportRT.offsetMax = new Vector2(-10, -6);
|
||||
var text = CreateText(viewport.transform, "Text", string.Empty, 20, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var placeholderGO = CreateText(viewport.transform, "Placeholder", placeholder, 18, TextAnchor.MiddleLeft, new Color(0.7f, 0.7f, 0.7f), FontStyles.Italic);
|
||||
var input = go.GetComponent<TMP_InputField>();
|
||||
input.textViewport = viewportRT;
|
||||
input.textComponent = text.GetComponent<TextMeshProUGUI>();
|
||||
input.placeholder = placeholderGO.GetComponent<TextMeshProUGUI>();
|
||||
var tRT = (RectTransform)text.transform;
|
||||
tRT.anchorMin = new Vector2(0, 0);
|
||||
tRT.anchorMax = new Vector2(1, 1);
|
||||
tRT.offsetMin = new Vector2(10, 0);
|
||||
tRT.offsetMax = new Vector2(-10, 0);
|
||||
var pRT = (RectTransform)placeholderGO.transform;
|
||||
pRT.anchorMin = new Vector2(0, 0);
|
||||
pRT.anchorMax = new Vector2(1, 1);
|
||||
pRT.offsetMin = new Vector2(10, 0);
|
||||
pRT.offsetMax = new Vector2(-10, 0);
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateDropdown(Transform parent, string name, string[] options)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_Dropdown));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = new Color(0.2f, 0.2f, 0.2f, 0.9f);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(600, 50);
|
||||
|
||||
var caption = CreateText(go.transform, "Label", options.FirstOrDefault() ?? "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var arrow = CreateText(go.transform, "Arrow", "▼", 18, TextAnchor.MiddleRight, Color.white, FontStyles.Bold);
|
||||
|
||||
var template = new GameObject("Template", typeof(RectTransform), typeof(Image), typeof(ScrollRect));
|
||||
template.transform.SetParent(go.transform, false);
|
||||
var templateRT = (RectTransform)template.transform;
|
||||
templateRT.anchorMin = new Vector2(0, 0);
|
||||
templateRT.anchorMax = new Vector2(1, 0);
|
||||
templateRT.pivot = new Vector2(0.5f, 1f);
|
||||
templateRT.sizeDelta = new Vector2(0, 220);
|
||||
template.SetActive(false);
|
||||
var templateImg = template.GetComponent<Image>();
|
||||
templateImg.color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
|
||||
|
||||
var tplCanvas = template.GetComponent<Canvas>();
|
||||
if (tplCanvas == null)
|
||||
{
|
||||
tplCanvas = template.AddComponent<Canvas>();
|
||||
}
|
||||
tplCanvas.overrideSorting = true;
|
||||
tplCanvas.sortingOrder = 5000;
|
||||
if (!template.GetComponent<GraphicRaycaster>())
|
||||
{
|
||||
template.AddComponent<GraphicRaycaster>();
|
||||
}
|
||||
|
||||
var viewport = new GameObject("Viewport", typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
viewport.transform.SetParent(template.transform, false);
|
||||
var viewportRT = (RectTransform)viewport.transform;
|
||||
viewportRT.anchorMin = new Vector2(0, 0);
|
||||
viewportRT.anchorMax = new Vector2(1, 1);
|
||||
viewportRT.offsetMin = Vector2.zero;
|
||||
viewportRT.offsetMax = Vector2.zero;
|
||||
var vImg = viewport.GetComponent<Image>();
|
||||
vImg.color = new Color(0, 0, 0, 0.2f);
|
||||
vImg.raycastTarget = false;
|
||||
var mask = viewport.GetComponent<Mask>();
|
||||
mask.showMaskGraphic = false;
|
||||
|
||||
var content = new GameObject("Content", typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
content.transform.SetParent(viewport.transform, false);
|
||||
var contentRT = (RectTransform)content.transform;
|
||||
contentRT.anchorMin = new Vector2(0, 1);
|
||||
contentRT.anchorMax = new Vector2(1, 1);
|
||||
contentRT.pivot = new Vector2(0.5f, 1f);
|
||||
var vlg = content.GetComponent<VerticalLayoutGroup>();
|
||||
vlg.spacing = 4;
|
||||
vlg.childForceExpandWidth = true;
|
||||
vlg.childControlHeight = true;
|
||||
|
||||
var item = new GameObject("Item", typeof(RectTransform), typeof(Toggle));
|
||||
item.transform.SetParent(content.transform, false);
|
||||
var itemRT = (RectTransform)item.transform;
|
||||
itemRT.sizeDelta = new Vector2(0, 30);
|
||||
var itemBG = new GameObject("Item Background", typeof(RectTransform), typeof(Image));
|
||||
itemBG.transform.SetParent(item.transform, false);
|
||||
var itemBGImg = itemBG.GetComponent<Image>();
|
||||
itemBGImg.color = new Color(0.2f, 0.2f, 0.2f, 0.9f);
|
||||
var itemCheck = new GameObject("Item Checkmark", typeof(RectTransform), typeof(Image));
|
||||
itemCheck.transform.SetParent(itemBG.transform, false);
|
||||
var itemCheckImg = itemCheck.GetComponent<Image>();
|
||||
itemCheckImg.color = new Color(0.7f, 1f, 0.7f, 1f);
|
||||
var itemLabelGO = CreateText(item.transform, "Item Label", "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
|
||||
var bgRT = (RectTransform)itemBG.transform;
|
||||
bgRT.anchorMin = new Vector2(0, 0);
|
||||
bgRT.anchorMax = new Vector2(1, 1);
|
||||
bgRT.offsetMin = Vector2.zero;
|
||||
bgRT.offsetMax = Vector2.zero;
|
||||
var ckRT = (RectTransform)itemCheck.transform;
|
||||
ckRT.anchorMin = new Vector2(0, 0.5f);
|
||||
ckRT.anchorMax = new Vector2(0, 0.5f);
|
||||
ckRT.pivot = new Vector2(0, 0.5f);
|
||||
ckRT.sizeDelta = new Vector2(18, 18);
|
||||
ckRT.anchoredPosition = new Vector2(6, 0);
|
||||
var itemLabelRT = (RectTransform)itemLabelGO.transform;
|
||||
itemLabelRT.anchorMin = new Vector2(0, 0);
|
||||
itemLabelRT.anchorMax = new Vector2(1, 1);
|
||||
itemLabelRT.offsetMin = new Vector2(28, 0);
|
||||
itemLabelRT.offsetMax = new Vector2(-6, 0);
|
||||
|
||||
var toggle = item.GetComponent<Toggle>();
|
||||
toggle.targetGraphic = itemBGImg;
|
||||
toggle.graphic = itemCheckImg;
|
||||
|
||||
var dropdown = go.GetComponent<TMP_Dropdown>();
|
||||
dropdown.template = templateRT;
|
||||
dropdown.captionText = caption.GetComponent<TextMeshProUGUI>();
|
||||
dropdown.itemText = itemLabelGO.GetComponent<TextMeshProUGUI>();
|
||||
dropdown.options = options.Select(o => new TMP_Dropdown.OptionData(o)).ToList();
|
||||
dropdown.alphaFadeSpeed = 0.15f;
|
||||
dropdown.RefreshShownValue();
|
||||
|
||||
var scrollRect = template.GetComponent<ScrollRect>();
|
||||
scrollRect.viewport = viewportRT;
|
||||
scrollRect.content = (RectTransform)content.transform;
|
||||
scrollRect.horizontal = false;
|
||||
scrollRect.vertical = true;
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateSlider(Transform parent, string name, float min, float max, float value)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Slider));
|
||||
go.transform.SetParent(parent, false);
|
||||
var slider = go.GetComponent<Slider>();
|
||||
slider.minValue = min;
|
||||
slider.maxValue = max;
|
||||
slider.value = value;
|
||||
slider.direction = Slider.Direction.LeftToRight;
|
||||
slider.wholeNumbers = true;
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(600, 30);
|
||||
|
||||
var background = new GameObject("Background", typeof(RectTransform), typeof(Image));
|
||||
background.transform.SetParent(go.transform, false);
|
||||
var bgRT = (RectTransform)background.transform;
|
||||
bgRT.anchorMin = new Vector2(0, 0.25f);
|
||||
bgRT.anchorMax = new Vector2(1, 0.75f);
|
||||
bgRT.offsetMin = Vector2.zero;
|
||||
bgRT.offsetMax = Vector2.zero;
|
||||
var bgImg = background.GetComponent<Image>();
|
||||
bgImg.color = new Color(0.1f, 0.1f, 0.1f, 1f);
|
||||
|
||||
var fillArea = new GameObject("Fill Area", typeof(RectTransform));
|
||||
fillArea.transform.SetParent(go.transform, false);
|
||||
var faRT = (RectTransform)fillArea.transform;
|
||||
faRT.anchorMin = new Vector2(0, 0.25f);
|
||||
faRT.anchorMax = new Vector2(1, 0.75f);
|
||||
faRT.offsetMin = new Vector2(10, 0);
|
||||
faRT.offsetMax = new Vector2(-10, 0);
|
||||
|
||||
var fill = new GameObject("Fill", typeof(RectTransform), typeof(Image));
|
||||
fill.transform.SetParent(fillArea.transform, false);
|
||||
var fillImg = fill.GetComponent<Image>();
|
||||
fillImg.color = new Color(0.4f, 0.9f, 0.4f, 1f);
|
||||
var fillRT = (RectTransform)fill.transform;
|
||||
fillRT.anchorMin = new Vector2(0, 0);
|
||||
fillRT.anchorMax = new Vector2(1, 1);
|
||||
fillRT.offsetMin = Vector2.zero;
|
||||
fillRT.offsetMax = Vector2.zero;
|
||||
|
||||
var handleArea = new GameObject("Handle Slide Area", typeof(RectTransform));
|
||||
handleArea.transform.SetParent(go.transform, false);
|
||||
var haRT = (RectTransform)handleArea.transform;
|
||||
haRT.anchorMin = new Vector2(0, 0);
|
||||
haRT.anchorMax = new Vector2(1, 1);
|
||||
haRT.offsetMin = Vector2.zero;
|
||||
haRT.offsetMax = Vector2.zero;
|
||||
|
||||
var handle = new GameObject("Handle", typeof(RectTransform), typeof(Image));
|
||||
handle.transform.SetParent(handleArea.transform, false);
|
||||
var handleImg = handle.GetComponent<Image>();
|
||||
handleImg.color = new Color(0.8f, 1f, 0.8f, 1f);
|
||||
var hRT = (RectTransform)handle.transform;
|
||||
hRT.sizeDelta = new Vector2(16, 24);
|
||||
hRT.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
hRT.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
hRT.anchoredPosition = Vector2.zero;
|
||||
|
||||
slider.fillRect = fill.GetComponent<RectTransform>();
|
||||
slider.handleRect = handle.GetComponent<RectTransform>();
|
||||
slider.targetGraphic = handleImg;
|
||||
slider.direction = Slider.Direction.LeftToRight;
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateLabeledSlider(Transform parent, string label, string name, float min, float max, float value)
|
||||
{
|
||||
var group = CreateVerticalGroup(parent, name + "_Group", 4, TextAnchor.UpperLeft, new RectOffset(0, 0, 0, 0));
|
||||
CreateText(group.transform, name + "_Label", label, 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
CreateSlider(group.transform, name, min, max, value);
|
||||
return group;
|
||||
}
|
||||
|
||||
internal static GameObject CreateToggle(Transform parent, string name, string labelText, bool initial)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Toggle));
|
||||
go.transform.SetParent(parent, false);
|
||||
var bg = CreateImage(go.transform, "Background", new Color(0.2f, 0.2f, 0.2f));
|
||||
var check = CreateImage(bg.transform, "Checkmark", new Color(0.7f, 1f, 0.7f));
|
||||
var label = CreateText(go.transform, "Label", labelText, 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var toggle = go.GetComponent<Toggle>();
|
||||
toggle.isOn = initial;
|
||||
toggle.graphic = check.GetComponent<Image>();
|
||||
toggle.targetGraphic = bg.GetComponent<Image>();
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.sizeDelta = new Vector2(600, 40);
|
||||
var bgRT = (RectTransform)bg.transform;
|
||||
bgRT.anchorMin = new Vector2(0, 0.5f);
|
||||
bgRT.anchorMax = new Vector2(0, 0.5f);
|
||||
bgRT.pivot = new Vector2(0, 0.5f);
|
||||
bgRT.sizeDelta = new Vector2(24, 24);
|
||||
var checkRT = (RectTransform)check.transform;
|
||||
checkRT.anchorMin = checkRT.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
checkRT.sizeDelta = new Vector2(16, 16);
|
||||
var labelRT = (RectTransform)label.transform;
|
||||
labelRT.anchorMin = new Vector2(0, 0);
|
||||
labelRT.anchorMax = new Vector2(1, 1);
|
||||
labelRT.offsetMin = new Vector2(34, 0);
|
||||
labelRT.offsetMax = new Vector2(0, 0);
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static GameObject CreateImage(Transform parent, string name, Color color)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = color;
|
||||
return go;
|
||||
}
|
||||
|
||||
internal static void CreateSpacer(Transform parent, float height)
|
||||
{
|
||||
var spacer = new GameObject("Spacer", typeof(RectTransform));
|
||||
spacer.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)spacer.transform;
|
||||
rt.sizeDelta = new Vector2(0, height);
|
||||
}
|
||||
|
||||
internal static ScrollRect CreateScrollList(Transform parent, out Transform content, string scrollName, string viewportName, string contentName)
|
||||
{
|
||||
var scrollGO = new GameObject(scrollName, typeof(RectTransform), typeof(Image), typeof(ScrollRect));
|
||||
scrollGO.transform.SetParent(parent, false);
|
||||
var srt = (RectTransform)scrollGO.transform;
|
||||
srt.sizeDelta = new Vector2(0, 240);
|
||||
var img = scrollGO.GetComponent<Image>();
|
||||
img.color = new Color(0, 0, 0, 0.3f);
|
||||
var viewport = new GameObject(viewportName, typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
viewport.transform.SetParent(scrollGO.transform, false);
|
||||
var vImg = viewport.GetComponent<Image>();
|
||||
vImg.color = new Color(0, 0, 0, 0.1f);
|
||||
viewport.GetComponent<Mask>().showMaskGraphic = false;
|
||||
var vprt = (RectTransform)viewport.transform;
|
||||
vprt.anchorMin = new Vector2(0, 0);
|
||||
vprt.anchorMax = new Vector2(1, 1);
|
||||
vprt.offsetMin = Vector2.zero;
|
||||
vprt.offsetMax = Vector2.zero;
|
||||
var contentGO = new GameObject(contentName, typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
contentGO.transform.SetParent(viewport.transform, false);
|
||||
var vlg = contentGO.GetComponent<VerticalLayoutGroup>();
|
||||
vlg.spacing = 8;
|
||||
vlg.childAlignment = TextAnchor.UpperLeft;
|
||||
vlg.childForceExpandWidth = true;
|
||||
var crt = (RectTransform)contentGO.transform;
|
||||
crt.anchorMin = new Vector2(0, 1);
|
||||
crt.anchorMax = new Vector2(1, 1);
|
||||
crt.pivot = new Vector2(0.5f, 1);
|
||||
crt.offsetMin = Vector2.zero;
|
||||
crt.offsetMax = Vector2.zero;
|
||||
var csf = contentGO.AddComponent<ContentSizeFitter>();
|
||||
csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
content = contentGO.transform;
|
||||
var scroll = scrollGO.GetComponent<ScrollRect>();
|
||||
scroll.viewport = (RectTransform)viewport.transform;
|
||||
scroll.content = (RectTransform)content;
|
||||
scroll.horizontal = false;
|
||||
scroll.vertical = true;
|
||||
return scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Editor/UGUIBuilderUtils.cs.meta
Normal file
2
Editor/UGUIBuilderUtils.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2af2a4c51891b754d82ab14274d8146d
|
||||
@@ -2,8 +2,6 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using System.Linq;
|
||||
|
||||
namespace MegaKoop.EditorTools
|
||||
{
|
||||
@@ -23,17 +21,92 @@ namespace MegaKoop.EditorTools
|
||||
canvas = canvasGO.GetComponent<Canvas>();
|
||||
if (canvas == null) canvas = canvasGO.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
canvas.sortingOrder = 100;
|
||||
var scaler = canvasGO.GetComponent<CanvasScaler>();
|
||||
if (scaler == null) scaler = canvasGO.AddComponent<CanvasScaler>();
|
||||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1920, 1080);
|
||||
scaler.matchWidthOrHeight = 0.5f;
|
||||
var raycaster = canvasGO.GetComponent<GraphicRaycaster>();
|
||||
if (raycaster == null) raycaster = canvasGO.AddComponent<GraphicRaycaster>();
|
||||
|
||||
// Ensure EventSystem exists
|
||||
if (Object.FindObjectOfType<UnityEngine.EventSystems.EventSystem>() == null)
|
||||
// Ensure/upgrade EventSystem based on available modules
|
||||
var existingES = Object.FindObjectOfType<UnityEngine.EventSystems.EventSystem>();
|
||||
var inputSystemModuleType = System.Type.GetType("UnityEngine.InputSystem.UI.InputSystemUIInputModule, Unity.InputSystem", false);
|
||||
bool wantIS = inputSystemModuleType != null;
|
||||
bool wantLegacy = !wantIS;
|
||||
|
||||
GameObject esGO = null;
|
||||
if (existingES == null)
|
||||
{
|
||||
var es = new GameObject("EventSystem", typeof(UnityEngine.EventSystems.EventSystem), typeof(UnityEngine.EventSystems.StandaloneInputModule));
|
||||
var es = new GameObject("EventSystem", typeof(UnityEngine.EventSystems.EventSystem));
|
||||
if (wantIS) es.AddComponent(inputSystemModuleType);
|
||||
if (wantLegacy) es.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
|
||||
Undo.RegisterCreatedObjectUndo(es, "Create EventSystem");
|
||||
esGO = es;
|
||||
}
|
||||
else
|
||||
{
|
||||
esGO = existingES.gameObject;
|
||||
var sim = existingES.GetComponent<UnityEngine.EventSystems.StandaloneInputModule>();
|
||||
var ism = inputSystemModuleType != null ? existingES.GetComponent(inputSystemModuleType) : null;
|
||||
if (wantIS && ism == null) Undo.AddComponent(existingES.gameObject, inputSystemModuleType);
|
||||
if (wantLegacy && sim == null) Undo.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>(existingES.gameObject);
|
||||
}
|
||||
|
||||
// Assign actionsAsset only if the picked InputActionAsset contains a "UI" action map
|
||||
bool assignedUIActions = false;
|
||||
if (wantIS && inputSystemModuleType != null && esGO != null)
|
||||
{
|
||||
var module = esGO.GetComponent(inputSystemModuleType);
|
||||
if (module != null)
|
||||
{
|
||||
var prop = inputSystemModuleType.GetProperty("actionsAsset");
|
||||
if (prop != null)
|
||||
{
|
||||
var current = prop.GetValue(module, null) as UnityEngine.Object;
|
||||
if (current == null)
|
||||
{
|
||||
var iaaType = System.Type.GetType("UnityEngine.InputSystem.InputActionAsset, Unity.InputSystem", false);
|
||||
string ChooseUIAsset()
|
||||
{
|
||||
var guids = AssetDatabase.FindAssets("t:InputActionAsset");
|
||||
foreach (var g in guids)
|
||||
{
|
||||
var path = AssetDatabase.GUIDToAssetPath(g);
|
||||
var asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
|
||||
if (asset != null && iaaType != null && iaaType.IsInstanceOfType(asset))
|
||||
{
|
||||
var map = iaaType.GetMethod("FindActionMap", new[] { typeof(string), typeof(bool) })?.Invoke(asset, new object[] { "UI", true });
|
||||
if (map != null) return path;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var best = ChooseUIAsset();
|
||||
if (!string.IsNullOrEmpty(best))
|
||||
{
|
||||
var asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(best);
|
||||
prop.SetValue(module, asset, null);
|
||||
var comp = module as Component; if (comp != null) EditorUtility.SetDirty(comp);
|
||||
assignedUIActions = true;
|
||||
}
|
||||
// else: leave null to let module use its default actions
|
||||
}
|
||||
else { assignedUIActions = true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (esGO != null)
|
||||
{
|
||||
var hasSIM = esGO.GetComponent<UnityEngine.EventSystems.StandaloneInputModule>() != null;
|
||||
var hasIS = inputSystemModuleType != null && esGO.GetComponent(inputSystemModuleType) != null;
|
||||
if (hasIS && !assignedUIActions && !hasSIM)
|
||||
{
|
||||
Undo.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>(esGO);
|
||||
}
|
||||
Debug.Log($"[UGUIMenuBuilder] EventSystem configured. InputSystem={(hasIS ? "ON" : "OFF")} (actions={(assignedUIActions ? "OK" : "none")}), Standalone={(hasSIM ? "ON" : "OFF")}");
|
||||
}
|
||||
|
||||
// Clean old generated panels if present to avoid duplicates
|
||||
@@ -49,134 +122,9 @@ namespace MegaKoop.EditorTools
|
||||
DestroyChildIfExists(canvas.transform, "Panel_Settings");
|
||||
DestroyChildIfExists(canvas.transform, "Panel_Lobby");
|
||||
|
||||
// Root panels
|
||||
var panelMain = CreatePanel(canvas.transform, "Panel_MainMenu", new Vector2(900, 800));
|
||||
var panelSettings = CreatePanel(canvas.transform, "Panel_Settings", new Vector2(900, 800));
|
||||
var panelLobby = CreatePanel(canvas.transform, "Panel_Lobby", new Vector2(1100, 820));
|
||||
panelSettings.SetActive(false);
|
||||
panelLobby.SetActive(false);
|
||||
|
||||
// Main Menu Content
|
||||
var mainContainer = CreateVerticalGroup(panelMain.transform, "Main_VLayout", 20, TextAnchor.MiddleCenter, new RectOffset(30, 30, 30, 30));
|
||||
CreateText(mainContainer.transform, "Text_Title", "MEGA KOOP", 70, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
CreateText(mainContainer.transform, "Text_Subtitle", "CO-OP ADVENTURE", 20, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Normal);
|
||||
CreateSpacer(mainContainer.transform, 20);
|
||||
|
||||
CreateMenuButton(mainContainer.transform, "Button_Multiplayer", "MULTIPLAYER");
|
||||
CreateMenuButton(mainContainer.transform, "Button_Settings", "SETTINGS");
|
||||
CreateMenuButton(mainContainer.transform, "Button_Quit", "QUIT GAME", isDanger:true);
|
||||
|
||||
// Settings
|
||||
var settingsContainer = CreateVerticalGroup(panelSettings.transform, "Settings_VLayout", 16, TextAnchor.UpperCenter, new RectOffset(30,30,30,30));
|
||||
CreateText(settingsContainer.transform, "Text_SettingsTitle", "SETTINGS", 48, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
CreateSpacer(settingsContainer.transform, 10);
|
||||
|
||||
var gfxGroup = CreateVerticalGroup(settingsContainer.transform, "Graphics_Group", 10, TextAnchor.UpperLeft, new RectOffset(10,10,10,10));
|
||||
CreateText(gfxGroup.transform, "Text_Graphics", "Graphics", 24, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
CreateDropdown(gfxGroup.transform, "Dropdown_Quality", new string[]{"Low","Medium","High","Ultra"});
|
||||
CreateToggle(gfxGroup.transform, "Toggle_Fullscreen", "Fullscreen", true);
|
||||
CreateDropdown(gfxGroup.transform, "Dropdown_Resolution", new string[]{"1280x720","1920x1080","2560x1440","3840x2160"});
|
||||
|
||||
var settingsButtons = CreateHorizontalGroup(settingsContainer.transform, "Settings_Buttons", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateMenuButton(settingsButtons.transform, "Button_ApplySettings", "APPLY");
|
||||
CreateMenuButton(settingsButtons.transform, "Button_BackFromSettings", "BACK");
|
||||
|
||||
// Lobby
|
||||
var lobbyContainer = CreateVerticalGroup(panelLobby.transform, "Lobby_VLayout", 16, TextAnchor.UpperCenter, new RectOffset(24,24,24,24));
|
||||
var lobbyHeader = CreateHorizontalGroup(lobbyContainer.transform, "Lobby_Header", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,10));
|
||||
CreateText(lobbyHeader.transform, "Text_LobbyTitle", "MULTIPLAYER LOBBY", 36, TextAnchor.MiddleLeft, new Color(0.7f,1f,0.7f), FontStyles.Bold);
|
||||
CreateText(lobbyHeader.transform, "Text_Status", "OFFLINE", 18, TextAnchor.MiddleRight, new Color(0.8f,0.8f,0.8f), FontStyles.Bold);
|
||||
|
||||
// Lobby code area
|
||||
var codeGroup = CreateVerticalGroup(lobbyContainer.transform, "Lobby_CodeGroup", 8, TextAnchor.MiddleCenter, new RectOffset(10,10,10,10));
|
||||
CreateText(codeGroup.transform, "Text_LobbyCodeLabel", "LOBBY CODE", 16, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Bold);
|
||||
var codeRow = CreateHorizontalGroup(codeGroup.transform, "Lobby_CodeRow", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateText(codeRow.transform, "Text_LobbyCodeValue", "------", 44, TextAnchor.MiddleCenter, new Color(0.7f,1f,0.7f), FontStyles.Bold);
|
||||
CreateMenuButton(codeRow.transform, "Button_CopyCode", "COPY");
|
||||
CreateText(codeGroup.transform, "Text_LobbyCodeHint", "Share this code with friends to invite them", 12, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Normal);
|
||||
|
||||
// Tabs
|
||||
var tabs = CreateHorizontalGroup(lobbyContainer.transform, "Lobby_Tabs", 0, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateMenuButton(tabs.transform, "Button_HostTab", "HOST LOBBY");
|
||||
CreateMenuButton(tabs.transform, "Button_JoinTab", "JOIN LOBBY");
|
||||
|
||||
// Join content
|
||||
var joinGroup = CreateVerticalGroup(lobbyContainer.transform, "Group_Join", 10, TextAnchor.UpperCenter, new RectOffset(10,10,10,10));
|
||||
var joinRow = CreateHorizontalGroup(joinGroup.transform, "Join_Row", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateInputField(joinRow.transform, "Input_LobbyCode", "Enter 6-digit code...");
|
||||
CreateMenuButton(joinGroup.transform, "Button_Connect", "CONNECT");
|
||||
|
||||
// Host content
|
||||
var hostGroup = CreateVerticalGroup(lobbyContainer.transform, "Group_Host", 10, TextAnchor.UpperCenter, new RectOffset(10,10,10,10));
|
||||
CreateDropdown(hostGroup.transform, "Dropdown_MaxPlayers", new string[]{"2","3","4","8"});
|
||||
CreateToggle(hostGroup.transform, "Toggle_PublicLobby", "Public", true);
|
||||
CreateMenuButton(hostGroup.transform, "Button_CreateLobby", "CREATE LOBBY");
|
||||
|
||||
// Players list
|
||||
var playersHeader = CreateHorizontalGroup(lobbyContainer.transform, "Players_Header", 10, TextAnchor.MiddleLeft, new RectOffset(0,0,0,0));
|
||||
CreateText(playersHeader.transform, "Text_PlayersTitle", "PLAYERS", 20, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
CreateText(playersHeader.transform, "Text_PlayerCount", "0/4", 18, TextAnchor.MiddleRight, new Color(0.7f,1f,0.7f), FontStyles.Bold);
|
||||
|
||||
var scroll = CreateScrollList(lobbyContainer.transform, out var content, "Scroll_Players", "Viewport", "Content_PlayersList");
|
||||
var empty = CreateText(lobbyContainer.transform, "Empty_Players", "Waiting for players...", 16, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Italic);
|
||||
|
||||
// Template for player entry
|
||||
var template = new GameObject("PlayerItemTemplate", typeof(RectTransform), typeof(HorizontalLayoutGroup));
|
||||
template.transform.SetParent(content, false);
|
||||
var hlg = template.GetComponent<HorizontalLayoutGroup>();
|
||||
hlg.childAlignment = TextAnchor.MiddleLeft; hlg.spacing = 12; hlg.childControlWidth = false; hlg.childForceExpandWidth = true;
|
||||
var avatar = CreateImage(template.transform, "Image_Avatar", new Color(0.3f,0.6f,0.3f));
|
||||
var name = CreateText(template.transform, "Text_PlayerName", "Player", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Bold);
|
||||
var status = CreateText(template.transform, "Text_PlayerStatus", "NOT READY", 14, TextAnchor.MiddleRight, new Color(0.8f,0.8f,0.8f), FontStyles.Bold);
|
||||
((RectTransform)avatar.transform).sizeDelta = new Vector2(40,40);
|
||||
template.SetActive(false);
|
||||
|
||||
// Host controls
|
||||
var hostControls = CreateHorizontalGroup(lobbyContainer.transform, "Host_Controls", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateMenuButton(hostControls.transform, "Button_InviteFriends", "INVITE FRIENDS");
|
||||
CreateMenuButton(hostControls.transform, "Button_KickSelected", "KICK SELECTED");
|
||||
|
||||
// Friends picker will be a modal overlay under Panel_Lobby (so it doesn't stretch main layout)
|
||||
var friendsOverlay = new GameObject("Panel_Friends", typeof(RectTransform), typeof(Image));
|
||||
friendsOverlay.transform.SetParent(panelLobby.transform, false);
|
||||
var ovRT = (RectTransform)friendsOverlay.transform; ovRT.anchorMin = new Vector2(0,0); ovRT.anchorMax = new Vector2(1,1); ovRT.offsetMin = Vector2.zero; ovRT.offsetMax = Vector2.zero;
|
||||
var ovImg = friendsOverlay.GetComponent<Image>(); ovImg.color = new Color(0,0,0,0.55f);
|
||||
friendsOverlay.SetActive(false);
|
||||
|
||||
// Transparent background button to close on backdrop click
|
||||
var closeBg = new GameObject("Button_CloseFriendsOverlay", typeof(RectTransform), typeof(Image), typeof(Button));
|
||||
closeBg.transform.SetParent(friendsOverlay.transform, false);
|
||||
var closeBgRT = (RectTransform)closeBg.transform; closeBgRT.anchorMin = new Vector2(0,0); closeBgRT.anchorMax = new Vector2(1,1); closeBgRT.offsetMin = Vector2.zero; closeBgRT.offsetMax = Vector2.zero;
|
||||
var closeBgImg = closeBg.GetComponent<Image>(); closeBgImg.color = new Color(0,0,0,0);
|
||||
|
||||
// Center modal window
|
||||
var friendsWindow = CreatePanel(friendsOverlay.transform, "Friends_Window", new Vector2(900, 420));
|
||||
var friendsV = CreateVerticalGroup(friendsWindow.transform, "Friends_VLayout", 8, TextAnchor.UpperCenter, new RectOffset(16,16,16,16));
|
||||
CreateText(friendsV.transform, "Text_FriendsTitle", "INVITE FRIENDS", 24, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
CreateText(friendsV.transform, "Text_FriendsHint", "Select a friend to send a Steam invite.", 12, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Normal);
|
||||
var friendsScroll = CreateScrollList(friendsV.transform, out var friendsContent, "Scroll_Friends", "Viewport", "Content_FriendsList");
|
||||
// Make friends content a compact grid of icons
|
||||
var vlgFriends = friendsContent.GetComponent<VerticalLayoutGroup>();
|
||||
if (vlgFriends) Object.DestroyImmediate(vlgFriends);
|
||||
var gridFriends = friendsContent.gameObject.AddComponent<GridLayoutGroup>();
|
||||
gridFriends.cellSize = new Vector2(72, 72);
|
||||
gridFriends.spacing = new Vector2(10, 10);
|
||||
gridFriends.startAxis = GridLayoutGroup.Axis.Horizontal;
|
||||
var csfFriends = friendsContent.GetComponent<ContentSizeFitter>();
|
||||
if (csfFriends == null) csfFriends = friendsContent.gameObject.AddComponent<ContentSizeFitter>();
|
||||
csfFriends.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
CreateText(friendsV.transform, "Empty_Friends", "No friends found.", 14, TextAnchor.MiddleCenter, new Color(0.8f,0.8f,0.8f), FontStyles.Italic);
|
||||
var friendsFooter = CreateHorizontalGroup(friendsV.transform, "Friends_Footer", 8, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateMenuButton(friendsFooter.transform, "Button_BackFromFriends", "BACK");
|
||||
|
||||
// Ready
|
||||
CreateMenuButton(lobbyContainer.transform, "Button_ToggleReady", "TOGGLE READY");
|
||||
|
||||
// Footer
|
||||
var footer = CreateHorizontalGroup(lobbyContainer.transform, "Lobby_Footer", 10, TextAnchor.MiddleCenter, new RectOffset(0,0,0,0));
|
||||
CreateMenuButton(footer.transform, "Button_StartGame", "START GAME");
|
||||
CreateMenuButton(footer.transform, "Button_LeaveLobby", "LEAVE LOBBY");
|
||||
CreateMenuButton(footer.transform, "Button_BackFromLobby", "BACK TO MENU");
|
||||
var mainPanel = new MainMenuPanelBuilder(canvas.transform).Build();
|
||||
var settingsPanel = new SettingsPanelBuilder(canvas.transform).Build();
|
||||
var lobbyPanel = new LobbyPanelBuilder(canvas.transform).Build();
|
||||
|
||||
// Controllers
|
||||
var mainCtrl = canvas.gameObject.GetComponent<MegaKoop.UI.UGUIMainMenuController>();
|
||||
@@ -185,238 +133,13 @@ namespace MegaKoop.EditorTools
|
||||
if (lobbyCtrl == null) lobbyCtrl = canvas.gameObject.AddComponent<MegaKoop.UI.UGUIMultiplayerLobbyController>();
|
||||
|
||||
// Inject panel references for reliability
|
||||
mainCtrl.SetPanels(panelMain, panelSettings, panelLobby);
|
||||
lobbyCtrl.SetLobbyRoot(panelLobby);
|
||||
mainCtrl.SetPanels(mainPanel, settingsPanel, lobbyPanel);
|
||||
lobbyCtrl.SetLobbyRoot(lobbyPanel);
|
||||
|
||||
Selection.activeGameObject = canvas.gameObject;
|
||||
|
||||
Debug.Log("[UGUIMenuBuilder] UGUI Main Menu generated successfully. You can press Play and test.");
|
||||
}
|
||||
|
||||
private static GameObject CreatePanel(Transform parent, string name, Vector2 size)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = rt.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rt.pivot = new Vector2(0.5f, 0.5f);
|
||||
rt.sizeDelta = size;
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = new Color(0.13f, 0.13f, 0.13f, 0.95f);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateVerticalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 1); rt.offsetMin = new Vector2(0,0); rt.offsetMax = new Vector2(0,0);
|
||||
var vlg = go.GetComponent<VerticalLayoutGroup>();
|
||||
vlg.spacing = spacing; vlg.childAlignment = align; vlg.padding = padding; vlg.childForceExpandWidth = true; vlg.childControlWidth = true; vlg.childControlHeight = false;
|
||||
var fitter = go.GetComponent<ContentSizeFitter>();
|
||||
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateHorizontalGroup(Transform parent, string name, float spacing, TextAnchor align, RectOffset padding)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(HorizontalLayoutGroup));
|
||||
go.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)go.transform;
|
||||
rt.anchorMin = new Vector2(0, 0); rt.anchorMax = new Vector2(1, 0); rt.pivot = new Vector2(0.5f, 0.5f);
|
||||
rt.sizeDelta = new Vector2(0, 60);
|
||||
var hlg = go.GetComponent<HorizontalLayoutGroup>();
|
||||
hlg.spacing = spacing; hlg.childAlignment = align; hlg.padding = padding; hlg.childControlWidth = true; hlg.childForceExpandWidth = true;
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateText(Transform parent, string name, string text, int fontSize, TextAnchor anchor, Color color, FontStyles fontStyle)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement));
|
||||
go.transform.SetParent(parent, false);
|
||||
var t = go.GetComponent<TextMeshProUGUI>();
|
||||
t.text = text; t.fontSize = fontSize; t.color = color; t.alignment = MapAlignment(anchor); t.fontStyle = fontStyle;
|
||||
t.enableWordWrapping = false; // avoid vertical letters
|
||||
t.raycastTarget = false; // don't block parent UI clicks
|
||||
if (TMP_Settings.defaultFontAsset != null) t.font = TMP_Settings.defaultFontAsset;
|
||||
var le = go.GetComponent<LayoutElement>();
|
||||
le.minHeight = Mathf.Max(24, fontSize + 12);
|
||||
var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(0, fontSize + 20);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static TextAlignmentOptions MapAlignment(TextAnchor anchor)
|
||||
{
|
||||
switch (anchor)
|
||||
{
|
||||
case TextAnchor.UpperLeft: return TextAlignmentOptions.TopLeft;
|
||||
case TextAnchor.UpperCenter: return TextAlignmentOptions.Top;
|
||||
case TextAnchor.UpperRight: return TextAlignmentOptions.TopRight;
|
||||
case TextAnchor.MiddleLeft: return TextAlignmentOptions.MidlineLeft;
|
||||
case TextAnchor.MiddleCenter: return TextAlignmentOptions.Midline;
|
||||
case TextAnchor.MiddleRight: return TextAlignmentOptions.MidlineRight;
|
||||
case TextAnchor.LowerLeft: return TextAlignmentOptions.BottomLeft;
|
||||
case TextAnchor.LowerCenter: return TextAlignmentOptions.Bottom;
|
||||
case TextAnchor.LowerRight: return TextAlignmentOptions.BottomRight;
|
||||
default: return TextAlignmentOptions.Center;
|
||||
}
|
||||
}
|
||||
|
||||
private static GameObject CreateMenuButton(Transform parent, string name, string label, bool isDanger = false)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>();
|
||||
img.color = isDanger ? new Color(0.5f, 0.15f, 0.15f, 0.9f) : new Color(0.25f, 0.5f, 0.25f, 0.9f);
|
||||
var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(0, 48);
|
||||
var leBtn = go.AddComponent<LayoutElement>();
|
||||
leBtn.flexibleWidth = 1; leBtn.minHeight = 48;
|
||||
var text = CreateText(go.transform, "Text", label, 20, TextAnchor.MiddleCenter, Color.white, FontStyles.Bold);
|
||||
var textRT = (RectTransform)text.transform; textRT.anchorMin = new Vector2(0,0); textRT.anchorMax = new Vector2(1,1); textRT.offsetMin = Vector2.zero; textRT.offsetMax = Vector2.zero;
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateInputField(Transform parent, string name, string placeholder)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_InputField));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>(); img.color = new Color(0.1f,0.1f,0.1f,0.9f);
|
||||
var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 50);
|
||||
var viewport = new GameObject("TextViewport", typeof(RectTransform)); viewport.transform.SetParent(go.transform, false);
|
||||
var viewportRT = (RectTransform)viewport.transform; viewportRT.anchorMin = new Vector2(0,0); viewportRT.anchorMax = new Vector2(1,1); viewportRT.offsetMin = new Vector2(10,6); viewportRT.offsetMax = new Vector2(-10,-6);
|
||||
var text = CreateText(viewport.transform, "Text", string.Empty, 20, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var placeholderGO = CreateText(viewport.transform, "Placeholder", placeholder, 18, TextAnchor.MiddleLeft, new Color(0.7f,0.7f,0.7f), FontStyles.Italic);
|
||||
var input = go.GetComponent<TMP_InputField>();
|
||||
input.textViewport = viewportRT;
|
||||
input.textComponent = text.GetComponent<TextMeshProUGUI>();
|
||||
input.placeholder = placeholderGO.GetComponent<TextMeshProUGUI>();
|
||||
var tRT = (RectTransform)text.transform; tRT.anchorMin = new Vector2(0,0); tRT.anchorMax = new Vector2(1,1); tRT.offsetMin = new Vector2(10,0); tRT.offsetMax = new Vector2(-10,0);
|
||||
var pRT = (RectTransform)placeholderGO.transform; pRT.anchorMin = new Vector2(0,0); pRT.anchorMax = new Vector2(1,1); pRT.offsetMin = new Vector2(10,0); pRT.offsetMax = new Vector2(-10,0);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateDropdown(Transform parent, string name, string[] options)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(TMP_Dropdown));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>(); img.color = new Color(0.2f,0.2f,0.2f,0.9f);
|
||||
var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 50);
|
||||
|
||||
// Caption label
|
||||
var caption = CreateText(go.transform, "Label", options.FirstOrDefault() ?? "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var arrow = CreateText(go.transform, "Arrow", "▼", 18, TextAnchor.MiddleRight, Color.white, FontStyles.Bold);
|
||||
|
||||
// Template (disabled by default)
|
||||
var template = new GameObject("Template", typeof(RectTransform), typeof(Image), typeof(ScrollRect));
|
||||
template.transform.SetParent(go.transform, false);
|
||||
var templateRT = (RectTransform)template.transform;
|
||||
templateRT.anchorMin = new Vector2(0, 0); templateRT.anchorMax = new Vector2(1, 0); templateRT.pivot = new Vector2(0.5f, 1);
|
||||
templateRT.sizeDelta = new Vector2(0, 220); // visible dropdown height
|
||||
template.SetActive(false);
|
||||
var templateImg = template.GetComponent<Image>(); templateImg.color = new Color(0.1f,0.1f,0.1f,0.95f);
|
||||
|
||||
// Viewport
|
||||
var viewport = new GameObject("Viewport", typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
viewport.transform.SetParent(template.transform, false);
|
||||
var viewportRT = (RectTransform)viewport.transform; viewportRT.anchorMin = new Vector2(0,0); viewportRT.anchorMax = new Vector2(1,1); viewportRT.offsetMin = Vector2.zero; viewportRT.offsetMax = Vector2.zero;
|
||||
var vImg = viewport.GetComponent<Image>(); vImg.color = new Color(0,0,0,0.2f);
|
||||
viewport.GetComponent<Mask>().showMaskGraphic = false;
|
||||
|
||||
// Scroll content
|
||||
var content = new GameObject("Content", typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
content.transform.SetParent(viewport.transform, false);
|
||||
var contentRT = (RectTransform)content.transform; contentRT.anchorMin = new Vector2(0,1); contentRT.anchorMax = new Vector2(1,1); contentRT.pivot = new Vector2(0.5f,1);
|
||||
var vlg = content.GetComponent<VerticalLayoutGroup>(); vlg.spacing = 4; vlg.childForceExpandWidth = true; vlg.childControlHeight = true;
|
||||
|
||||
// Item (Toggle)
|
||||
var item = new GameObject("Item", typeof(RectTransform), typeof(Toggle));
|
||||
item.transform.SetParent(content.transform, false);
|
||||
var itemRT = (RectTransform)item.transform; itemRT.sizeDelta = new Vector2(0, 30);
|
||||
var itemBG = new GameObject("Item Background", typeof(RectTransform), typeof(Image));
|
||||
itemBG.transform.SetParent(item.transform, false);
|
||||
var itemBGImg = itemBG.GetComponent<Image>(); itemBGImg.color = new Color(0.2f,0.2f,0.2f,0.9f);
|
||||
var itemCheck = new GameObject("Item Checkmark", typeof(RectTransform), typeof(Image));
|
||||
itemCheck.transform.SetParent(itemBG.transform, false);
|
||||
var itemCheckImg = itemCheck.GetComponent<Image>(); itemCheckImg.color = new Color(0.7f,1f,0.7f,1f);
|
||||
var itemLabelGO = CreateText(item.transform, "Item Label", "Option", 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
|
||||
// Position sub-elements
|
||||
var bgRT = (RectTransform)itemBG.transform; bgRT.anchorMin = new Vector2(0,0); bgRT.anchorMax = new Vector2(1,1); bgRT.offsetMin = Vector2.zero; bgRT.offsetMax = Vector2.zero;
|
||||
var ckRT = (RectTransform)itemCheck.transform; ckRT.anchorMin = new Vector2(0,0.5f); ckRT.anchorMax = new Vector2(0,0.5f); ckRT.pivot = new Vector2(0,0.5f); ckRT.sizeDelta = new Vector2(18,18); ckRT.anchoredPosition = new Vector2(6,0);
|
||||
var itemLabelRT = (RectTransform)itemLabelGO.transform; itemLabelRT.anchorMin = new Vector2(0,0); itemLabelRT.anchorMax = new Vector2(1,1); itemLabelRT.offsetMin = new Vector2(28,0); itemLabelRT.offsetMax = new Vector2(-6,0);
|
||||
|
||||
// Toggle wiring
|
||||
var tgl = item.GetComponent<Toggle>();
|
||||
tgl.targetGraphic = itemBGImg; tgl.graphic = itemCheckImg;
|
||||
|
||||
// Dropdown wiring
|
||||
var dd = go.GetComponent<TMP_Dropdown>();
|
||||
dd.template = template.GetComponent<RectTransform>();
|
||||
dd.captionText = caption.GetComponent<TextMeshProUGUI>();
|
||||
dd.itemText = itemLabelGO.GetComponent<TextMeshProUGUI>();
|
||||
dd.options = options.Select(o => new TMP_Dropdown.OptionData(o)).ToList();
|
||||
dd.RefreshShownValue();
|
||||
|
||||
// ScrollRect wiring
|
||||
var scr = template.GetComponent<ScrollRect>();
|
||||
scr.viewport = viewport.GetComponent<RectTransform>();
|
||||
scr.content = content.GetComponent<RectTransform>();
|
||||
scr.horizontal = false; scr.vertical = true;
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateToggle(Transform parent, string name, string labelText, bool initial)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Toggle));
|
||||
go.transform.SetParent(parent, false);
|
||||
var bg = CreateImage(go.transform, "Background", new Color(0.2f,0.2f,0.2f));
|
||||
var check = CreateImage(bg.transform, "Checkmark", new Color(0.7f,1f,0.7f));
|
||||
var label = CreateText(go.transform, "Label", labelText, 18, TextAnchor.MiddleLeft, Color.white, FontStyles.Normal);
|
||||
var t = go.GetComponent<Toggle>();
|
||||
t.isOn = initial; t.graphic = check.GetComponent<Image>(); t.targetGraphic = bg.GetComponent<Image>();
|
||||
var rt = (RectTransform)go.transform; rt.sizeDelta = new Vector2(600, 40);
|
||||
var bgRT = (RectTransform)bg.transform; bgRT.anchorMin = new Vector2(0,0.5f); bgRT.anchorMax = new Vector2(0,0.5f); bgRT.pivot = new Vector2(0,0.5f); bgRT.sizeDelta = new Vector2(24,24);
|
||||
var checkRT = (RectTransform)check.transform; checkRT.anchorMin = checkRT.anchorMax = new Vector2(0.5f,0.5f); checkRT.sizeDelta = new Vector2(16,16);
|
||||
var labelRT = (RectTransform)label.transform; labelRT.anchorMin = new Vector2(0,0); labelRT.anchorMax = new Vector2(1,1); labelRT.offsetMin = new Vector2(34,0); labelRT.offsetMax = new Vector2(0,0);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject CreateImage(Transform parent, string name, Color color)
|
||||
{
|
||||
var go = new GameObject(name, typeof(RectTransform), typeof(Image));
|
||||
go.transform.SetParent(parent, false);
|
||||
var img = go.GetComponent<Image>(); img.color = color;
|
||||
return go;
|
||||
}
|
||||
|
||||
private static void CreateSpacer(Transform parent, float height)
|
||||
{
|
||||
var sp = new GameObject("Spacer", typeof(RectTransform));
|
||||
sp.transform.SetParent(parent, false);
|
||||
var rt = (RectTransform)sp.transform; rt.sizeDelta = new Vector2(0, height);
|
||||
}
|
||||
|
||||
private static ScrollRect CreateScrollList(Transform parent, out Transform content, string scrollName, string viewportName, string contentName)
|
||||
{
|
||||
var scrollGO = new GameObject(scrollName, typeof(RectTransform), typeof(Image), typeof(ScrollRect));
|
||||
scrollGO.transform.SetParent(parent, false);
|
||||
var srt = (RectTransform)scrollGO.transform; srt.sizeDelta = new Vector2(0, 240);
|
||||
var img = scrollGO.GetComponent<Image>(); img.color = new Color(0,0,0,0.3f);
|
||||
var viewport = new GameObject(viewportName, typeof(RectTransform), typeof(Mask), typeof(Image));
|
||||
viewport.transform.SetParent(scrollGO.transform, false);
|
||||
var vImg = viewport.GetComponent<Image>(); vImg.color = new Color(0,0,0,0.1f);
|
||||
viewport.GetComponent<Mask>().showMaskGraphic = false;
|
||||
var vprt = (RectTransform)viewport.transform; vprt.anchorMin = new Vector2(0,0); vprt.anchorMax = new Vector2(1,1); vprt.offsetMin = Vector2.zero; vprt.offsetMax = Vector2.zero;
|
||||
var contentGO = new GameObject(contentName, typeof(RectTransform), typeof(VerticalLayoutGroup));
|
||||
contentGO.transform.SetParent(viewport.transform, false);
|
||||
var vlg = contentGO.GetComponent<VerticalLayoutGroup>(); vlg.spacing = 8; vlg.childAlignment = TextAnchor.UpperLeft; vlg.childForceExpandWidth = true;
|
||||
var crt = (RectTransform)contentGO.transform; crt.anchorMin = new Vector2(0,1); crt.anchorMax = new Vector2(1,1); crt.pivot = new Vector2(0.5f,1); crt.offsetMin = new Vector2(0,0); crt.offsetMax = new Vector2(0,0);
|
||||
var csf = contentGO.AddComponent<ContentSizeFitter>(); csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
||||
content = contentGO.transform;
|
||||
var scroll = scrollGO.GetComponent<ScrollRect>(); scroll.viewport = (RectTransform)viewport.transform; scroll.content = (RectTransform)content; scroll.horizontal = false; scroll.vertical = true;
|
||||
return scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,8 @@ MonoBehaviour:
|
||||
m_Name: BossSchedule
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Game.Scripts.Runtime.Data.BossSchedule
|
||||
events:
|
||||
- TimeSinceStart: 1000
|
||||
Boss: {fileID: 11400000, guid: 1bc4888fa172eb99f94756653be6c1ed, type: 2}
|
||||
- TimeSinceStart: 30
|
||||
Boss: {fileID: 11400000, guid: 931549bcc3a079d30b302ebd17d6ebd4, type: 2}
|
||||
Count: 1
|
||||
useSpawnRadiusOverride: 0
|
||||
spawnRadiusOverride: 0
|
||||
|
||||
@@ -205,6 +205,8 @@ namespace MegaKoop.Game.EditorExtensions
|
||||
|
||||
var move = root.AddState("Move", new Vector3(250, 150, 0));
|
||||
move.motion = CreateMoveBlendTree(controller);
|
||||
move.speedParameterActive = true;
|
||||
move.speedParameter = "MoveSpeedNormalized";
|
||||
|
||||
AnimatorState crouch = null;
|
||||
if (crouchIdle != null)
|
||||
@@ -262,11 +264,27 @@ namespace MegaKoop.Game.EditorExtensions
|
||||
}
|
||||
|
||||
// Jump transitions: AnyState -> Jump Begin
|
||||
var anyToJumpBegin = root.AddAnyStateTransition(jumpBeginState);
|
||||
anyToJumpBegin.hasExitTime = false;
|
||||
anyToJumpBegin.duration = 0.05f;
|
||||
anyToJumpBegin.canTransitionToSelf = false;
|
||||
anyToJumpBegin.AddCondition(AnimatorConditionMode.If, 0f, "Jump");
|
||||
// Jump transitions from grounded states
|
||||
var idleToJump = idle.AddTransition(jumpBeginState);
|
||||
idleToJump.hasExitTime = false;
|
||||
idleToJump.duration = 0.05f;
|
||||
idleToJump.AddCondition(AnimatorConditionMode.If, 0f, "IsJumping");
|
||||
idleToJump.AddCondition(AnimatorConditionMode.IfNot, 0f, "IsGrounded");
|
||||
|
||||
var moveToJump = move.AddTransition(jumpBeginState);
|
||||
moveToJump.hasExitTime = false;
|
||||
moveToJump.duration = 0.05f;
|
||||
moveToJump.AddCondition(AnimatorConditionMode.If, 0f, "IsJumping");
|
||||
moveToJump.AddCondition(AnimatorConditionMode.IfNot, 0f, "IsGrounded");
|
||||
|
||||
if (crouch != null)
|
||||
{
|
||||
var crouchToJump = crouch.AddTransition(jumpBeginState);
|
||||
crouchToJump.hasExitTime = false;
|
||||
crouchToJump.duration = 0.05f;
|
||||
crouchToJump.AddCondition(AnimatorConditionMode.If, 0f, "IsJumping");
|
||||
crouchToJump.AddCondition(AnimatorConditionMode.IfNot, 0f, "IsGrounded");
|
||||
}
|
||||
|
||||
// Jump Begin -> Jump Fall (automatic after animation)
|
||||
var jumpBeginToFall = jumpBeginState.AddTransition(jumpFallState);
|
||||
@@ -330,10 +348,11 @@ namespace MegaKoop.Game.EditorExtensions
|
||||
controller.AddParameter("MoveX", AnimatorControllerParameterType.Float);
|
||||
controller.AddParameter("MoveZ", AnimatorControllerParameterType.Float);
|
||||
controller.AddParameter("Speed", AnimatorControllerParameterType.Float);
|
||||
controller.AddParameter("MoveSpeedNormalized", AnimatorControllerParameterType.Float);
|
||||
controller.AddParameter("IsGrounded", AnimatorControllerParameterType.Bool);
|
||||
controller.AddParameter("IsCrouching", AnimatorControllerParameterType.Bool);
|
||||
controller.AddParameter("IsDead", AnimatorControllerParameterType.Bool);
|
||||
controller.AddParameter("Jump", AnimatorControllerParameterType.Trigger);
|
||||
controller.AddParameter("IsJumping", AnimatorControllerParameterType.Bool);
|
||||
}
|
||||
|
||||
private Motion CreateMoveBlendTree(AnimatorController controller)
|
||||
|
||||
8
Game/Enemy/Butcher.meta
Normal file
8
Game/Enemy/Butcher.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48c9e67a0c0c948489f927fd1c27b2fa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3522
Game/Enemy/Butcher/Butcher.prefab
Normal file
3522
Game/Enemy/Butcher/Butcher.prefab
Normal file
File diff suppressed because it is too large
Load Diff
9
Game/Enemy/Butcher/Butcher.prefab.meta
Normal file
9
Game/Enemy/Butcher/Butcher.prefab.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d086cbb30c7bb4ba3a58cb2024fa0b31
|
||||
timeCreated: 1526423972
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
22
Game/Enemy/Butcher/ButcherDefinition.asset
Normal file
22
Game/Enemy/Butcher/ButcherDefinition.asset
Normal file
@@ -0,0 +1,22 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 6b0e84710d3119d60af5d5373005e029, type: 3}
|
||||
m_Name: ButcherDefinition
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Game.Scripts.Runtime.Data.EnemyDefinition
|
||||
id: enemy_golem
|
||||
Prefab: {fileID: 1170732337855516, guid: d086cbb30c7bb4ba3a58cb2024fa0b31, type: 3}
|
||||
IsBoss: 1
|
||||
BaseHP: 300
|
||||
MoveSpeed: 6
|
||||
Damage: 10
|
||||
PrefabPivotOffset: {x: 0, y: 0, z: 0}
|
||||
Tags: []
|
||||
8
Game/Enemy/Butcher/ButcherDefinition.asset.meta
Normal file
8
Game/Enemy/Butcher/ButcherDefinition.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 931549bcc3a079d30b302ebd17d6ebd4
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Game/Hero/Champion_00.asset
Normal file
29
Game/Hero/Champion_00.asset
Normal file
@@ -0,0 +1,29 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1db1d1943f6165546b7a8aa42068f69b, type: 3}
|
||||
m_Name: Champion_00
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Champions.ChampionData
|
||||
championName: Champion 1
|
||||
championId: 0
|
||||
description: Popis pro Champion 1
|
||||
portrait: {fileID: 0}
|
||||
championPrefab: {fileID: 7059514996416789454, guid: fe75fe22781f92b369675fdfc9657f7d, type: 3}
|
||||
primaryGunName: Primary Weapon
|
||||
primaryGunDescription: Primary gun description
|
||||
secondaryGunName: Secondary Weapon
|
||||
secondaryGunDescription: Secondary gun description
|
||||
passiveName: Passive Ability
|
||||
passiveDescription: Passive ability description
|
||||
primaryGunIcon: {fileID: 0}
|
||||
secondaryGunIcon: {fileID: 0}
|
||||
passiveIcon: {fileID: 0}
|
||||
themeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
8
Game/Hero/Champion_00.asset.meta
Normal file
8
Game/Hero/Champion_00.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e91e178970c9ce94fa1aae63627dd287
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Game/Hero/Champion_01.asset
Normal file
29
Game/Hero/Champion_01.asset
Normal file
@@ -0,0 +1,29 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1db1d1943f6165546b7a8aa42068f69b, type: 3}
|
||||
m_Name: Champion_01
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Champions.ChampionData
|
||||
championName: Champion 2
|
||||
championId: 1
|
||||
description: Popis pro Champion 2
|
||||
portrait: {fileID: 0}
|
||||
championPrefab: {fileID: 2809934685114486836, guid: ae082cf2d3a36684fb23d8ec0e643150, type: 3}
|
||||
primaryGunName: Primary Weapon
|
||||
primaryGunDescription: Primary gun description
|
||||
secondaryGunName: Secondary Weapon
|
||||
secondaryGunDescription: Secondary gun description
|
||||
passiveName: Passive Ability
|
||||
passiveDescription: Passive ability description
|
||||
primaryGunIcon: {fileID: 0}
|
||||
secondaryGunIcon: {fileID: 0}
|
||||
passiveIcon: {fileID: 0}
|
||||
themeColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
8
Game/Hero/Champion_01.asset.meta
Normal file
8
Game/Hero/Champion_01.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3063583c11830974380a240794f2a205
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -15,10 +15,10 @@ MonoBehaviour:
|
||||
displayName: Weapon
|
||||
viewPrefab: {fileID: 6595277065068154610, guid: 7eba33411273ad195adc8a8253711e93, type: 3}
|
||||
projectilePrefab: {fileID: -6920969466594260193, guid: 6703b124cb13a577c8aae6a4851d0274, type: 3}
|
||||
projectileSpeed: 18
|
||||
projectileSpeed: 15
|
||||
projectileLifetime: 5
|
||||
shotsPerSecond: 2
|
||||
baseDamage: 50
|
||||
shotsPerSecond: 1
|
||||
baseDamage: 5
|
||||
range: 25
|
||||
projectilesPerShot: 2
|
||||
spreadAngle: 0
|
||||
|
||||
@@ -643,6 +643,7 @@ GameObject:
|
||||
- component: {fileID: 7469640283978802878}
|
||||
- component: {fileID: 1813583201016405249}
|
||||
- component: {fileID: 3442404066554451922}
|
||||
- component: {fileID: -2591875487324942466}
|
||||
m_Layer: 0
|
||||
m_Name: Wizard 2.0
|
||||
m_TagString: Untagged
|
||||
@@ -733,7 +734,14 @@ MonoBehaviour:
|
||||
jumpHeight: 1.6
|
||||
gravity: -20
|
||||
groundedGravity: -5
|
||||
jumpBufferTime: 0.1
|
||||
coyoteTime: 0.1
|
||||
upwardGravityMultiplier: 1
|
||||
fallGravityMultiplier: 2.5
|
||||
cameraTransform: {fileID: 6707832248248563092}
|
||||
animator: {fileID: 9099213046038254594}
|
||||
animationDamping: 0.075
|
||||
crouchKey: 306
|
||||
--- !u!114 &710593002191720509
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -903,6 +911,7 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Game.Networking.SteamCharacterNetworkBridge
|
||||
characterController: {fileID: 3919077998180469670}
|
||||
animator: {fileID: 9099213046038254594}
|
||||
identity: {fileID: 3262185422700989869}
|
||||
rootTransform: {fileID: 3042213512511893744}
|
||||
networkInputProxy: {fileID: 3442404066554451922}
|
||||
@@ -939,7 +948,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Game.Networking.SteamLocalInputSender
|
||||
characterNetwork: {fileID: 8235037133905039757}
|
||||
sendInterval: 0.05
|
||||
cameraTransform: {fileID: 0}
|
||||
cameraTransform: {fileID: 6707832248248563092}
|
||||
--- !u!114 &3442404066554451922
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -952,6 +961,23 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: e3118c9c432a7acbd824645749251552, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Game.Networking.NetworkCharacterInputProxy
|
||||
--- !u!114 &-2591875487324942466
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2809934685114486836}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 79fb1fbc20d80f546ba695c751860930, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Game.UI.SteamNameTag
|
||||
followHead: {fileID: 852694279969892930}
|
||||
worldOffset: {x: 0, y: 2.5, z: 0}
|
||||
billboardToCamera: 1
|
||||
hideForLocal: 1
|
||||
visibleDistance: 60
|
||||
--- !u!1 &2999616957953547817
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -1859,6 +1859,7 @@ GameObject:
|
||||
- component: {fileID: 7618815643042096284}
|
||||
- component: {fileID: 2662658783078050447}
|
||||
- component: {fileID: 2417536914360261273}
|
||||
- component: {fileID: 2931281317230154068}
|
||||
m_Layer: 0
|
||||
m_Name: Wizard
|
||||
m_TagString: Untagged
|
||||
@@ -1947,8 +1948,12 @@ MonoBehaviour:
|
||||
rotationSharpness: 15
|
||||
airControlResponsiveness: 60
|
||||
jumpHeight: 1.6
|
||||
gravity: -1
|
||||
gravity: -10
|
||||
groundedGravity: -0.01
|
||||
jumpBufferTime: 0.1
|
||||
coyoteTime: 0.1
|
||||
upwardGravityMultiplier: 1
|
||||
fallGravityMultiplier: 10
|
||||
cameraTransform: {fileID: 266386425542752718}
|
||||
animator: {fileID: 3962868364137827229}
|
||||
animationDamping: 0.075
|
||||
@@ -2095,6 +2100,23 @@ MonoBehaviour:
|
||||
SwitchTransformSpaceWhenParented: 0
|
||||
Interpolate: 1
|
||||
SlerpPosition: 0
|
||||
--- !u!114 &2931281317230154068
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7059514996416789454}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 79fb1fbc20d80f546ba695c751860930, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Game.UI.SteamNameTag
|
||||
followHead: {fileID: 7928616218613849049}
|
||||
worldOffset: {x: 0, y: 1.2, z: 0}
|
||||
billboardToCamera: 1
|
||||
hideForLocal: 1
|
||||
visibleDistance: 60
|
||||
--- !u!1 &7094911519708027617
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
8
Game/Scripts/Champion.meta
Normal file
8
Game/Scripts/Champion.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9f986f0da88643469a3c8d6d1223351
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Game/Scripts/Champions.meta
Normal file
8
Game/Scripts/Champions.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d7b510344abb3846bb4a3bdab6135d5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Game/Scripts/Data.meta
Normal file
8
Game/Scripts/Data.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dae8c62813124b4b992a6e90303c912
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -22,9 +22,6 @@ namespace MegaKoop.Game.Enemy
|
||||
public class SteamEnemyController : MonoBehaviour
|
||||
{
|
||||
private static readonly List<Health> SharedHealthBuffer = new(32);
|
||||
private static int nextEnemyNetworkId = StartingEnemyNetworkId;
|
||||
|
||||
private const int StartingEnemyNetworkId = 10000;
|
||||
|
||||
[Header("Movement")]
|
||||
[SerializeField] private float moveSpeed = 3.5f;
|
||||
@@ -69,7 +66,6 @@ namespace MegaKoop.Game.Enemy
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
EnsureIdentity();
|
||||
spawnPosition = transform.position;
|
||||
baseMoveSpeed = moveSpeed;
|
||||
|
||||
@@ -119,7 +115,7 @@ namespace MegaKoop.Game.Enemy
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void ResetNetworkIdCounter()
|
||||
{
|
||||
nextEnemyNetworkId = StartingEnemyNetworkId;
|
||||
NetworkIdAllocator.Reset();
|
||||
}
|
||||
|
||||
private void EnsureIdentity()
|
||||
@@ -134,14 +130,23 @@ namespace MegaKoop.Game.Enemy
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.NetworkId == 0)
|
||||
if (identity.NetworkId != 0)
|
||||
{
|
||||
identity.SetNetworkId(nextEnemyNetworkId++);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShouldAssignLocalNetworkId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int allocatedId = NetworkIdAllocator.AllocateEnemyId();
|
||||
identity.SetNetworkId(allocatedId);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
EnsureIdentity();
|
||||
networkManager = SteamCoopNetworkManager.Instance;
|
||||
pooledInstance ??= GetComponent<PooledInstance>();
|
||||
pendingDespawn = false;
|
||||
@@ -232,6 +237,22 @@ namespace MegaKoop.Game.Enemy
|
||||
return networkManager.IsHost;
|
||||
}
|
||||
|
||||
private bool ShouldAssignLocalNetworkId()
|
||||
{
|
||||
var manager = SteamCoopNetworkManager.Instance;
|
||||
if (manager == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!manager.IsConnected)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return manager.IsHost;
|
||||
}
|
||||
|
||||
private void SyncNavMeshAgentState(bool simulate)
|
||||
{
|
||||
if (navMeshAgent == null)
|
||||
|
||||
@@ -182,6 +182,7 @@ namespace MegaKoop.Game.Networking
|
||||
var clone = Instantiate(template, spawnPosition, baseRotation, parent);
|
||||
clone.name = BuildPlayerName(info, i);
|
||||
|
||||
AdjustSpawnToGround(clone);
|
||||
ConfigureCloneForPlayer(clone, info, i);
|
||||
|
||||
ulong ownerSteamId = ParseSteamId(info.SteamId);
|
||||
@@ -252,11 +253,30 @@ namespace MegaKoop.Game.Networking
|
||||
return center + offset;
|
||||
}
|
||||
|
||||
private void AdjustSpawnToGround(GameObject clone)
|
||||
{
|
||||
if (clone == null) return;
|
||||
var t = clone.transform;
|
||||
var cc = clone.GetComponent<CharacterController>();
|
||||
Vector3 pos = t.position;
|
||||
float up = 2.5f;
|
||||
float down = 10f;
|
||||
float radius = cc != null ? cc.radius : 0.25f;
|
||||
Vector3 origin = pos + Vector3.up * up;
|
||||
if (Physics.SphereCast(origin, Mathf.Max(0.05f, radius * 0.9f), Vector3.down, out RaycastHit hit, up + down, ~0, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
float centerY = cc != null ? cc.center.y : 0f;
|
||||
float height = cc != null ? cc.height : 2f;
|
||||
float targetY = hit.point.y + (height * 0.5f) - centerY + 0.02f;
|
||||
t.position = new Vector3(pos.x, targetY, pos.z);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureCloneForPlayer(GameObject clone, LobbyPlayerInfo info, int index)
|
||||
{
|
||||
// Ensure network identity is deterministic across clients.
|
||||
var identity = clone.GetComponent<NetworkIdentity>() ?? clone.AddComponent<NetworkIdentity>();
|
||||
identity.SetNetworkId(index + 1);
|
||||
identity.SetNetworkId(NetworkIdAllocator.PlayerIdStart + index);
|
||||
|
||||
var bridge = clone.GetComponent<SteamCharacterNetworkBridge>() ?? clone.AddComponent<SteamCharacterNetworkBridge>();
|
||||
bridge.AssignOwner(ParseSteamId(info.SteamId), info.IsLocal);
|
||||
|
||||
80
Game/Scripts/Networking/NetworkIdAllocator.cs
Normal file
80
Game/Scripts/Networking/NetworkIdAllocator.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MegaKoop.Game.Networking
|
||||
{
|
||||
internal static class NetworkIdAllocator
|
||||
{
|
||||
public const int PlayerIdStart = 1;
|
||||
public const int EnemyIdStart = 10000;
|
||||
private const int EnemyIdRange = 10000;
|
||||
|
||||
private static int nextEnemyId = EnemyIdStart;
|
||||
private static readonly System.Collections.Generic.HashSet<int> ActiveEnemyIds = new();
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void ResetOnLoad()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
nextEnemyId = EnemyIdStart;
|
||||
ActiveEnemyIds.Clear();
|
||||
}
|
||||
|
||||
public static int AllocateEnemyId()
|
||||
{
|
||||
if (nextEnemyId < EnemyIdStart)
|
||||
{
|
||||
nextEnemyId = EnemyIdStart;
|
||||
}
|
||||
|
||||
const int maxAttempts = EnemyIdRange;
|
||||
int attempts = 0;
|
||||
while ((ActiveEnemyIds.Contains(nextEnemyId) || NetworkIdRegistry.IsIdRegistered(nextEnemyId) || NetworkIdRegistry.IsIdReserved(nextEnemyId)) && attempts < maxAttempts)
|
||||
{
|
||||
AdvanceEnemyCursor();
|
||||
attempts++;
|
||||
}
|
||||
|
||||
int allocated = nextEnemyId;
|
||||
AdvanceEnemyCursor();
|
||||
ActiveEnemyIds.Add(allocated);
|
||||
return allocated;
|
||||
}
|
||||
|
||||
public static bool IsPlayerId(int id) => id >= PlayerIdStart && id < EnemyIdStart;
|
||||
|
||||
public static bool IsEnemyId(int id) => id >= EnemyIdStart;
|
||||
|
||||
public static void SyncEnemyCursor(int id)
|
||||
{
|
||||
if (id >= EnemyIdStart && id >= nextEnemyId)
|
||||
{
|
||||
nextEnemyId = id + 1;
|
||||
}
|
||||
if (id >= EnemyIdStart)
|
||||
{
|
||||
ActiveEnemyIds.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseEnemyId(int id)
|
||||
{
|
||||
if (id >= EnemyIdStart)
|
||||
{
|
||||
ActiveEnemyIds.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AdvanceEnemyCursor()
|
||||
{
|
||||
nextEnemyId++;
|
||||
if (nextEnemyId >= EnemyIdStart + EnemyIdRange)
|
||||
{
|
||||
nextEnemyId = EnemyIdStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Game/Scripts/Networking/NetworkIdAllocator.cs.meta
Normal file
2
Game/Scripts/Networking/NetworkIdAllocator.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bda656b26417ac8de83785cb9d5b853d
|
||||
@@ -242,6 +242,7 @@ namespace MegaKoop.Game.Networking
|
||||
instance.registry.Clear();
|
||||
instance.steamIdToNetworkId.Clear();
|
||||
instance.reservedIds.Clear();
|
||||
NetworkIdAllocator.Reset();
|
||||
|
||||
Debug.Log($"[NetworkIdRegistry] Registry cleared. Removed {registryCount} identities, {mappingCount} Steam ID mappings, and {reservedCount} reserved IDs.");
|
||||
}
|
||||
|
||||
@@ -14,28 +14,37 @@ namespace MegaKoop.Game.Networking
|
||||
{
|
||||
// Note: Auto-increment removed in favor of deterministic ID generation
|
||||
// IDs should be assigned via SetNetworkId() before or during Awake
|
||||
if (assignOnAwake && networkId == 0)
|
||||
if (networkId != 0)
|
||||
{
|
||||
Debug.LogWarning($"[NetworkIdentity] {name} has assignOnAwake=true but no ID assigned. " +
|
||||
"Use DeterministicIdGenerator or manually call SetNetworkId().");
|
||||
Register();
|
||||
}
|
||||
|
||||
Register();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
NetworkIdRegistry.Unregister(networkId);
|
||||
if (networkId != 0)
|
||||
{
|
||||
if (NetworkIdAllocator.IsEnemyId(networkId))
|
||||
{
|
||||
NetworkIdAllocator.ReleaseEnemyId(networkId);
|
||||
}
|
||||
NetworkIdRegistry.Unregister(networkId);
|
||||
networkId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void Register()
|
||||
{
|
||||
if (networkId == 0)
|
||||
{
|
||||
Debug.LogWarning($"[NetworkIdentity] {name} has no network id and won't be tracked.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NetworkIdAllocator.IsEnemyId(networkId))
|
||||
{
|
||||
NetworkIdAllocator.SyncEnemyCursor(networkId);
|
||||
}
|
||||
|
||||
if (!NetworkIdRegistry.TryRegister(this))
|
||||
{
|
||||
Debug.LogError($"[NetworkIdentity] Failed to register {name} with ID {networkId}. " +
|
||||
@@ -72,11 +81,21 @@ namespace MegaKoop.Game.Networking
|
||||
// Unregister old ID if it was registered
|
||||
if (networkId != 0)
|
||||
{
|
||||
if (NetworkIdAllocator.IsEnemyId(networkId))
|
||||
{
|
||||
NetworkIdAllocator.ReleaseEnemyId(networkId);
|
||||
}
|
||||
|
||||
NetworkIdRegistry.Unregister(networkId);
|
||||
}
|
||||
|
||||
networkId = id;
|
||||
|
||||
|
||||
if (NetworkIdAllocator.IsEnemyId(networkId))
|
||||
{
|
||||
NetworkIdAllocator.SyncEnemyCursor(networkId);
|
||||
}
|
||||
|
||||
// Register with new ID
|
||||
if (!NetworkIdRegistry.TryRegister(this))
|
||||
{
|
||||
@@ -89,5 +108,25 @@ namespace MegaKoop.Game.Networking
|
||||
/// Gets the current network ID without triggering registration.
|
||||
/// </summary>
|
||||
public int GetNetworkId() => networkId;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current network ID and unregisters without emitting duplicate warnings.
|
||||
/// </summary>
|
||||
public void ClearNetworkId()
|
||||
{
|
||||
if (networkId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int id = networkId;
|
||||
NetworkIdRegistry.Unregister(id);
|
||||
if (NetworkIdAllocator.IsEnemyId(id))
|
||||
{
|
||||
NetworkIdAllocator.ReleaseEnemyId(id);
|
||||
}
|
||||
|
||||
networkId = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ namespace MegaKoop.Game.Networking
|
||||
ProjectileImpact = 7,
|
||||
GameState = 8,
|
||||
EnemySpawn = 9,
|
||||
EnemyDespawn = 10
|
||||
EnemyDespawn = 10,
|
||||
CharacterAnim = 11
|
||||
}
|
||||
|
||||
public enum ProjectileImpactKind : byte
|
||||
@@ -108,6 +109,71 @@ namespace MegaKoop.Game.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct CharacterAnimMessage
|
||||
{
|
||||
public readonly int NetworkId;
|
||||
public readonly float MoveX;
|
||||
public readonly float MoveZ;
|
||||
public readonly float Speed;
|
||||
public readonly float MoveSpeedNormalized;
|
||||
public readonly bool IsGrounded;
|
||||
public readonly bool IsCrouching;
|
||||
public readonly bool IsDead;
|
||||
public readonly bool IsJumping;
|
||||
|
||||
public CharacterAnimMessage(
|
||||
int networkId,
|
||||
float moveX,
|
||||
float moveZ,
|
||||
float speed,
|
||||
float moveSpeedNormalized,
|
||||
bool isGrounded,
|
||||
bool isCrouching,
|
||||
bool isDead,
|
||||
bool isJumping)
|
||||
{
|
||||
NetworkId = networkId;
|
||||
MoveX = moveX;
|
||||
MoveZ = moveZ;
|
||||
Speed = speed;
|
||||
MoveSpeedNormalized = moveSpeedNormalized;
|
||||
IsGrounded = isGrounded;
|
||||
IsCrouching = isCrouching;
|
||||
IsDead = isDead;
|
||||
IsJumping = isJumping;
|
||||
}
|
||||
|
||||
public static byte[] Serialize(CharacterAnimMessage message)
|
||||
{
|
||||
using var writer = new NetworkWriter();
|
||||
writer.Write(message.NetworkId);
|
||||
writer.Write(message.MoveX);
|
||||
writer.Write(message.MoveZ);
|
||||
writer.Write(message.Speed);
|
||||
writer.Write(message.MoveSpeedNormalized);
|
||||
writer.Write(message.IsGrounded);
|
||||
writer.Write(message.IsCrouching);
|
||||
writer.Write(message.IsDead);
|
||||
writer.Write(message.IsJumping);
|
||||
return writer.ToArray();
|
||||
}
|
||||
|
||||
public static CharacterAnimMessage Deserialize(byte[] buffer)
|
||||
{
|
||||
using var reader = new NetworkReader(buffer);
|
||||
int id = reader.ReadInt();
|
||||
float moveX = reader.ReadFloat();
|
||||
float moveZ = reader.ReadFloat();
|
||||
float speed = reader.ReadFloat();
|
||||
float moveSpeedNormalized = reader.ReadFloat();
|
||||
bool isGrounded = reader.ReadBool();
|
||||
bool isCrouching = reader.ReadBool();
|
||||
bool isDead = reader.ReadBool();
|
||||
bool isJumping = reader.ReadBool();
|
||||
return new CharacterAnimMessage(id, moveX, moveZ, speed, moveSpeedNormalized, isGrounded, isCrouching, isDead, isJumping);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct WeaponFireMessage
|
||||
{
|
||||
public readonly int NetworkId;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Steamworks;
|
||||
using UnityEngine;
|
||||
using MegaKoop.Game.UI;
|
||||
|
||||
namespace MegaKoop.Game.Networking
|
||||
{
|
||||
@@ -8,6 +9,7 @@ namespace MegaKoop.Game.Networking
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private ThirdPersonCharacterController characterController;
|
||||
[SerializeField] private Animator animator;
|
||||
[SerializeField] private NetworkIdentity identity;
|
||||
[SerializeField] private Transform rootTransform;
|
||||
[SerializeField] private NetworkCharacterInputProxy networkInputProxy;
|
||||
@@ -29,12 +31,14 @@ namespace MegaKoop.Game.Networking
|
||||
private Vector3 remoteTargetVelocity;
|
||||
private bool haveRemoteState;
|
||||
private bool localOverrideSet;
|
||||
private int expectedNetworkId;
|
||||
|
||||
public void AssignOwner(ulong steamId, bool localPlayer)
|
||||
{
|
||||
ownerSteamId = steamId;
|
||||
isLocalPlayer = localPlayer;
|
||||
localOverrideSet = true;
|
||||
CaptureExpectedNetworkId();
|
||||
UpdateAuthority();
|
||||
ConfigureController();
|
||||
}
|
||||
@@ -70,13 +74,29 @@ namespace MegaKoop.Game.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (animator == null)
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
if (animator != null)
|
||||
{
|
||||
animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||||
}
|
||||
}
|
||||
|
||||
remoteTargetPosition = rootTransform.position;
|
||||
remoteTargetRotation = rootTransform.rotation;
|
||||
var nameTag = GetComponent<SteamNameTag>();
|
||||
if (nameTag == null)
|
||||
{
|
||||
nameTag = gameObject.AddComponent<SteamNameTag>();
|
||||
}
|
||||
nameTag.SetFollowHead(null, this);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
networkManager = SteamCoopNetworkManager.Instance;
|
||||
CaptureExpectedNetworkId();
|
||||
UpdateAuthority();
|
||||
ConfigureController();
|
||||
}
|
||||
@@ -84,6 +104,9 @@ namespace MegaKoop.Game.Networking
|
||||
private void OnEnable()
|
||||
{
|
||||
networkManager = SteamCoopNetworkManager.Instance;
|
||||
CaptureExpectedNetworkId();
|
||||
UpdateAuthority();
|
||||
ConfigureController();
|
||||
RegisterHandlers();
|
||||
}
|
||||
|
||||
@@ -136,6 +159,7 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
networkManager.RegisterHandler(NetworkMessageType.PlayerInput, HandlePlayerInputMessage);
|
||||
networkManager.RegisterHandler(NetworkMessageType.CharacterTransform, HandleCharacterTransformMessage);
|
||||
networkManager.RegisterHandler(NetworkMessageType.CharacterAnim, HandleCharacterAnimMessage);
|
||||
isRegistered = true;
|
||||
}
|
||||
|
||||
@@ -148,6 +172,7 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
networkManager.UnregisterHandler(NetworkMessageType.PlayerInput, HandlePlayerInputMessage);
|
||||
networkManager.UnregisterHandler(NetworkMessageType.CharacterTransform, HandleCharacterTransformMessage);
|
||||
networkManager.UnregisterHandler(NetworkMessageType.CharacterAnim, HandleCharacterAnimMessage);
|
||||
isRegistered = false;
|
||||
}
|
||||
|
||||
@@ -188,6 +213,8 @@ namespace MegaKoop.Game.Networking
|
||||
if (unityController != null)
|
||||
{
|
||||
unityController.enabled = true;
|
||||
unityController.detectCollisions = true;
|
||||
unityController.enableOverlapRecovery = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -197,7 +224,9 @@ namespace MegaKoop.Game.Networking
|
||||
var unityController = characterController.GetComponent<UnityEngine.CharacterController>();
|
||||
if (unityController != null)
|
||||
{
|
||||
unityController.enabled = false;
|
||||
unityController.enabled = true;
|
||||
unityController.detectCollisions = true;
|
||||
unityController.enableOverlapRecovery = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,12 +238,54 @@ namespace MegaKoop.Game.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.NetworkId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var unityController = GetComponent<CharacterController>();
|
||||
Vector3 velocity = unityController != null ? unityController.velocity : Vector3.zero;
|
||||
SteamCharacterStateCache.ReportLocalState(identity.NetworkId, rootTransform.position, rootTransform.rotation, velocity);
|
||||
var message = new CharacterTransformMessage(identity.NetworkId, rootTransform.position, rootTransform.rotation, velocity);
|
||||
byte[] payload = CharacterTransformMessage.Serialize(message);
|
||||
networkManager.SendToAll(NetworkMessageType.CharacterTransform, payload, EP2PSend.k_EP2PSendUnreliableNoDelay);
|
||||
|
||||
BroadcastAnimatorParameters();
|
||||
}
|
||||
|
||||
private void BroadcastAnimatorParameters()
|
||||
{
|
||||
if (networkManager == null || identity == null || animator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.NetworkId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float moveX = animator.GetFloat("MoveX");
|
||||
float moveZ = animator.GetFloat("MoveZ");
|
||||
float speed = animator.GetFloat("Speed");
|
||||
float moveSpeedNorm = animator.GetFloat("MoveSpeedNormalized");
|
||||
bool isGround = animator.GetBool("IsGrounded");
|
||||
bool isCrouch = animator.GetBool("IsCrouching");
|
||||
bool isDeadFlag = animator.GetBool("IsDead");
|
||||
bool isJump = animator.GetBool("IsJumping");
|
||||
|
||||
var animMsg = new CharacterAnimMessage(
|
||||
identity.NetworkId,
|
||||
moveX,
|
||||
moveZ,
|
||||
speed,
|
||||
moveSpeedNorm,
|
||||
isGround,
|
||||
isCrouch,
|
||||
isDeadFlag,
|
||||
isJump);
|
||||
byte[] animPayload = CharacterAnimMessage.Serialize(animMsg);
|
||||
networkManager.SendToAll(NetworkMessageType.CharacterAnim, animPayload, EP2PSend.k_EP2PSendUnreliableNoDelay);
|
||||
}
|
||||
|
||||
private void HandlePlayerInputMessage(NetworkMessage message)
|
||||
@@ -241,24 +312,9 @@ namespace MegaKoop.Game.Networking
|
||||
}
|
||||
|
||||
CharacterTransformMessage transformMessage = CharacterTransformMessage.Deserialize(message.Payload);
|
||||
if (identity != null && transformMessage.NetworkId != identity.NetworkId)
|
||||
if (!EnsureMatchingNetworkId(transformMessage.NetworkId, message.Sender))
|
||||
{
|
||||
if (ownerSteamId != 0 && message.Sender != ownerSteamId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var existing = NetworkIdRegistry.GetById(transformMessage.NetworkId);
|
||||
if (existing != null && existing != identity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
identity.SetNetworkId(transformMessage.NetworkId);
|
||||
if (identity.NetworkId != transformMessage.NetworkId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
remoteTargetPosition = transformMessage.Position;
|
||||
@@ -267,6 +323,125 @@ namespace MegaKoop.Game.Networking
|
||||
haveRemoteState = true;
|
||||
}
|
||||
|
||||
private void HandleCharacterAnimMessage(NetworkMessage message)
|
||||
{
|
||||
if (isAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterAnimMessage anim = CharacterAnimMessage.Deserialize(message.Payload);
|
||||
if (!EnsureMatchingNetworkId(anim.NetworkId, message.Sender))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (animator == null)
|
||||
{
|
||||
animator = GetComponent<Animator>();
|
||||
if (animator == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
animator.SetFloat("MoveX", anim.MoveX);
|
||||
animator.SetFloat("MoveZ", anim.MoveZ);
|
||||
animator.SetFloat("Speed", anim.Speed);
|
||||
animator.SetFloat("MoveSpeedNormalized", anim.MoveSpeedNormalized);
|
||||
animator.SetBool("IsGrounded", anim.IsGrounded);
|
||||
animator.SetBool("IsCrouching", anim.IsCrouching);
|
||||
animator.SetBool("IsDead", anim.IsDead);
|
||||
animator.SetBool("IsJumping", anim.IsJumping);
|
||||
}
|
||||
|
||||
private void CaptureExpectedNetworkId()
|
||||
{
|
||||
if (identity == null)
|
||||
{
|
||||
identity = GetComponent<NetworkIdentity>();
|
||||
}
|
||||
|
||||
if (identity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.NetworkId != 0)
|
||||
{
|
||||
expectedNetworkId = identity.NetworkId;
|
||||
if (ownerSteamId != 0)
|
||||
{
|
||||
var mapped = NetworkIdRegistry.GetNetworkIdForSteamId(ownerSteamId);
|
||||
if (mapped != expectedNetworkId)
|
||||
{
|
||||
NetworkIdRegistry.MapSteamIdToNetworkId(ownerSteamId, expectedNetworkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool EnsureMatchingNetworkId(int incomingId, ulong sender)
|
||||
{
|
||||
if (identity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (incomingId == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int currentId = identity.NetworkId;
|
||||
if (currentId == incomingId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentId != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ownerSteamId != 0 && sender != ownerSteamId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int mappedId = ownerSteamId != 0 ? NetworkIdRegistry.GetNetworkIdForSteamId(ownerSteamId) : expectedNetworkId;
|
||||
if (mappedId != 0)
|
||||
{
|
||||
identity.SetNetworkId(mappedId);
|
||||
if (identity.NetworkId == mappedId)
|
||||
{
|
||||
expectedNetworkId = mappedId;
|
||||
return mappedId == incomingId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NetworkIdAllocator.IsPlayerId(incomingId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
identity.SetNetworkId(incomingId);
|
||||
if (identity.NetworkId != incomingId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
expectedNetworkId = incomingId;
|
||||
if (ownerSteamId != 0)
|
||||
{
|
||||
NetworkIdRegistry.MapSteamIdToNetworkId(ownerSteamId, incomingId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SendLocalInput(Vector2 moveInput, bool jump)
|
||||
{
|
||||
if (networkManager == null || identity == null || !isAuthority)
|
||||
@@ -279,6 +454,11 @@ namespace MegaKoop.Game.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.NetworkId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
networkManager.SendToAll(NetworkMessageType.PlayerInput, PlayerInputMessage.Serialize(new PlayerInputMessage(identity.NetworkId, moveInput, jump)), EP2PSend.k_EP2PSendUnreliableNoDelay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace MegaKoop.Game.Networking
|
||||
EnemyDefinitionRegistry.Register(definition);
|
||||
}
|
||||
|
||||
if (!DetermineAuthority() || networkManager == null)
|
||||
if (!IsHostClient() || networkManager == null)
|
||||
{
|
||||
if (hasPendingRemoteSpawn)
|
||||
{
|
||||
@@ -241,7 +241,7 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
private void HandleInstanceDespawned(GameObject instance, EnemyDefinition definition)
|
||||
{
|
||||
if (!DetermineAuthority() || networkManager == null)
|
||||
if (!IsHostClient() || networkManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
private void HandleEnemySpawnMessage(NetworkMessage message)
|
||||
{
|
||||
if (DetermineAuthority())
|
||||
if (IsHostClient())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -279,6 +279,19 @@ namespace MegaKoop.Game.Networking
|
||||
hasPendingRemoteSpawn = false;
|
||||
return;
|
||||
}
|
||||
EnemyDefinitionRegistry.Register(definition);
|
||||
|
||||
if (pendingRemoteSpawn.NetworkId != 0 && NetworkIdentity.TryGet(pendingRemoteSpawn.NetworkId, out var existingIdentity) && existingIdentity != null)
|
||||
{
|
||||
var existingInstance = existingIdentity.gameObject;
|
||||
if (existingInstance != null)
|
||||
{
|
||||
existingInstance.SetActive(true);
|
||||
existingInstance.transform.SetPositionAndRotation(pendingRemoteSpawn.Position + definition.PrefabPivotOffset, pendingRemoteSpawn.Rotation);
|
||||
hasPendingRemoteSpawn = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = spawner != null && spawner.TrySpawn(definition, pendingRemoteSpawn.Position);
|
||||
if (success)
|
||||
@@ -302,7 +315,7 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
private void HandleEnemyDespawnMessage(NetworkMessage message)
|
||||
{
|
||||
if (DetermineAuthority())
|
||||
if (IsHostClient())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -351,5 +364,11 @@ namespace MegaKoop.Game.Networking
|
||||
identity.SetNetworkId(pendingRemoteSpawn.NetworkId);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsHostClient()
|
||||
{
|
||||
RefreshNetworkManager();
|
||||
return networkManager != null && networkManager.IsHost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace MegaKoop.Game.Networking
|
||||
private Quaternion remoteTargetRotation;
|
||||
private Vector3 remoteTargetVelocity;
|
||||
private bool haveRemoteState;
|
||||
private SteamCharacterNetworkBridge characterBridge;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -54,6 +55,13 @@ namespace MegaKoop.Game.Networking
|
||||
trackedNavMeshAgent = GetComponent<UnityEngine.AI.NavMeshAgent>();
|
||||
}
|
||||
|
||||
characterBridge = GetComponent<SteamCharacterNetworkBridge>();
|
||||
if (characterBridge != null)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
remoteTargetPosition = targetTransform.position;
|
||||
remoteTargetRotation = targetTransform.rotation;
|
||||
remoteTargetVelocity = Vector3.zero;
|
||||
@@ -62,6 +70,12 @@ namespace MegaKoop.Game.Networking
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
characterBridge = GetComponent<SteamCharacterNetworkBridge>();
|
||||
if (characterBridge != null)
|
||||
{
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
EnsureNetworkManager();
|
||||
RegisterHandlers();
|
||||
}
|
||||
|
||||
@@ -126,6 +126,11 @@ namespace MegaKoop.Game.Networking
|
||||
}
|
||||
|
||||
ProjectileSpawnMessage spawnMessage = ProjectileSpawnMessage.Deserialize(message.Payload);
|
||||
if (identity.NetworkId == 0 && spawnMessage.NetworkId != 0)
|
||||
{
|
||||
identity.SetNetworkId(spawnMessage.NetworkId);
|
||||
}
|
||||
|
||||
if (spawnMessage.NetworkId != identity.NetworkId)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Game.Scripts.Runtime.Abstractions;
|
||||
using Game.Scripts.Runtime.Data;
|
||||
using UnityEngine;
|
||||
using Unity.Netcode;
|
||||
using MegaKoop.Game.Networking;
|
||||
|
||||
namespace Game.Scripts.Runtime.Pooling
|
||||
{
|
||||
@@ -144,6 +145,8 @@ namespace Game.Scripts.Runtime.Pooling
|
||||
{
|
||||
Destroy(netObj);
|
||||
}
|
||||
var identity = instance.GetComponent<NetworkIdentity>();
|
||||
identity?.ClearNetworkId();
|
||||
bucket.Available.Enqueue(instance);
|
||||
item.Handle?.NotifyDespawned();
|
||||
InstanceDespawned?.Invoke(instance, item.Definition);
|
||||
@@ -183,6 +186,9 @@ namespace Game.Scripts.Runtime.Pooling
|
||||
go.name = $"{definition.Prefab.name}_Pooled";
|
||||
go.SetActive(false);
|
||||
|
||||
var identity = go.GetComponent<NetworkIdentity>();
|
||||
identity?.ClearNetworkId();
|
||||
|
||||
var handle = go.GetComponent<PooledInstance>();
|
||||
if (handle == null)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace MegaKoop.Game
|
||||
[SerializeField] private float jumpHeight = 1.6f;
|
||||
[SerializeField] private float gravity = -20f;
|
||||
[SerializeField] private float groundedGravity = -5f;
|
||||
[SerializeField, Range(0f, 0.3f)] private float jumpBufferTime = 0.1f;
|
||||
[SerializeField, Range(0f, 0.3f)] private float coyoteTime = 0.1f;
|
||||
[SerializeField, Min(0.5f)] private float upwardGravityMultiplier = 1f;
|
||||
[SerializeField, Min(1f)] private float fallGravityMultiplier = 2.5f;
|
||||
|
||||
[Header("Camera Reference")]
|
||||
[SerializeField] private Transform cameraTransform;
|
||||
@@ -32,16 +36,20 @@ namespace MegaKoop.Game
|
||||
private bool isGrounded;
|
||||
private bool lastGrounded;
|
||||
private bool isDead;
|
||||
private bool isJumping;
|
||||
private MegaKoop.Game.Networking.ICharacterInputSource inputSource;
|
||||
private float lastJumpPressedTime = float.NegativeInfinity;
|
||||
private float lastTimeGrounded = float.NegativeInfinity;
|
||||
|
||||
// Animator parameter hashes
|
||||
private int hashMoveX;
|
||||
private int hashMoveZ;
|
||||
private int hashSpeed;
|
||||
private int hashMoveSpeedNormalized;
|
||||
private int hashIsGrounded;
|
||||
private int hashIsCrouching;
|
||||
private int hashIsDead;
|
||||
private int hashJump;
|
||||
private int hashIsJumping;
|
||||
private bool animatorHashesInitialized;
|
||||
|
||||
private void Reset()
|
||||
@@ -78,6 +86,7 @@ namespace MegaKoop.Game
|
||||
{
|
||||
EnsureAnimatorReference();
|
||||
InitializeAnimatorHashes();
|
||||
SnapToGroundImmediate();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
@@ -86,6 +95,8 @@ namespace MegaKoop.Game
|
||||
InitializeAnimatorHashes();
|
||||
|
||||
Vector2 moveInput = ReadMovementInput();
|
||||
TrackJumpInput();
|
||||
|
||||
Vector3 desiredMove = CalculateDesiredMove(moveInput);
|
||||
bool hasMoveInput = desiredMove.sqrMagnitude > 0f;
|
||||
|
||||
@@ -110,6 +121,31 @@ namespace MegaKoop.Game
|
||||
UpdateAnimator();
|
||||
}
|
||||
|
||||
private void SnapToGroundImmediate()
|
||||
{
|
||||
if (characterController == null)
|
||||
{
|
||||
characterController = GetComponent<UnityEngine.CharacterController>();
|
||||
}
|
||||
|
||||
Vector3 pos = transform.position;
|
||||
float up = 2.5f;
|
||||
float down = 10f;
|
||||
float radius = characterController != null ? characterController.radius : 0.25f;
|
||||
Vector3 origin = pos + Vector3.up * up;
|
||||
if (Physics.SphereCast(origin, Mathf.Max(0.05f, radius * 0.9f), Vector3.down, out RaycastHit hit, up + down, ~0, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
float centerY = characterController != null ? characterController.center.y : 0f;
|
||||
float height = characterController != null ? characterController.height : 2f;
|
||||
float bottomToCenter = Mathf.Max(radius, height * 0.5f) - radius;
|
||||
float targetY = hit.point.y + bottomToCenter - centerY + 0.02f;
|
||||
transform.position = new Vector3(pos.x, targetY, pos.z);
|
||||
isGrounded = true;
|
||||
verticalVelocity = groundedGravity;
|
||||
lastTimeGrounded = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetInputSource(MegaKoop.Game.Networking.ICharacterInputSource source)
|
||||
{
|
||||
inputSource = source;
|
||||
@@ -192,39 +228,65 @@ namespace MegaKoop.Game
|
||||
|
||||
private void UpdateGroundedStateBeforeGravity()
|
||||
{
|
||||
if (isGrounded && verticalVelocity < 0f)
|
||||
if (isGrounded)
|
||||
{
|
||||
verticalVelocity = groundedGravity;
|
||||
lastTimeGrounded = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleJumpInput()
|
||||
{
|
||||
if (!isGrounded)
|
||||
bool bufferedJump = Time.time - lastJumpPressedTime <= jumpBufferTime;
|
||||
bool coyoteAvailable = Time.time - lastTimeGrounded <= coyoteTime;
|
||||
|
||||
if (!bufferedJump)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShouldJumpThisFrame())
|
||||
if (isGrounded || coyoteAvailable)
|
||||
{
|
||||
verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
||||
isGrounded = false;
|
||||
isJumping = true;
|
||||
lastJumpPressedTime = float.NegativeInfinity;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldJumpThisFrame()
|
||||
private void TrackJumpInput()
|
||||
{
|
||||
bool jumpPressed = false;
|
||||
|
||||
if (inputSource != null)
|
||||
{
|
||||
return inputSource.JumpPressed;
|
||||
jumpPressed = inputSource.JumpPressed;
|
||||
}
|
||||
else if (Input.GetButtonDown("Jump"))
|
||||
{
|
||||
jumpPressed = true;
|
||||
}
|
||||
|
||||
return Input.GetButtonDown("Jump");
|
||||
if (jumpPressed)
|
||||
{
|
||||
lastJumpPressedTime = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyGravity()
|
||||
{
|
||||
verticalVelocity += gravity * Time.deltaTime;
|
||||
float gravityMultiplier = verticalVelocity > 0f ? upwardGravityMultiplier : fallGravityMultiplier;
|
||||
float currentGravity = gravity * gravityMultiplier;
|
||||
|
||||
if (isGrounded && verticalVelocity < 0f)
|
||||
{
|
||||
verticalVelocity = groundedGravity;
|
||||
lastTimeGrounded = Time.time;
|
||||
isJumping = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
verticalVelocity += currentGravity * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAnimator()
|
||||
@@ -241,24 +303,21 @@ namespace MegaKoop.Game
|
||||
float denom = Mathf.Max(0.01f, moveSpeed);
|
||||
float moveX = Mathf.Clamp(localVelocity.x / denom, -1f, 1f);
|
||||
float moveZ = Mathf.Clamp(localVelocity.z / denom, -1f, 1f);
|
||||
float normalizedSpeed = Mathf.Clamp01(speed / moveSpeed);
|
||||
|
||||
// Update animator parameters
|
||||
animator.SetFloat(hashSpeed, speed);
|
||||
animator.SetFloat(hashMoveSpeedNormalized, normalizedSpeed);
|
||||
animator.SetFloat(hashMoveX, moveX, animationDamping, Time.deltaTime);
|
||||
animator.SetFloat(hashMoveZ, moveZ, animationDamping, Time.deltaTime);
|
||||
animator.SetBool(hashIsGrounded, isGrounded);
|
||||
animator.SetBool(hashIsJumping, isJumping);
|
||||
|
||||
// Crouch input (currently only supports local input, can be extended via inputSource)
|
||||
bool isCrouching = !isDead && Input.GetKey(crouchKey);
|
||||
animator.SetBool(hashIsCrouching, isCrouching);
|
||||
|
||||
// Jump trigger - when leaving ground with upward velocity
|
||||
if (lastGrounded && !isGrounded && verticalVelocity > 0.1f)
|
||||
{
|
||||
animator.ResetTrigger(hashJump);
|
||||
animator.SetTrigger(hashJump);
|
||||
}
|
||||
|
||||
animator.SetBool(hashIsDead, isDead);
|
||||
lastGrounded = isGrounded;
|
||||
}
|
||||
@@ -283,6 +342,10 @@ namespace MegaKoop.Game
|
||||
gravity = Mathf.Min(-0.01f, gravity);
|
||||
groundedGravity = Mathf.Clamp(groundedGravity, gravity, 0f);
|
||||
animationDamping = Mathf.Max(0f, animationDamping);
|
||||
jumpBufferTime = Mathf.Clamp(jumpBufferTime, 0f, 0.3f);
|
||||
coyoteTime = Mathf.Clamp(coyoteTime, 0f, 0.3f);
|
||||
upwardGravityMultiplier = Mathf.Max(0.5f, upwardGravityMultiplier);
|
||||
fallGravityMultiplier = Mathf.Max(1f, fallGravityMultiplier);
|
||||
EnsureAnimatorReference();
|
||||
InitializeAnimatorHashes();
|
||||
}
|
||||
@@ -309,7 +372,8 @@ namespace MegaKoop.Game
|
||||
hashIsGrounded = Animator.StringToHash("IsGrounded");
|
||||
hashIsCrouching = Animator.StringToHash("IsCrouching");
|
||||
hashIsDead = Animator.StringToHash("IsDead");
|
||||
hashJump = Animator.StringToHash("Jump");
|
||||
hashIsJumping = Animator.StringToHash("IsJumping");
|
||||
hashMoveSpeedNormalized = Animator.StringToHash("MoveSpeedNormalized");
|
||||
animatorHashesInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
250
Game/Scripts/UI/SteamNameTag.cs
Normal file
250
Game/Scripts/UI/SteamNameTag.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using Steamworks;
|
||||
using MegaKoop.Game.Networking;
|
||||
|
||||
namespace MegaKoop.Game.UI
|
||||
{
|
||||
[DefaultExecutionOrder(10000)]
|
||||
[DisallowMultipleComponent]
|
||||
public class SteamNameTag : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Transform followHead;
|
||||
[SerializeField] private Vector3 worldOffset = new Vector3(0f, 2.5f, 0f);
|
||||
[SerializeField] private bool billboardToCamera = true;
|
||||
[SerializeField] private bool hideForLocal = true;
|
||||
[SerializeField] private float visibleDistance = 60f;
|
||||
|
||||
private TextMeshPro text;
|
||||
private Transform tagTransform;
|
||||
private Transform camTransform;
|
||||
private SteamCharacterNetworkBridge bridge;
|
||||
private Callback<PersonaStateChange_t> personaChanged;
|
||||
private ulong lastSteamId;
|
||||
private float camFindTimer;
|
||||
private Coroutine ensureActiveRoutine;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Reuse existing NameTag child if present (prevents duplicates when cloning templates)
|
||||
var existing = transform.Find("NameTag");
|
||||
GameObject go;
|
||||
if (existing != null)
|
||||
{
|
||||
tagTransform = existing;
|
||||
go = existing.gameObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
go = new GameObject("NameTag");
|
||||
go.layer = gameObject.layer;
|
||||
tagTransform = go.transform;
|
||||
tagTransform.SetParent(transform, worldPositionStays: false);
|
||||
}
|
||||
if (!go.activeSelf) go.SetActive(true);
|
||||
|
||||
text = go.GetComponent<TextMeshPro>();
|
||||
if (text == null)
|
||||
{
|
||||
text = go.AddComponent<TextMeshPro>();
|
||||
}
|
||||
text.alignment = TextAlignmentOptions.Center;
|
||||
text.color = Color.white;
|
||||
text.fontSize = 2.5f;
|
||||
text.enableAutoSizing = true;
|
||||
text.fontSizeMin = 1.5f;
|
||||
text.fontSizeMax = 4.5f;
|
||||
text.text = GetObjectDisplayName();
|
||||
if (!text.gameObject.activeSelf) text.gameObject.SetActive(true);
|
||||
text.enabled = true;
|
||||
|
||||
bridge = GetComponent<SteamCharacterNetworkBridge>();
|
||||
|
||||
if (followHead == null)
|
||||
{
|
||||
followHead = FindChildRecursive(transform, "Head");
|
||||
if (followHead == null)
|
||||
{
|
||||
followHead = transform;
|
||||
worldOffset = new Vector3(0f, 2.5f, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFollowHead(Transform head, SteamCharacterNetworkBridge b)
|
||||
{
|
||||
if (head != null) followHead = head;
|
||||
if (b != null) bridge = b;
|
||||
UpdateDisplayName(true);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
camTransform = Camera.main != null ? Camera.main.transform : null;
|
||||
TryCreatePersonaCallback();
|
||||
if (tagTransform != null && !tagTransform.gameObject.activeSelf)
|
||||
{
|
||||
tagTransform.gameObject.SetActive(true);
|
||||
}
|
||||
if (text != null)
|
||||
{
|
||||
if (!text.gameObject.activeSelf) text.gameObject.SetActive(true);
|
||||
text.enabled = true;
|
||||
}
|
||||
if (ensureActiveRoutine == null)
|
||||
{
|
||||
ensureActiveRoutine = StartCoroutine(EnsureActiveLoop());
|
||||
}
|
||||
UpdateDisplayName(true);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
personaChanged = null;
|
||||
if (ensureActiveRoutine != null)
|
||||
{
|
||||
StopCoroutine(ensureActiveRoutine);
|
||||
ensureActiveRoutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryCreatePersonaCallback()
|
||||
{
|
||||
if (personaChanged == null)
|
||||
{
|
||||
personaChanged = Callback<PersonaStateChange_t>.Create(OnPersonaChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator EnsureActiveLoop()
|
||||
{
|
||||
var waiter = new WaitForEndOfFrame();
|
||||
while (isActiveAndEnabled)
|
||||
{
|
||||
if (tagTransform != null && !tagTransform.gameObject.activeSelf)
|
||||
{
|
||||
tagTransform.gameObject.SetActive(true);
|
||||
}
|
||||
if (text != null)
|
||||
{
|
||||
if (!text.gameObject.activeSelf) text.gameObject.SetActive(true);
|
||||
text.enabled = true;
|
||||
}
|
||||
yield return waiter;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPersonaChanged(PersonaStateChange_t cb)
|
||||
{
|
||||
if (bridge == null) return;
|
||||
if (cb.m_ulSteamID == bridge.OwnerSteamId)
|
||||
{
|
||||
UpdateDisplayName(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
camFindTimer -= Time.unscaledDeltaTime;
|
||||
if ((camTransform == null || !camTransform.gameObject.activeInHierarchy) && camFindTimer <= 0f)
|
||||
{
|
||||
var cam = Camera.main;
|
||||
camTransform = cam != null ? cam.transform : null;
|
||||
camFindTimer = 1f;
|
||||
}
|
||||
|
||||
// Never deactivate the NameTag GameObject; only toggle text rendering
|
||||
if (tagTransform != null && !tagTransform.gameObject.activeSelf)
|
||||
{
|
||||
tagTransform.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
Vector3 basePos = followHead != null ? followHead.position : transform.position;
|
||||
tagTransform.position = basePos + worldOffset;
|
||||
|
||||
if (billboardToCamera && camTransform != null)
|
||||
{
|
||||
Vector3 dir = tagTransform.position - camTransform.position;
|
||||
if (dir.sqrMagnitude > 0.001f)
|
||||
{
|
||||
tagTransform.rotation = Quaternion.LookRotation(dir, Vector3.up);
|
||||
}
|
||||
}
|
||||
|
||||
if (text != null)
|
||||
{
|
||||
if (!text.gameObject.activeSelf) text.gameObject.SetActive(true);
|
||||
text.enabled = true;
|
||||
}
|
||||
|
||||
UpdateDisplayName(false);
|
||||
}
|
||||
|
||||
private void UpdateDisplayName(bool force)
|
||||
{
|
||||
if (text == null) return;
|
||||
ulong sid = 0;
|
||||
if (bridge != null) sid = bridge.OwnerSteamId;
|
||||
if (!force && sid == lastSteamId && !string.IsNullOrEmpty(text.text)) return;
|
||||
|
||||
lastSteamId = sid;
|
||||
string display = null;
|
||||
if (sid != 0)
|
||||
{
|
||||
display = ResolvePersonaName(sid);
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(display))
|
||||
{
|
||||
display = GetObjectDisplayName();
|
||||
}
|
||||
if (!string.Equals(text.text, display))
|
||||
{
|
||||
text.text = display;
|
||||
}
|
||||
}
|
||||
|
||||
private string ResolvePersonaName(ulong sid)
|
||||
{
|
||||
if (!SteamBootstrap.IsInitialized)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ulong local = SteamUser.GetSteamID().m_SteamID;
|
||||
if (sid == local)
|
||||
{
|
||||
return SteamFriends.GetPersonaName();
|
||||
}
|
||||
|
||||
var csid = new CSteamID(sid);
|
||||
string name = SteamFriends.GetFriendPersonaName(csid);
|
||||
if (string.IsNullOrEmpty(name) || name == "???")
|
||||
{
|
||||
SteamFriends.RequestUserInformation(csid, true);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private string GetObjectDisplayName()
|
||||
{
|
||||
string n = transform.root != null ? transform.root.name : gameObject.name;
|
||||
if (n.StartsWith("Wizard_"))
|
||||
{
|
||||
return n.Substring("Wizard_".Length);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private static Transform FindChildRecursive(Transform root, string name)
|
||||
{
|
||||
if (root == null) return null;
|
||||
foreach (Transform c in root)
|
||||
{
|
||||
if (c.name == name) return c;
|
||||
var r = FindChildRecursive(c, name);
|
||||
if (r != null) return r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Game/Scripts/UI/SteamNameTag.cs.meta
Normal file
2
Game/Scripts/UI/SteamNameTag.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79fb1fbc20d80f546ba695c751860930
|
||||
@@ -12,6 +12,8 @@ GameObject:
|
||||
- component: {fileID: 3684779780933677124}
|
||||
- component: {fileID: 938331400041015936}
|
||||
- component: {fileID: 8192567680868647748}
|
||||
- component: {fileID: 4756281759482734665}
|
||||
- component: {fileID: 8304926713945689473}
|
||||
m_Layer: 0
|
||||
m_Name: SpawnController
|
||||
m_TagString: Untagged
|
||||
@@ -92,3 +94,35 @@ MonoBehaviour:
|
||||
poolRoot: {fileID: 0}
|
||||
markAsDontDestroyOnLoad: 1
|
||||
defaultHardCap: 64
|
||||
--- !u!114 &4756281759482734665
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3072068626087694729}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5137a566078d27c81957d1c4040e32eb, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
spawner: {fileID: 938331400041015936}
|
||||
gameController: {fileID: 3684779780933677124}
|
||||
pooler: {fileID: 8192567680868647748}
|
||||
additionalDefinitions: []
|
||||
autoFindReferences: 0
|
||||
--- !u!114 &8304926713945689473
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3072068626087694729}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: a4ee45b08060ff11b9c4de6b6ab9d671, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
gameController: {fileID: 3684779780933677124}
|
||||
enemySpawner: {fileID: 938331400041015936}
|
||||
heartbeatInterval: 0.5
|
||||
|
||||
@@ -14,7 +14,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Game.Scripts.Runtime.Data.SpawnerConfig
|
||||
MinSpawnRadius: 8
|
||||
MaxSpawnRadius: 24
|
||||
SpawnInterval: 10
|
||||
SpawnInterval: 5
|
||||
SpawnRateOverTime:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
@@ -39,7 +39,7 @@ MonoBehaviour:
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
MaxConcurrent: 20
|
||||
MaxConcurrent: 50
|
||||
MaxPlacementAttempts: 6
|
||||
PrewarmPerType: 4
|
||||
PoolHardCapPerType: 60
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1101 &-8653239217332838315
|
||||
--- !u!1102 &-9159441798702175618
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Jump Land
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 3313327580545924896}
|
||||
- {fileID: 1851180482452469980}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 3094330708855449807, guid: c969c57136eab8b48b882fdc45e975c4, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &-5633800869693003173
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -15,7 +43,7 @@ AnimatorStateTransition:
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 2133809347797768411}
|
||||
m_DstState: {fileID: 5754690394921863263}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
@@ -28,34 +56,116 @@ AnimatorStateTransition:
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-8501351176590210390
|
||||
--- !u!1101 &-5481894409494695167
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: IsCrouching
|
||||
m_EventTreshold: 0
|
||||
- m_ConditionMode: 3
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -4140020287260570153}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &-4182145420113595913
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 4
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 5754690394921863263}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-4140020287260570153
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Jump Begin
|
||||
m_Name: Move
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 6106028750639478370}
|
||||
- {fileID: -4182145420113595913}
|
||||
- {fileID: 3230187453778429532}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_SpeedParameterActive: 1
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 3094330708855449807, guid: b1844fbe628f5bf4ab29e6c68912a708, type: 3}
|
||||
m_Motion: {fileID: 1645608330671036843}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_SpeedParameter: MoveSpeedNormalized
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1102 &-6354293237005665956
|
||||
--- !u!1101 &-2863568448335919091
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsJumping
|
||||
m_EventTreshold: 0
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: IsGrounded
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 7993235720092425232}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-1553988547846161377
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
@@ -81,43 +191,20 @@ AnimatorState:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &-4096702130486027139
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 4
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 2133809347797768411}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &-3837842955075777776
|
||||
--- !u!1102 &-1281127197651375096
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Move
|
||||
m_Name: Crouch
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -4096702130486027139}
|
||||
- {fileID: -5633800869693003173}
|
||||
- {fileID: -5481894409494695167}
|
||||
- {fileID: -2863568448335919091}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
@@ -127,12 +214,37 @@ AnimatorState:
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 7292886750186029930}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: aa30e50360fde394fb96e9e6c0ba8e18, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &-1175380347819888189
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsGrounded
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -9159441798702175618}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!91 &9100000
|
||||
AnimatorController:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -160,6 +272,12 @@ AnimatorController:
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
- m_Name: MoveSpeedNormalized
|
||||
m_Type: 1
|
||||
m_DefaultFloat: 0
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
- m_Name: IsGrounded
|
||||
m_Type: 4
|
||||
m_DefaultFloat: 0
|
||||
@@ -178,8 +296,8 @@ AnimatorController:
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
- m_Name: Jump
|
||||
m_Type: 9
|
||||
- m_Name: IsJumping
|
||||
m_Type: 4
|
||||
m_DefaultFloat: 0
|
||||
m_DefaultInt: 0
|
||||
m_DefaultBool: 0
|
||||
@@ -187,7 +305,7 @@ AnimatorController:
|
||||
m_AnimatorLayers:
|
||||
- serializedVersion: 5
|
||||
m_Name: Base Layer
|
||||
m_StateMachine: {fileID: 456980109897493105}
|
||||
m_StateMachine: {fileID: 8917191963327386668}
|
||||
m_Mask: {fileID: 0}
|
||||
m_Motions: []
|
||||
m_Behaviours: []
|
||||
@@ -197,105 +315,7 @@ AnimatorController:
|
||||
m_IKPass: 0
|
||||
m_SyncedLayerAffectsTiming: 0
|
||||
m_Controller: {fileID: 9100000}
|
||||
--- !u!1102 &429358291008205178
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Jump Land
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 6017886512958357952}
|
||||
- {fileID: 9219489292818365840}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 3094330708855449807, guid: c969c57136eab8b48b882fdc45e975c4, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1107 &456980109897493105
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Base Layer
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 2133809347797768411}
|
||||
m_Position: {x: 250, y: 50, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -3837842955075777776}
|
||||
m_Position: {x: 250, y: 150, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 3657533443322484474}
|
||||
m_Position: {x: 250, y: 250, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -8501351176590210390}
|
||||
m_Position: {x: 500, y: 50, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 4880998032211746345}
|
||||
m_Position: {x: 500, y: 150, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 429358291008205178}
|
||||
m_Position: {x: 500, y: 250, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -6354293237005665956}
|
||||
m_Position: {x: 250, y: 350, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions:
|
||||
- {fileID: 9054913250047092416}
|
||||
- {fileID: 7541083490971539274}
|
||||
- {fileID: 8366131237598160117}
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 2133809347797768411}
|
||||
--- !u!1102 &2133809347797768411
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Idle
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 9167710540657582094}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: -2576967968662016515, guid: 56fd86b76fc74d24d83522069f5deb9b, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &3448741829527053982
|
||||
--- !u!1101 &254728727500707171
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -304,10 +324,38 @@ AnimatorStateTransition:
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsCrouching
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -1281127197651375096}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &461524094991714154
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsJumping
|
||||
m_EventTreshold: 0
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: IsGrounded
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 429358291008205178}
|
||||
m_DstState: {fileID: 7993235720092425232}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
@@ -320,35 +368,7 @@ AnimatorStateTransition:
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &3657533443322484474
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Crouch
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: -8653239217332838315}
|
||||
- {fileID: 5152896216695493134}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 3094330708855449807, guid: aa30e50360fde394fb96e9e6c0ba8e18, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1102 &4880998032211746345
|
||||
--- !u!1102 &861509553362583957
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
@@ -359,7 +379,7 @@ AnimatorState:
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 3448741829527053982}
|
||||
- {fileID: -1175380347819888189}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
@@ -375,82 +395,7 @@ AnimatorState:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &5152896216695493134
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: IsCrouching
|
||||
m_EventTreshold: 0
|
||||
- m_ConditionMode: 3
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -3837842955075777776}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &6017886512958357952
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 4
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 2133809347797768411}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.7
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &6106028750639478370
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 4880998032211746345}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.8
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!206 &7292886750186029930
|
||||
--- !u!206 &1645608330671036843
|
||||
BlendTree:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -459,7 +404,7 @@ BlendTree:
|
||||
m_Name: MoveTree
|
||||
m_Childs:
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: c133e3c197c12e04a9dd23bd0966910f, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 6deac83e30d8acd4cbb8c7d8a11545bd, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0, y: 1}
|
||||
m_TimeScale: 1
|
||||
@@ -467,7 +412,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: f1f1135ca9cfa8c47bf81718bb0d6873, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: a8e6c7cf678a13541a726c2ae9ec00e3, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0, y: -1}
|
||||
m_TimeScale: 1
|
||||
@@ -475,7 +420,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: b702e254d5e77904da0429cfcbc77709, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 9f9dbe8815370164d8a2214328af4f13, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: -1, y: 0}
|
||||
m_TimeScale: 1
|
||||
@@ -483,7 +428,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 2cd37dc84c089ac4981cd6d36abd33eb, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 9f9dbe8815370164d8a2214328af4f13, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 1, y: 0}
|
||||
m_TimeScale: 1
|
||||
@@ -491,7 +436,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 3a4cf5e04ded562489d1c3b2da8c2d7a, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 2d491dc6ab8cc5045919954fe2601203, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: -0.707, y: 0.707}
|
||||
m_TimeScale: 1
|
||||
@@ -499,7 +444,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: dd9cde7e792f5f946b091935d7903296, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 152af2cd00aaae34e816ebb8deb4b68e, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0.707, y: 0.707}
|
||||
m_TimeScale: 1
|
||||
@@ -507,7 +452,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 5dcc71b9770f2554e8fd3ea0d6c1e1f4, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 02fe127be7c987640bef36b78efaf2cf, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: -0.707, y: -0.707}
|
||||
m_TimeScale: 1
|
||||
@@ -515,7 +460,7 @@ BlendTree:
|
||||
m_DirectBlendParameter:
|
||||
m_Mirror: 0
|
||||
- serializedVersion: 2
|
||||
m_Motion: {fileID: 3094330708855449807, guid: 55d43189338018e4c9e0c2ce1f608563, type: 3}
|
||||
m_Motion: {fileID: 3094330708855449807, guid: ca7bf50d255ff5749a3a9ff602076af8, type: 3}
|
||||
m_Threshold: 0
|
||||
m_Position: {x: 0.707, y: -0.707}
|
||||
m_TimeScale: 1
|
||||
@@ -529,82 +474,7 @@ BlendTree:
|
||||
m_UseAutomaticThresholds: 0
|
||||
m_NormalizedBlendValues: 0
|
||||
m_BlendType: 3
|
||||
--- !u!1101 &7541083490971539274
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: Jump
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -8501351176590210390}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 0
|
||||
--- !u!1101 &8366131237598160117
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsDead
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -6354293237005665956}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.2
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &9054913250047092416
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsCrouching
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 3657533443322484474}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &9167710540657582094
|
||||
--- !u!1101 &1851180482452469980
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@@ -616,32 +486,7 @@ AnimatorStateTransition:
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -3837842955075777776}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &9219489292818365840
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 3
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -3837842955075777776}
|
||||
m_DstState: {fileID: -4140020287260570153}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
@@ -654,3 +499,225 @@ AnimatorStateTransition:
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &3230187453778429532
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsJumping
|
||||
m_EventTreshold: 0
|
||||
- m_ConditionMode: 2
|
||||
m_ConditionEvent: IsGrounded
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 7993235720092425232}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &3313327580545924896
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 4
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 5754690394921863263}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.7
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &5754690394921863263
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Idle
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 6463146362643610033}
|
||||
- {fileID: 461524094991714154}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: -2576967968662016515, guid: 56fd86b76fc74d24d83522069f5deb9b, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &6463146362643610033
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 3
|
||||
m_ConditionEvent: Speed
|
||||
m_EventTreshold: 0.1
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -4140020287260570153}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.1
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.9
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1102 &7993235720092425232
|
||||
AnimatorState:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Jump Begin
|
||||
m_Speed: 1
|
||||
m_CycleOffset: 0
|
||||
m_Transitions:
|
||||
- {fileID: 8546449291118487461}
|
||||
m_StateMachineBehaviours: []
|
||||
m_Position: {x: 50, y: 50, z: 0}
|
||||
m_IKOnFeet: 0
|
||||
m_WriteDefaultValues: 1
|
||||
m_Mirror: 0
|
||||
m_SpeedParameterActive: 0
|
||||
m_MirrorParameterActive: 0
|
||||
m_CycleOffsetParameterActive: 0
|
||||
m_TimeParameterActive: 0
|
||||
m_Motion: {fileID: 3094330708855449807, guid: b1844fbe628f5bf4ab29e6c68912a708, type: 3}
|
||||
m_Tag:
|
||||
m_SpeedParameter:
|
||||
m_MirrorParameter:
|
||||
m_CycleOffsetParameter:
|
||||
m_TimeParameter:
|
||||
--- !u!1101 &8415669427978378661
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions:
|
||||
- m_ConditionMode: 1
|
||||
m_ConditionEvent: IsDead
|
||||
m_EventTreshold: 0
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: -1553988547846161377}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.2
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.75
|
||||
m_HasExitTime: 0
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1101 &8546449291118487461
|
||||
AnimatorStateTransition:
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_Conditions: []
|
||||
m_DstStateMachine: {fileID: 0}
|
||||
m_DstState: {fileID: 861509553362583957}
|
||||
m_Solo: 0
|
||||
m_Mute: 0
|
||||
m_IsExit: 0
|
||||
serializedVersion: 3
|
||||
m_TransitionDuration: 0.05
|
||||
m_TransitionOffset: 0
|
||||
m_ExitTime: 0.8
|
||||
m_HasExitTime: 1
|
||||
m_HasFixedDuration: 1
|
||||
m_InterruptionSource: 0
|
||||
m_OrderedInterruption: 1
|
||||
m_CanTransitionToSelf: 1
|
||||
--- !u!1107 &8917191963327386668
|
||||
AnimatorStateMachine:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 1
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Base Layer
|
||||
m_ChildStates:
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 5754690394921863263}
|
||||
m_Position: {x: 250, y: 50, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -4140020287260570153}
|
||||
m_Position: {x: 250, y: 150, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -1281127197651375096}
|
||||
m_Position: {x: 250, y: 250, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 7993235720092425232}
|
||||
m_Position: {x: 500, y: 50, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: 861509553362583957}
|
||||
m_Position: {x: 500, y: 150, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -9159441798702175618}
|
||||
m_Position: {x: 500, y: 250, z: 0}
|
||||
- serializedVersion: 1
|
||||
m_State: {fileID: -1553988547846161377}
|
||||
m_Position: {x: 250, y: 350, z: 0}
|
||||
m_ChildStateMachines: []
|
||||
m_AnyStateTransitions:
|
||||
- {fileID: 254728727500707171}
|
||||
- {fileID: 8415669427978378661}
|
||||
m_EntryTransitions: []
|
||||
m_StateMachineTransitions: {}
|
||||
m_StateMachineBehaviours: []
|
||||
m_AnyStatePosition: {x: 50, y: 20, z: 0}
|
||||
m_EntryPosition: {x: 50, y: 120, z: 0}
|
||||
m_ExitPosition: {x: 800, y: 120, z: 0}
|
||||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
|
||||
m_DefaultState: {fileID: 5754690394921863263}
|
||||
|
||||
8
MegaKoop.meta
Normal file
8
MegaKoop.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0da2da2780d0484dbb4b0d6698bab27
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
MegaKoop/GeneratedUI.meta
Normal file
8
MegaKoop/GeneratedUI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 486c8daa3c35a794ab6d0d0926b1cdbe
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
MegaKoop/GeneratedUI/pill_32.png
Normal file
BIN
MegaKoop/GeneratedUI/pill_32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
130
MegaKoop/GeneratedUI/pill_32.png.meta
Normal file
130
MegaKoop/GeneratedUI/pill_32.png.meta
Normal file
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e12555a05d95f214ba3f917c40371b0c
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 32, y: 32, z: 32, w: 32}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
MegaKoop/GeneratedUI/rounded_16.png
Normal file
BIN
MegaKoop/GeneratedUI/rounded_16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 430 B |
130
MegaKoop/GeneratedUI/rounded_16.png.meta
Normal file
130
MegaKoop/GeneratedUI/rounded_16.png.meta
Normal file
@@ -0,0 +1,130 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34eb234f95e13684ea08cfe7cd06a207
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 13
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
flipGreenChannel: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
ignoreMipmapLimit: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 2
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 16, y: 16, z: 16, w: 16}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 4
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 4
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
ignorePlatformSupport: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
customData:
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spriteCustomMetadata:
|
||||
entries: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -378,9 +378,36 @@ namespace MegaKoop.Steam
|
||||
|
||||
private void OnRichPresenceJoinRequestedCb(GameRichPresenceJoinRequested_t cb)
|
||||
{
|
||||
// Some Steamworks.NET versions expose only m_rgchConnect here.
|
||||
// We cannot reliably parse lobby id across versions; log and rely on GameLobbyJoinRequested_t for lobby joins.
|
||||
Debug.Log("[SteamLobbyService] RichPresence join requested - handle via GameLobbyJoinRequested or custom connect string.");
|
||||
// Parse steam://joinlobby/<appId>/<lobbyId>/<steamId> and join the lobby
|
||||
string conn = cb.m_rgchConnect;
|
||||
if (!string.IsNullOrEmpty(conn))
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = conn.Trim();
|
||||
const string prefix = "steam://joinlobby/";
|
||||
if (s.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var rest = s.Substring(prefix.Length);
|
||||
var parts = rest.Split('/');
|
||||
// Expected: [appId, lobbyId, steamId]
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
if (ulong.TryParse(parts[1], out var lobbyId))
|
||||
{
|
||||
var lobby = new CSteamID(lobbyId);
|
||||
SteamMatchmaking.JoinLobby(lobby);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[SteamLobbyService] Failed to parse rich presence connect '{conn}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
Debug.LogWarning($"[SteamLobbyService] RichPresence join requested but could not parse connect '{conn}'.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
8
Resources.meta
Normal file
8
Resources.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3823f2d99b808149beac04887adcd94
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
40
Resources/ChampionDatabase.asset
Normal file
40
Resources/ChampionDatabase.asset
Normal file
@@ -0,0 +1,40 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 2844d064cf51ea940a481b3b76c10ff6, type: 3}
|
||||
m_Name: ChampionDatabase
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.Champions.ChampionDatabase
|
||||
champions:
|
||||
- {fileID: 11400000, guid: e91e178970c9ce94fa1aae63627dd287, type: 2}
|
||||
- {fileID: 11400000, guid: 3063583c11830974380a240794f2a205, type: 2}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
- {fileID: 0}
|
||||
8
Resources/ChampionDatabase.asset.meta
Normal file
8
Resources/ChampionDatabase.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e37c7626379bc4d4d8201c2e0a952d71
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Resources/UI.meta
Normal file
8
Resources/UI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a36370dada5aac34aa74f79ffad8e647
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
52
Resources/UI/Lobby.uxml
Normal file
52
Resources/UI/Lobby.uxml
Normal file
@@ -0,0 +1,52 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
|
||||
<ui:VisualElement class="root">
|
||||
<ui:VisualElement class="panel" name="Panel_Lobby">
|
||||
<ui:Label class="title" text="LOBBY" />
|
||||
|
||||
<!-- Status and Code -->
|
||||
<ui:VisualElement class="status-bar">
|
||||
<ui:Label class="status" name="Text_Status" text="OFFLINE" />
|
||||
<ui:Label class="lobby-code-label" text="CODE:" />
|
||||
<ui:Label class="lobby-code" name="Text_LobbyCodeValue" text="------" />
|
||||
<ui:Button class="small-button" name="Button_CopyCode" text="COPY" />
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Tabs -->
|
||||
<ui:VisualElement class="tab-bar">
|
||||
<ui:Button class="tab-button" name="Button_HostTab" text="HOST" />
|
||||
<ui:Button class="tab-button" name="Button_JoinTab" text="JOIN" />
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Host Group -->
|
||||
<ui:VisualElement class="tab-content" name="Group_Host">
|
||||
<ui:DropdownField class="dropdown" name="Dropdown_MaxPlayers" label="Max Players" />
|
||||
<ui:Toggle class="toggle" name="Toggle_PublicLobby" label="Public Lobby" />
|
||||
<ui:Button class="button" name="Button_CreateLobby" text="CREATE LOBBY" />
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Join Group -->
|
||||
<ui:VisualElement class="tab-content" name="Group_Join">
|
||||
<ui:TextField class="text-field" name="Input_LobbyCode" label="Lobby Code" />
|
||||
<ui:Button class="button" name="Button_Connect" text="CONNECT" />
|
||||
</ui:VisualElement>
|
||||
|
||||
<!-- Players List -->
|
||||
<ui:GroupBox class="players-group">
|
||||
<ui:Label class="group-title" text="Players" />
|
||||
<ui:Label class="player-count" name="Text_PlayerCount" text="0/4 Players" />
|
||||
<ui:ScrollView class="players-scroll" name="Scroll_Players">
|
||||
<ui:VisualElement name="Content_PlayersList" class="players-content" />
|
||||
</ui:ScrollView>
|
||||
</ui:GroupBox>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<ui:VisualElement class="action-buttons">
|
||||
<ui:Button class="button" name="Button_InviteFriends" text="INVITE FRIENDS" />
|
||||
<ui:Button class="button" name="Button_ToggleReady" text="READY" />
|
||||
<ui:Button class="button" name="Button_StartGame" text="START GAME" />
|
||||
<ui:Button class="button" name="Button_LeaveLobby" text="LEAVE" />
|
||||
<ui:Button class="button" name="Button_BackFromLobby" text="BACK" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
10
Resources/UI/Lobby.uxml.meta
Normal file
10
Resources/UI/Lobby.uxml.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 538b6231934f83d4e81659acd0184683
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
11
Resources/UI/MainMenu.uxml
Normal file
11
Resources/UI/MainMenu.uxml
Normal file
@@ -0,0 +1,11 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
|
||||
<ui:VisualElement class="root">
|
||||
<ui:VisualElement class="panel" name="Panel_MainMenu">
|
||||
<ui:Label class="title" text="MageKoop" />
|
||||
<ui:Button class="button" name="Button_Play" text="PLAY" />
|
||||
<ui:Button class="button" name="Button_Join" text="JOIN" />
|
||||
<ui:Button class="button" name="Button_Settings" text="SETTINGS" />
|
||||
<ui:Button class="button" name="Button_Quit" text="QUIT" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
10
Resources/UI/MainMenu.uxml.meta
Normal file
10
Resources/UI/MainMenu.uxml.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23149369d8f3d49438ce80e1c8ead9b9
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
50
Resources/UI/New Panel Settings.asset
Normal file
50
Resources/UI/New Panel Settings.asset
Normal file
@@ -0,0 +1,50 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 19101, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_Name: New Panel Settings
|
||||
m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.PanelSettings
|
||||
themeUss: {fileID: -4733365628477956816, guid: ab886bbada599f947a3b93ee959a51c9, type: 3}
|
||||
m_DisableNoThemeWarning: 0
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_ColliderUpdateMode: 0
|
||||
m_ColliderIsTrigger: 1
|
||||
m_ScaleMode: 1
|
||||
m_ReferenceSpritePixelsPerUnit: 100
|
||||
m_PixelsPerUnit: 100
|
||||
m_Scale: 1
|
||||
m_ReferenceDpi: 278.1
|
||||
m_FallbackDpi: 96
|
||||
m_ReferenceResolution: {x: 1200, y: 800}
|
||||
m_ScreenMatchMode: 0
|
||||
m_Match: 0
|
||||
m_SortingOrder: 0
|
||||
m_TargetDisplay: 0
|
||||
m_BindingLogLevel: 0
|
||||
m_ClearDepthStencil: 1
|
||||
m_ClearColor: 0
|
||||
m_ColorClearValue: {r: 0, g: 0, b: 0, a: 0}
|
||||
m_VertexBudget: 0
|
||||
m_DynamicAtlasSettings:
|
||||
m_MinAtlasSize: 64
|
||||
m_MaxAtlasSize: 4096
|
||||
m_MaxSubTextureSize: 64
|
||||
m_ActiveFilters: -1
|
||||
m_AtlasBlitShader: {fileID: 9101, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_RuntimeShader: {fileID: 9100, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_RuntimeWorldShader: {fileID: 9102, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_SDFShader: {fileID: 19011, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_BitmapShader: {fileID: 9001, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_SpriteShader: {fileID: 19012, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ICUDataAsset: {fileID: 0}
|
||||
forceGammaRendering: 0
|
||||
textSettings: {fileID: 0}
|
||||
8
Resources/UI/New Panel Settings.asset.meta
Normal file
8
Resources/UI/New Panel Settings.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89f4f7ac6e9bec34fac6f5115884e279
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
29
Resources/UI/SelectChampion.uxml
Normal file
29
Resources/UI/SelectChampion.uxml
Normal file
@@ -0,0 +1,29 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
|
||||
<ui:VisualElement class="root">
|
||||
<ui:VisualElement class="panel" name="Panel_SelectChampion">
|
||||
<ui:Label class="title" text="SELECT CHAMPION" />
|
||||
|
||||
<ui:ScrollView class="champion-scroll">
|
||||
<ui:ListView class="champion-list" name="ListView_Champions" />
|
||||
</ui:ScrollView>
|
||||
|
||||
<ui:VisualElement class="champion-info" name="Panel_ChampionInfo">
|
||||
<ui:Label class="champion-name" name="Label_ChampionName" text="Select a Champion" />
|
||||
<ui:Label class="champion-description" name="Label_ChampionDescription" text="Choose your champion to begin the game." />
|
||||
<ui:VisualElement class="champion-stats">
|
||||
<ui:Label class="stat-label" text="Health:" />
|
||||
<ui:Label class="stat-value" name="Label_Health" text="--" />
|
||||
<ui:Label class="stat-label" text="Attack:" />
|
||||
<ui:Label class="stat-value" name="Label_Attack" text="--" />
|
||||
<ui:Label class="stat-label" text="Speed:" />
|
||||
<ui:Label class="stat-value" name="Label_Speed" text="--" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
|
||||
<ui:VisualElement class="button-row">
|
||||
<ui:Button class="button" name="Button_SelectChampion" text="SELECT" />
|
||||
<ui:Button class="button" name="Button_BackFromChampionSelect" text="BACK" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
10
Resources/UI/SelectChampion.uxml.meta
Normal file
10
Resources/UI/SelectChampion.uxml.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30d3a72f007fb4846939f7f6a51cdbb0
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
26
Resources/UI/Settings.uxml
Normal file
26
Resources/UI/Settings.uxml
Normal file
@@ -0,0 +1,26 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" editor-extension-mode="False">
|
||||
<ui:VisualElement class="root">
|
||||
<ui:VisualElement class="panel" name="Panel_Settings">
|
||||
<ui:Label class="title" text="SETTINGS" />
|
||||
|
||||
<ui:GroupBox class="settings-group">
|
||||
<ui:Label class="group-title" text="Graphics" />
|
||||
<ui:DropdownField class="dropdown" name="Dropdown_Quality" label="Quality" />
|
||||
<ui:DropdownField class="dropdown" name="Dropdown_Resolution" label="Resolution" />
|
||||
<ui:Toggle class="toggle" name="Toggle_Fullscreen" label="Fullscreen" />
|
||||
</ui:GroupBox>
|
||||
|
||||
<ui:GroupBox class="settings-group">
|
||||
<ui:Label class="group-title" text="Audio" />
|
||||
<ui:Slider class="slider" name="Slider_MasterVolume" label="Master Volume" low-value="0" high-value="100" value="100" />
|
||||
<ui:Slider class="slider" name="Slider_MusicVolume" label="Music Volume" low-value="0" high-value="100" value="80" />
|
||||
<ui:Slider class="slider" name="Slider_SFXVolume" label="SFX Volume" low-value="0" high-value="100" value="100" />
|
||||
</ui:GroupBox>
|
||||
|
||||
<ui:VisualElement class="button-row">
|
||||
<ui:Button class="button" name="Button_ApplySettings" text="APPLY" />
|
||||
<ui:Button class="button" name="Button_BackFromSettings" text="BACK" />
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
10
Resources/UI/Settings.uxml.meta
Normal file
10
Resources/UI/Settings.uxml.meta
Normal file
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d519118cd99e75140b82a612e7bea482
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
72
Resources/UIPanelSettings.asset
Normal file
72
Resources/UIPanelSettings.asset
Normal file
@@ -0,0 +1,72 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ca76b4b0176a31c4c970c750d21e86ab, type: 3}
|
||||
m_Name: UIPanelSettings
|
||||
m_EditorClassIdentifier: Assembly-CSharp::MegaKoop.UI.UIPanelSettings
|
||||
mainMenuPanel: {fileID: 9197481963319205126, guid: 23149369d8f3d49438ce80e1c8ead9b9, type: 3}
|
||||
settingsPanel: {fileID: 9197481963319205126, guid: d519118cd99e75140b82a612e7bea482, type: 3}
|
||||
lobbyPanel: {fileID: 9197481963319205126, guid: 538b6231934f83d4e81659acd0184683, type: 3}
|
||||
championSelectPanel: {fileID: 9197481963319205126, guid: 30d3a72f007fb4846939f7f6a51cdbb0, type: 3}
|
||||
themeStyleSheet: {fileID: 7433441132597879392, guid: 09cd88ad290da0c4b87b4b1d8e9eeca0, type: 3}
|
||||
mainMenuStyleSheet: {fileID: 0}
|
||||
settingsStyleSheet: {fileID: 0}
|
||||
lobbyStyleSheet: {fileID: 0}
|
||||
championSelectStyleSheet: {fileID: 0}
|
||||
enableTransitions: 1
|
||||
transitionDuration: 0.3
|
||||
enableSoundEffects: 1
|
||||
enableHapticFeedback: 0
|
||||
enableResponsiveDesign: 1
|
||||
minResolution: {x: 1280, y: 720}
|
||||
maxResolution: {x: 3840, y: 2160}
|
||||
showCurve:
|
||||
m_Curve:
|
||||
- time: 0
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- time: 1
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
hideCurve:
|
||||
m_Curve:
|
||||
- time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
- time: 1
|
||||
value: 0
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0
|
||||
outWeight: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
8
Resources/UIPanelSettings.asset.meta
Normal file
8
Resources/UIPanelSettings.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c08e0f100d3df7409c38fff4a7a2e31
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28783
Scenes/MainMenu.unity
28783
Scenes/MainMenu.unity
File diff suppressed because it is too large
Load Diff
56748
Scenes/SimplePoly City - Low Poly Assets_Demo Scene.unity
Normal file
56748
Scenes/SimplePoly City - Low Poly Assets_Demo Scene.unity
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f51635c50073da5cabba6efdf303ee59
|
||||
timeCreated: 1488638231
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Scripts.meta
Normal file
8
Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 389bd161b6106e84b8268a9d3fc2c6aa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Scripts/UI.meta
Normal file
8
Scripts/UI.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74e5ebdb8ee4aab43bbb71822815ffcc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,20 +2,28 @@
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF - Metalic Green
|
||||
m_Shader: {fileID: 4800000, guid: 68e6db2ebdc24f95958faec2be5558d6, type: 3}
|
||||
m_ShaderKeywords: BEVEL_ON GLOW_ON OUTLINE_ON UNDERLAY_ON
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- BEVEL_ON
|
||||
- GLOW_ON
|
||||
- OUTLINE_ON
|
||||
- UNDERLAY_ON
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
@@ -32,14 +40,14 @@ Material:
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee,
|
||||
type: 2}
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OutlineTex:
|
||||
m_Texture: {fileID: 2800000, guid: f88677df267a41d6be1e7a6133e7d227, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _Ambient: 0
|
||||
- _Bevel: 1
|
||||
@@ -50,6 +58,7 @@ Material:
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _ColorMask: 15
|
||||
- _CullMode: 0
|
||||
- _Diffuse: 0
|
||||
- _FaceDilate: 0.15
|
||||
- _FaceUVSpeedX: 0
|
||||
@@ -69,8 +78,8 @@ Material:
|
||||
- _PerspectiveFilter: 0
|
||||
- _Reflectivity: 12.76
|
||||
- _ScaleRatioA: 0.9
|
||||
- _ScaleRatioB: 0.6525
|
||||
- _ScaleRatioC: 0.6525
|
||||
- _ScaleRatioB: 0.59624994
|
||||
- _ScaleRatioC: 0.59624994
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
@@ -102,3 +111,5 @@ Material:
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 0.7689687, g: 1, b: 0.75000346, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -6,6 +6,7 @@ using TMPro;
|
||||
#else
|
||||
using TMPro;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MegaKoop.UI
|
||||
{
|
||||
@@ -24,19 +25,20 @@ namespace MegaKoop.UI
|
||||
private GameObject panelSettings;
|
||||
private GameObject panelLobby;
|
||||
|
||||
// Main buttons
|
||||
private Button btnNewGame;
|
||||
private Button btnContinue;
|
||||
private Button btnMultiplayer;
|
||||
private Button btnSettings;
|
||||
private Button btnQuit;
|
||||
[Header("Manual Wiring - Main Menu Buttons")]
|
||||
[SerializeField] private Button btnMultiplayer;
|
||||
[SerializeField] private Button btnSettings;
|
||||
[SerializeField] private Button btnQuit;
|
||||
|
||||
// Settings controls
|
||||
private TMP_Dropdown ddQuality;
|
||||
private Toggle tgFullscreen;
|
||||
private TMP_Dropdown ddResolution;
|
||||
private Button btnApplySettings;
|
||||
private Button btnBackFromSettings;
|
||||
[Header("Manual Wiring - Settings Controls")]
|
||||
[SerializeField] private TMP_Dropdown ddQuality;
|
||||
[SerializeField] private Toggle tgFullscreen;
|
||||
[SerializeField] private TMP_Dropdown ddResolution;
|
||||
[SerializeField] private Button btnApplySettings;
|
||||
[SerializeField] private Button btnBackFromSettings;
|
||||
[SerializeField] private Slider slMaster;
|
||||
[SerializeField] private Slider slMusic;
|
||||
[SerializeField] private Slider slSFX;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -44,21 +46,27 @@ namespace MegaKoop.UI
|
||||
RefreshPanelReferences();
|
||||
|
||||
// Buttons
|
||||
btnNewGame = FindButton("Button_NewGame");
|
||||
btnContinue = FindButton("Button_Continue");
|
||||
btnMultiplayer = FindButton("Button_Multiplayer");
|
||||
btnSettings = FindButton("Button_Settings");
|
||||
btnQuit = FindButton("Button_Quit");
|
||||
btnMultiplayer = EnsureButton(btnMultiplayer, "Button_Multiplayer", panelMain ? panelMain.transform : this.transform);
|
||||
btnSettings = EnsureButton(btnSettings, "Button_Settings", panelMain ? panelMain.transform : this.transform);
|
||||
btnQuit = EnsureButton(btnQuit, "Button_Quit", panelMain ? panelMain.transform : this.transform);
|
||||
|
||||
// Settings
|
||||
ddQuality = FindDropdown("Dropdown_Quality");
|
||||
tgFullscreen = FindToggle("Toggle_Fullscreen");
|
||||
ddResolution = FindDropdown("Dropdown_Resolution");
|
||||
btnApplySettings = FindButton("Button_ApplySettings");
|
||||
btnBackFromSettings = FindButton("Button_BackFromSettings");
|
||||
ddQuality = EnsureDropdown(ddQuality, "Dropdown_Quality", panelSettings ? panelSettings.transform : this.transform);
|
||||
tgFullscreen = EnsureToggle(tgFullscreen, "Toggle_Fullscreen", panelSettings ? panelSettings.transform : this.transform);
|
||||
ddResolution = EnsureDropdown(ddResolution, "Dropdown_Resolution", panelSettings ? panelSettings.transform : this.transform);
|
||||
btnApplySettings = EnsureButton(btnApplySettings, "Button_ApplySettings", panelSettings ? panelSettings.transform : this.transform);
|
||||
btnBackFromSettings = EnsureButton(btnBackFromSettings, "Button_BackFromSettings", panelSettings ? panelSettings.transform : this.transform);
|
||||
slMaster = EnsureSlider(slMaster, "Slider_MasterVolume", panelSettings ? panelSettings.transform : this.transform);
|
||||
slMusic = EnsureSlider(slMusic, "Slider_MusicVolume", panelSettings ? panelSettings.transform : this.transform);
|
||||
slSFX = EnsureSlider(slSFX, "Slider_SFXVolume", panelSettings ? panelSettings.transform : this.transform);
|
||||
|
||||
if (!btnApplySettings && panelSettings) btnApplySettings = FindButtonByLabel("APPLY", panelSettings.transform);
|
||||
if (!btnBackFromSettings && panelSettings) btnBackFromSettings = FindButtonByLabel("BACK", panelSettings.transform);
|
||||
|
||||
WireEvents();
|
||||
|
||||
InitializeSettingsUI();
|
||||
|
||||
// Ensure initial panels
|
||||
ShowMainMenu();
|
||||
}
|
||||
@@ -72,6 +80,27 @@ namespace MegaKoop.UI
|
||||
RefreshPanelReferences();
|
||||
}
|
||||
|
||||
public void SetMainMenuButtons(Button multiplayerButton, Button settingsButton, Button quitButton)
|
||||
{
|
||||
btnMultiplayer = multiplayerButton;
|
||||
btnSettings = settingsButton;
|
||||
btnQuit = quitButton;
|
||||
}
|
||||
|
||||
public void SetSettingsControls(TMP_Dropdown qualityDropdown, Toggle fullscreenToggle,
|
||||
TMP_Dropdown resolutionDropdown, Slider masterVolume, Slider musicVolume, Slider sfxVolume,
|
||||
Button applyButton, Button backButton)
|
||||
{
|
||||
ddQuality = qualityDropdown;
|
||||
tgFullscreen = fullscreenToggle;
|
||||
ddResolution = resolutionDropdown;
|
||||
slMaster = masterVolume;
|
||||
slMusic = musicVolume;
|
||||
slSFX = sfxVolume;
|
||||
btnApplySettings = applyButton;
|
||||
btnBackFromSettings = backButton;
|
||||
}
|
||||
|
||||
private void RefreshPanelReferences()
|
||||
{
|
||||
panelMain = panelMainRef ? panelMainRef : (FindAnyInScene("Panel_MainMenu") ?? panelMain);
|
||||
@@ -79,6 +108,30 @@ namespace MegaKoop.UI
|
||||
panelLobby = panelLobbyRef ? panelLobbyRef : (FindAnyInScene("Panel_Lobby") ?? panelLobby);
|
||||
}
|
||||
|
||||
private Button EnsureButton(Button existing, string name, Transform scope)
|
||||
{
|
||||
if (existing) return existing;
|
||||
return FindButton(name, scope);
|
||||
}
|
||||
|
||||
private TMP_Dropdown EnsureDropdown(TMP_Dropdown existing, string name, Transform scope)
|
||||
{
|
||||
if (existing) return existing;
|
||||
return FindDropdown(name, scope);
|
||||
}
|
||||
|
||||
private Toggle EnsureToggle(Toggle existing, string name, Transform scope)
|
||||
{
|
||||
if (existing) return existing;
|
||||
return FindToggle(name, scope);
|
||||
}
|
||||
|
||||
private Slider EnsureSlider(Slider existing, string name, Transform scope)
|
||||
{
|
||||
if (existing) return existing;
|
||||
return FindSlider(name, scope);
|
||||
}
|
||||
|
||||
private GameObject FindAnyInScene(string name)
|
||||
{
|
||||
// Najde i neaktivní objekty
|
||||
@@ -93,32 +146,106 @@ namespace MegaKoop.UI
|
||||
return null;
|
||||
}
|
||||
|
||||
private Button FindButton(string name)
|
||||
private Button FindButton(string name, Transform scope = null)
|
||||
{
|
||||
var go = GameObject.Find(name);
|
||||
return go ? go.GetComponent<Button>() : null;
|
||||
if (scope != null)
|
||||
{
|
||||
var comps = scope.GetComponentsInChildren<Button>(true);
|
||||
foreach (var c in comps)
|
||||
{
|
||||
if (c && c.name == name) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var all = Resources.FindObjectsOfTypeAll<Button>();
|
||||
foreach (var c in all)
|
||||
{
|
||||
if (c && c.name == name && c.gameObject.scene.IsValid() && c.gameObject.scene.isLoaded) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private TMP_Dropdown FindDropdown(string name)
|
||||
private TMP_Dropdown FindDropdown(string name, Transform scope = null)
|
||||
{
|
||||
var go = GameObject.Find(name);
|
||||
return go ? go.GetComponent<TMP_Dropdown>() : null;
|
||||
if (scope != null)
|
||||
{
|
||||
var comps = scope.GetComponentsInChildren<TMP_Dropdown>(true);
|
||||
foreach (var c in comps)
|
||||
{
|
||||
if (c && c.name == name) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var all = Resources.FindObjectsOfTypeAll<TMP_Dropdown>();
|
||||
foreach (var c in all)
|
||||
{
|
||||
if (c && c.name == name && c.gameObject.scene.IsValid() && c.gameObject.scene.isLoaded) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private Toggle FindToggle(string name)
|
||||
private Toggle FindToggle(string name, Transform scope = null)
|
||||
{
|
||||
var go = GameObject.Find(name);
|
||||
return go ? go.GetComponent<Toggle>() : null;
|
||||
if (scope != null)
|
||||
{
|
||||
var comps = scope.GetComponentsInChildren<Toggle>(true);
|
||||
foreach (var c in comps)
|
||||
{
|
||||
if (c && c.name == name) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var all = Resources.FindObjectsOfTypeAll<Toggle>();
|
||||
foreach (var c in all)
|
||||
{
|
||||
if (c && c.name == name && c.gameObject.scene.IsValid() && c.gameObject.scene.isLoaded) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Slider FindSlider(string name, Transform scope = null)
|
||||
{
|
||||
if (scope != null)
|
||||
{
|
||||
var comps = scope.GetComponentsInChildren<Slider>(true);
|
||||
foreach (var c in comps)
|
||||
{
|
||||
if (c && c.name == name) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var all = Resources.FindObjectsOfTypeAll<Slider>();
|
||||
foreach (var c in all)
|
||||
{
|
||||
if (c && c.name == name && c.gameObject.scene.IsValid() && c.gameObject.scene.isLoaded) return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Button FindButtonByLabel(string label, Transform scope)
|
||||
{
|
||||
if (!scope) return null;
|
||||
var btns = scope.GetComponentsInChildren<Button>(true);
|
||||
for (int i = 0; i < btns.Length; i++)
|
||||
{
|
||||
var t = btns[i].GetComponentInChildren<TextMeshProUGUI>(true);
|
||||
if (t && string.Equals(t.text?.Trim(), label, System.StringComparison.OrdinalIgnoreCase))
|
||||
return btns[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void WireEvents()
|
||||
{
|
||||
if (btnNewGame) btnNewGame.onClick.AddListener(OnNewGame);
|
||||
if (btnContinue) btnContinue.onClick.AddListener(OnContinue);
|
||||
if (btnMultiplayer) btnMultiplayer.onClick.AddListener(OnOpenMultiplayer);
|
||||
if (btnSettings) btnSettings.onClick.AddListener(OnOpenSettings);
|
||||
if (btnQuit) btnQuit.onClick.AddListener(OnQuit);
|
||||
if (btnMultiplayer) btnMultiplayer.onClick.AddListener(OnOpenMultiplayer); else Debug.LogWarning("[UGUIMainMenu] Button_Multiplayer not found");
|
||||
if (btnSettings) btnSettings.onClick.AddListener(OnOpenSettings); else Debug.LogWarning("[UGUIMainMenu] Button_Settings not found");
|
||||
if (btnQuit) btnQuit.onClick.AddListener(OnQuit); else Debug.LogWarning("[UGUIMainMenu] Button_Quit not found");
|
||||
|
||||
if (btnApplySettings) btnApplySettings.onClick.AddListener(ApplySettings);
|
||||
if (btnBackFromSettings) btnBackFromSettings.onClick.AddListener(ShowMainMenu);
|
||||
if (btnApplySettings) btnApplySettings.onClick.AddListener(OnApplySettings); else Debug.LogWarning("[UGUIMainMenu] Button_ApplySettings not found");
|
||||
if (btnBackFromSettings) btnBackFromSettings.onClick.AddListener(ShowMainMenu); else Debug.LogWarning("[UGUIMainMenu] Button_BackFromSettings not found");
|
||||
|
||||
if (ddQuality) ddQuality.onValueChanged.AddListener(i => { Debug.Log("[UGUIMainMenu] Quality changed to index " + i); ddQuality.RefreshShownValue(); });
|
||||
if (ddResolution) ddResolution.onValueChanged.AddListener(i => { Debug.Log("[UGUIMainMenu] Resolution changed to index " + i); ddResolution.RefreshShownValue(); });
|
||||
if (tgFullscreen) tgFullscreen.onValueChanged.AddListener(v => { Debug.Log("[UGUIMainMenu] Fullscreen " + v); });
|
||||
if (slMaster) slMaster.onValueChanged.AddListener(v => { AudioListener.volume = v / 100f; });
|
||||
}
|
||||
|
||||
private void ShowMainMenu()
|
||||
@@ -158,42 +285,7 @@ namespace MegaKoop.UI
|
||||
if (panelMain) panelMain.SetActive(false);
|
||||
if (panelSettings) panelSettings.SetActive(true);
|
||||
if (panelLobby) panelLobby.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnNewGame()
|
||||
{
|
||||
// Co-op only: quick host path
|
||||
UGUIMultiplayerLobbyController lobby;
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
lobby = Object.FindFirstObjectByType<UGUIMultiplayerLobbyController>();
|
||||
#else
|
||||
lobby = Object.FindObjectOfType<UGUIMultiplayerLobbyController>();
|
||||
#endif
|
||||
if (lobby)
|
||||
{
|
||||
if (panelMain) panelMain.SetActive(false);
|
||||
if (panelSettings) panelSettings.SetActive(false);
|
||||
if (panelLobby) panelLobby.SetActive(true);
|
||||
lobby.QuickHost(4, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnContinue()
|
||||
{
|
||||
// Co-op only: join path
|
||||
UGUIMultiplayerLobbyController lobby;
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
lobby = Object.FindFirstObjectByType<UGUIMultiplayerLobbyController>();
|
||||
#else
|
||||
lobby = Object.FindObjectOfType<UGUIMultiplayerLobbyController>();
|
||||
#endif
|
||||
if (lobby)
|
||||
{
|
||||
if (panelMain) panelMain.SetActive(false);
|
||||
if (panelSettings) panelSettings.SetActive(false);
|
||||
if (panelLobby) panelLobby.SetActive(true);
|
||||
lobby.ShowJoinTabPublic();
|
||||
}
|
||||
Debug.Log("[UGUIMainMenu] Open Settings");
|
||||
}
|
||||
|
||||
private void OnQuit()
|
||||
@@ -217,13 +309,190 @@ namespace MegaKoop.UI
|
||||
}
|
||||
if (ddResolution)
|
||||
{
|
||||
var opt = ddResolution.options[ddResolution.value].text; // e.g., "1920x1080"
|
||||
var parts = opt.ToLower().Split('x');
|
||||
if (parts.Length == 2 && int.TryParse(parts[0], out int w) && int.TryParse(parts[1], out int h))
|
||||
if (ddResolution.options != null && ddResolution.options.Count > 0 && ddResolution.value >= 0 && ddResolution.value < ddResolution.options.Count)
|
||||
{
|
||||
Screen.SetResolution(w, h, Screen.fullScreenMode);
|
||||
var opt = ddResolution.options[ddResolution.value].text; // e.g., "1920x1080"
|
||||
var parts = opt.ToLower().Split('x');
|
||||
if (parts.Length == 2 && int.TryParse(parts[0], out int w) && int.TryParse(parts[1], out int h))
|
||||
{
|
||||
Screen.SetResolution(w, h, Screen.fullScreenMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slMaster)
|
||||
{
|
||||
AudioListener.volume = slMaster.value / 100f;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplySettings()
|
||||
{
|
||||
ApplySettings();
|
||||
SaveSettings();
|
||||
ShowMainMenu();
|
||||
Debug.Log("[UGUIMainMenu] Apply & Back to Main");
|
||||
}
|
||||
|
||||
private void InitializeSettingsUI()
|
||||
{
|
||||
if (ddQuality)
|
||||
{
|
||||
var names = QualitySettings.names;
|
||||
if (names != null && names.Length > 0)
|
||||
{
|
||||
ddQuality.ClearOptions();
|
||||
ddQuality.AddOptions(new List<string>(names));
|
||||
ddQuality.value = Mathf.Clamp(QualitySettings.GetQualityLevel(), 0, ddQuality.options.Count - 1);
|
||||
ddQuality.RefreshShownValue();
|
||||
}
|
||||
ddQuality.interactable = true;
|
||||
FixDropdownRaycasts(ddQuality);
|
||||
SetupDropdownTemplateCanvas(ddQuality);
|
||||
}
|
||||
|
||||
if (ddResolution)
|
||||
{
|
||||
var seen = new HashSet<string>();
|
||||
var opts = new List<string>();
|
||||
string cur = Screen.currentResolution.width + "x" + Screen.currentResolution.height;
|
||||
int curIdx = 0;
|
||||
foreach (var r in Screen.resolutions)
|
||||
{
|
||||
string s = r.width + "x" + r.height;
|
||||
if (seen.Add(s))
|
||||
{
|
||||
if (s == cur) curIdx = opts.Count;
|
||||
opts.Add(s);
|
||||
}
|
||||
}
|
||||
if (opts.Count == 0)
|
||||
{
|
||||
opts.Add(cur);
|
||||
curIdx = 0;
|
||||
}
|
||||
ddResolution.ClearOptions();
|
||||
ddResolution.AddOptions(opts);
|
||||
ddResolution.value = Mathf.Clamp(curIdx, 0, ddResolution.options.Count - 1);
|
||||
ddResolution.RefreshShownValue();
|
||||
ddResolution.interactable = true;
|
||||
FixDropdownRaycasts(ddResolution);
|
||||
SetupDropdownTemplateCanvas(ddResolution);
|
||||
}
|
||||
|
||||
if (tgFullscreen)
|
||||
{
|
||||
tgFullscreen.isOn = Screen.fullScreen;
|
||||
tgFullscreen.interactable = true;
|
||||
}
|
||||
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
private void SaveSettings()
|
||||
{
|
||||
if (ddQuality) PlayerPrefs.SetInt("QualityLevel", ddQuality.value);
|
||||
PlayerPrefs.SetInt("Fullscreen", Screen.fullScreen ? 1 : 0);
|
||||
if (ddResolution && ddResolution.options.Count > 0)
|
||||
{
|
||||
var opt = ddResolution.options[ddResolution.value].text;
|
||||
var parts = opt.Split('x');
|
||||
if (parts.Length == 2 && int.TryParse(parts[0], out int w) && int.TryParse(parts[1], out int h))
|
||||
{
|
||||
PlayerPrefs.SetInt("ResolutionWidth", w);
|
||||
PlayerPrefs.SetInt("ResolutionHeight", h);
|
||||
}
|
||||
}
|
||||
if (slMaster) PlayerPrefs.SetFloat("MasterVolume", slMaster.value);
|
||||
if (slMusic) PlayerPrefs.SetFloat("MusicVolume", slMusic.value);
|
||||
if (slSFX) PlayerPrefs.SetFloat("SFXVolume", slSFX.value);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
if (ddQuality && ddQuality.options.Count > 0)
|
||||
{
|
||||
int q = PlayerPrefs.GetInt("QualityLevel", QualitySettings.GetQualityLevel());
|
||||
ddQuality.value = Mathf.Clamp(q, 0, ddQuality.options.Count - 1);
|
||||
ddQuality.RefreshShownValue();
|
||||
}
|
||||
if (tgFullscreen)
|
||||
{
|
||||
bool full = PlayerPrefs.GetInt("Fullscreen", Screen.fullScreen ? 1 : 0) == 1;
|
||||
tgFullscreen.isOn = full;
|
||||
}
|
||||
if (ddResolution && ddResolution.options.Count > 0)
|
||||
{
|
||||
int w = PlayerPrefs.GetInt("ResolutionWidth", Screen.currentResolution.width);
|
||||
int h = PlayerPrefs.GetInt("ResolutionHeight", Screen.currentResolution.height);
|
||||
string key = w + "x" + h;
|
||||
int idx = ddResolution.options.FindIndex(o => o.text == key);
|
||||
if (idx >= 0)
|
||||
{
|
||||
ddResolution.value = idx;
|
||||
ddResolution.RefreshShownValue();
|
||||
}
|
||||
}
|
||||
if (slMaster)
|
||||
{
|
||||
var mv = PlayerPrefs.GetFloat("MasterVolume", 100f);
|
||||
slMaster.value = mv;
|
||||
AudioListener.volume = mv / 100f;
|
||||
}
|
||||
if (slMusic)
|
||||
{
|
||||
slMusic.value = PlayerPrefs.GetFloat("MusicVolume", 80f);
|
||||
}
|
||||
if (slSFX)
|
||||
{
|
||||
slSFX.value = PlayerPrefs.GetFloat("SFXVolume", 100f);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixDropdownRaycasts(TMP_Dropdown dd)
|
||||
{
|
||||
if (!dd || dd.template == null) return;
|
||||
var tpl = dd.template;
|
||||
var vp = tpl.Find("Viewport");
|
||||
if (vp)
|
||||
{
|
||||
var img = vp.GetComponent<Image>();
|
||||
if (img) img.raycastTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupDropdownTemplateCanvas(TMP_Dropdown dd)
|
||||
{
|
||||
if (!dd || dd.template == null) return;
|
||||
var tpl = dd.template;
|
||||
var cv = tpl.GetComponent<Canvas>();
|
||||
if (cv == null) cv = tpl.gameObject.AddComponent<Canvas>();
|
||||
cv.overrideSorting = true;
|
||||
cv.sortingOrder = 5000;
|
||||
if (!tpl.GetComponent<GraphicRaycaster>()) tpl.gameObject.AddComponent<GraphicRaycaster>();
|
||||
}
|
||||
|
||||
private void FixDropdownRaycasts(Dropdown dd)
|
||||
{
|
||||
if (!dd || dd.template == null) return;
|
||||
var tpl = dd.template;
|
||||
var vp = tpl.Find("Viewport");
|
||||
if (vp)
|
||||
{
|
||||
var img = vp.GetComponent<Image>();
|
||||
if (img) img.raycastTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupDropdownTemplateCanvas(Dropdown dd)
|
||||
{
|
||||
if (!dd || dd.template == null) return;
|
||||
var tpl = dd.template;
|
||||
var cv = tpl.GetComponent<Canvas>();
|
||||
if (cv == null) cv = tpl.gameObject.AddComponent<Canvas>();
|
||||
cv.overrideSorting = true;
|
||||
cv.sortingOrder = 5000;
|
||||
if (!tpl.GetComponent<GraphicRaycaster>()) tpl.gameObject.AddComponent<GraphicRaycaster>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,47 +23,47 @@ namespace MegaKoop.UI
|
||||
private GameObject groupJoin;
|
||||
private GameObject groupHost;
|
||||
|
||||
// Header & Code
|
||||
private TMP_Text textStatus;
|
||||
private TMP_Text textLobbyCodeValue;
|
||||
private Button btnCopyCode;
|
||||
[Header("Manual Wiring - Header & Code")]
|
||||
[SerializeField] private TMP_Text textStatus;
|
||||
[SerializeField] private TMP_Text textLobbyCodeValue;
|
||||
[SerializeField] private Button btnCopyCode;
|
||||
|
||||
// Tabs
|
||||
private Button btnHostTab;
|
||||
private Button btnJoinTab;
|
||||
[Header("Manual Wiring - Tabs")]
|
||||
[SerializeField] private Button btnHostTab;
|
||||
[SerializeField] private Button btnJoinTab;
|
||||
|
||||
// Join
|
||||
private TMP_InputField inputLobbyCode;
|
||||
private Button btnConnect;
|
||||
[Header("Manual Wiring - Join Section")]
|
||||
[SerializeField] private TMP_InputField inputLobbyCode;
|
||||
[SerializeField] private Button btnConnect;
|
||||
|
||||
// Host
|
||||
private TMP_Dropdown ddMaxPlayers;
|
||||
private Toggle tgPublicLobby;
|
||||
private Button btnCreateLobby;
|
||||
[Header("Manual Wiring - Host Section")]
|
||||
[SerializeField] private TMP_Dropdown ddMaxPlayers;
|
||||
[SerializeField] private Toggle tgPublicLobby;
|
||||
[SerializeField] private Button btnCreateLobby;
|
||||
|
||||
// Players
|
||||
private TMP_Text textPlayerCount;
|
||||
private ScrollRect scrollPlayers;
|
||||
private Transform contentPlayers;
|
||||
private GameObject playerItemTemplate;
|
||||
private GameObject emptyPlayers;
|
||||
[Header("Manual Wiring - Players List")]
|
||||
[SerializeField] private TMP_Text textPlayerCount;
|
||||
[SerializeField] private ScrollRect scrollPlayers;
|
||||
[SerializeField] private Transform contentPlayers;
|
||||
[SerializeField] private GameObject playerItemTemplate;
|
||||
[SerializeField] private GameObject emptyPlayers;
|
||||
|
||||
// Friends picker (fallback when overlay unavailable)
|
||||
private GameObject panelFriends;
|
||||
private Transform contentFriends;
|
||||
private GameObject emptyFriends;
|
||||
private Button btnBackFromFriends;
|
||||
private Button btnCloseFriendsOverlay;
|
||||
[Header("Manual Wiring - Friends Picker")]
|
||||
[SerializeField] private GameObject panelFriends;
|
||||
[SerializeField] private Transform contentFriends;
|
||||
[SerializeField] private GameObject emptyFriends;
|
||||
[SerializeField] private Button btnBackFromFriends;
|
||||
[SerializeField] private Button btnCloseFriendsOverlay;
|
||||
|
||||
// Host controls
|
||||
private Button btnInviteFriends;
|
||||
private Button btnKickSelected;
|
||||
[Header("Manual Wiring - Host Controls")]
|
||||
[SerializeField] private Button btnInviteFriends;
|
||||
[SerializeField] private Button btnKickSelected;
|
||||
|
||||
// Ready & footer
|
||||
private Button btnToggleReady;
|
||||
private Button btnStartGame;
|
||||
private Button btnLeaveLobby;
|
||||
private Button btnBackFromLobby;
|
||||
[Header("Manual Wiring - Footer")]
|
||||
[SerializeField] private Button btnToggleReady;
|
||||
[SerializeField] private Button btnStartGame;
|
||||
[SerializeField] private Button btnLeaveLobby;
|
||||
[SerializeField] private Button btnBackFromLobby;
|
||||
|
||||
[Header("Player Ready Styling")]
|
||||
[SerializeField] private Color readyBorderColor = new Color(0.2f, 0.82f, 0.35f, 1f);
|
||||
@@ -87,48 +87,49 @@ namespace MegaKoop.UI
|
||||
private string LobbyCode => steam != null ? steam.LobbyCode : string.Empty;
|
||||
private bool clientStartedFromSignal = false;
|
||||
private bool leftDueToKick = false;
|
||||
private bool inviteOverlayRequested = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// Find UI (including inactive)
|
||||
panelLobby = FindAnyGO("Panel_Lobby");
|
||||
groupJoin = FindAnyGO("Group_Join");
|
||||
groupHost = FindAnyGO("Group_Host");
|
||||
panelLobby = EnsureGO(panelLobby, "Panel_Lobby");
|
||||
groupJoin = EnsureGO(groupJoin, "Group_Join");
|
||||
groupHost = EnsureGO(groupHost, "Group_Host");
|
||||
|
||||
textStatus = FindText("Text_Status");
|
||||
textLobbyCodeValue = FindText("Text_LobbyCodeValue");
|
||||
btnCopyCode = FindButton("Button_CopyCode");
|
||||
textStatus = EnsureText(textStatus, "Text_Status");
|
||||
textLobbyCodeValue = EnsureText(textLobbyCodeValue, "Text_LobbyCodeValue");
|
||||
btnCopyCode = EnsureButton(btnCopyCode, "Button_CopyCode");
|
||||
|
||||
btnHostTab = FindButton("Button_HostTab");
|
||||
btnJoinTab = FindButton("Button_JoinTab");
|
||||
btnHostTab = EnsureButton(btnHostTab, "Button_HostTab");
|
||||
btnJoinTab = EnsureButton(btnJoinTab, "Button_JoinTab");
|
||||
|
||||
inputLobbyCode = FindInput("Input_LobbyCode");
|
||||
btnConnect = FindButton("Button_Connect");
|
||||
inputLobbyCode = EnsureInput(inputLobbyCode, "Input_LobbyCode");
|
||||
btnConnect = EnsureButton(btnConnect, "Button_Connect");
|
||||
|
||||
ddMaxPlayers = FindDropdown("Dropdown_MaxPlayers");
|
||||
tgPublicLobby = FindToggle("Toggle_PublicLobby");
|
||||
btnCreateLobby = FindButton("Button_CreateLobby");
|
||||
ddMaxPlayers = EnsureDropdown(ddMaxPlayers, "Dropdown_MaxPlayers");
|
||||
tgPublicLobby = EnsureToggle(tgPublicLobby, "Toggle_PublicLobby");
|
||||
btnCreateLobby = EnsureButton(btnCreateLobby, "Button_CreateLobby");
|
||||
|
||||
textPlayerCount = FindText("Text_PlayerCount");
|
||||
scrollPlayers = FindScroll("Scroll_Players");
|
||||
contentPlayers = FindAnyGO("Content_PlayersList")?.transform;
|
||||
emptyPlayers = FindAnyGO("Empty_Players");
|
||||
playerItemTemplate = FindAnyGO("PlayerItemTemplate");
|
||||
textPlayerCount = EnsureText(textPlayerCount, "Text_PlayerCount");
|
||||
scrollPlayers = EnsureScroll(scrollPlayers, "Scroll_Players");
|
||||
contentPlayers = EnsureTransform(contentPlayers, "Content_PlayersList");
|
||||
emptyPlayers = EnsureGO(emptyPlayers, "Empty_Players");
|
||||
playerItemTemplate = EnsureGO(playerItemTemplate, "PlayerItemTemplate");
|
||||
|
||||
btnInviteFriends = FindButton("Button_InviteFriends");
|
||||
btnKickSelected = FindButton("Button_KickSelected");
|
||||
btnInviteFriends = EnsureButton(btnInviteFriends, "Button_InviteFriends");
|
||||
btnKickSelected = EnsureButton(btnKickSelected, "Button_KickSelected");
|
||||
|
||||
btnToggleReady = FindButton("Button_ToggleReady");
|
||||
btnStartGame = FindButton("Button_StartGame");
|
||||
btnLeaveLobby = FindButton("Button_LeaveLobby");
|
||||
btnBackFromLobby = FindButton("Button_BackFromLobby");
|
||||
btnToggleReady = EnsureButton(btnToggleReady, "Button_ToggleReady");
|
||||
btnStartGame = EnsureButton(btnStartGame, "Button_StartGame");
|
||||
btnLeaveLobby = EnsureButton(btnLeaveLobby, "Button_LeaveLobby");
|
||||
btnBackFromLobby = EnsureButton(btnBackFromLobby, "Button_BackFromLobby");
|
||||
|
||||
// Friends picker
|
||||
panelFriends = FindAnyGO("Panel_Friends");
|
||||
contentFriends = FindAnyGO("Content_FriendsList")?.transform;
|
||||
emptyFriends = FindAnyGO("Empty_Friends");
|
||||
btnBackFromFriends = FindButton("Button_BackFromFriends");
|
||||
btnCloseFriendsOverlay = FindButton("Button_CloseFriendsOverlay");
|
||||
panelFriends = EnsureGO(panelFriends, "Panel_Friends");
|
||||
contentFriends = EnsureTransform(contentFriends, "Content_FriendsList");
|
||||
emptyFriends = EnsureGO(emptyFriends, "Empty_Friends");
|
||||
btnBackFromFriends = EnsureButton(btnBackFromFriends, "Button_BackFromFriends");
|
||||
btnCloseFriendsOverlay = EnsureButton(btnCloseFriendsOverlay, "Button_CloseFriendsOverlay");
|
||||
|
||||
EnsureSteamServices();
|
||||
RegisterSteamEvents();
|
||||
@@ -321,12 +322,78 @@ namespace MegaKoop.UI
|
||||
panelLobbyRef = root;
|
||||
}
|
||||
|
||||
private TMP_Text FindText(string name) => FindAnyComponent<TMP_Text>(name);
|
||||
private Button FindButton(string name) => FindAnyComponent<Button>(name);
|
||||
private Toggle FindToggle(string name) => FindAnyComponent<Toggle>(name);
|
||||
private TMP_Dropdown FindDropdown(string name) => FindAnyComponent<TMP_Dropdown>(name);
|
||||
private TMP_InputField FindInput(string name) => FindAnyComponent<TMP_InputField>(name);
|
||||
private ScrollRect FindScroll(string name) => FindAnyComponent<ScrollRect>(name);
|
||||
public void SetHostJoinGroups(GameObject hostGroup, GameObject joinGroup)
|
||||
{
|
||||
groupHost = hostGroup;
|
||||
groupJoin = joinGroup;
|
||||
}
|
||||
|
||||
public void SetHeaderControls(TMP_Text status, TMP_Text lobbyCode, Button copyCode)
|
||||
{
|
||||
textStatus = status;
|
||||
textLobbyCodeValue = lobbyCode;
|
||||
btnCopyCode = copyCode;
|
||||
}
|
||||
|
||||
public void SetTabButtons(Button hostTab, Button joinTab)
|
||||
{
|
||||
btnHostTab = hostTab;
|
||||
btnJoinTab = joinTab;
|
||||
}
|
||||
|
||||
public void SetJoinSection(TMP_InputField lobbyCodeInput, Button connectButton)
|
||||
{
|
||||
inputLobbyCode = lobbyCodeInput;
|
||||
btnConnect = connectButton;
|
||||
}
|
||||
|
||||
public void SetHostSection(TMP_Dropdown maxPlayersDropdown, Toggle publicToggle, Button createLobbyButton)
|
||||
{
|
||||
ddMaxPlayers = maxPlayersDropdown;
|
||||
tgPublicLobby = publicToggle;
|
||||
btnCreateLobby = createLobbyButton;
|
||||
}
|
||||
|
||||
public void SetPlayersList(TMP_Text playerCountText, ScrollRect playersScroll, Transform playersContent, GameObject itemTemplate, GameObject emptyState)
|
||||
{
|
||||
textPlayerCount = playerCountText;
|
||||
scrollPlayers = playersScroll;
|
||||
contentPlayers = playersContent;
|
||||
playerItemTemplate = itemTemplate;
|
||||
emptyPlayers = emptyState;
|
||||
}
|
||||
|
||||
public void SetFriendsPicker(GameObject friendsPanel, Transform friendsContent, GameObject friendsEmpty, Button backButton, Button closeOverlayButton)
|
||||
{
|
||||
panelFriends = friendsPanel;
|
||||
contentFriends = friendsContent;
|
||||
emptyFriends = friendsEmpty;
|
||||
btnBackFromFriends = backButton;
|
||||
btnCloseFriendsOverlay = closeOverlayButton;
|
||||
}
|
||||
|
||||
public void SetHostControls(Button inviteFriendsButton, Button kickSelectedButton)
|
||||
{
|
||||
btnInviteFriends = inviteFriendsButton;
|
||||
btnKickSelected = kickSelectedButton;
|
||||
}
|
||||
|
||||
public void SetFooterControls(Button toggleReadyButton, Button startGameButton, Button leaveLobbyButton, Button backButton)
|
||||
{
|
||||
btnToggleReady = toggleReadyButton;
|
||||
btnStartGame = startGameButton;
|
||||
btnLeaveLobby = leaveLobbyButton;
|
||||
btnBackFromLobby = backButton;
|
||||
}
|
||||
|
||||
private TMP_Text EnsureText(TMP_Text existing, string name) => existing ? existing : FindAnyComponent<TMP_Text>(name);
|
||||
private Button EnsureButton(Button existing, string name) => existing ? existing : FindAnyComponent<Button>(name);
|
||||
private Toggle EnsureToggle(Toggle existing, string name) => existing ? existing : FindAnyComponent<Toggle>(name);
|
||||
private TMP_Dropdown EnsureDropdown(TMP_Dropdown existing, string name) => existing ? existing : FindAnyComponent<TMP_Dropdown>(name);
|
||||
private TMP_InputField EnsureInput(TMP_InputField existing, string name) => existing ? existing : FindAnyComponent<TMP_InputField>(name);
|
||||
private ScrollRect EnsureScroll(ScrollRect existing, string name) => existing ? existing : FindAnyComponent<ScrollRect>(name);
|
||||
private Transform EnsureTransform(Transform existing, string name) => existing ? existing : FindAnyGO(name)?.transform;
|
||||
private GameObject EnsureGO(GameObject existing, string name) => existing ? existing : FindAnyGO(name);
|
||||
|
||||
#region Steam
|
||||
private void EnsureSteamServices()
|
||||
@@ -456,8 +523,9 @@ namespace MegaKoop.UI
|
||||
memberReadyCache.Clear();
|
||||
UpdateUIFromSteam();
|
||||
// Auto-open invite overlay for the host
|
||||
if (steam != null && steam.IsInLobby && steam.IsHost)
|
||||
if (inviteOverlayRequested && steam != null && steam.IsInLobby && steam.IsHost)
|
||||
{
|
||||
inviteOverlayRequested = false;
|
||||
steam.InviteFriends();
|
||||
if (!steam.IsOverlayEnabled()) ShowFriendsPanel();
|
||||
}
|
||||
@@ -469,8 +537,9 @@ namespace MegaKoop.UI
|
||||
memberReadyCache.Clear();
|
||||
UpdateUIFromSteam();
|
||||
// Auto-open invite overlay if we are the host entering our lobby
|
||||
if (steam != null && steam.IsInLobby && steam.IsHost)
|
||||
if (inviteOverlayRequested && steam != null && steam.IsInLobby && steam.IsHost)
|
||||
{
|
||||
inviteOverlayRequested = false;
|
||||
steam.InviteFriends();
|
||||
if (!steam.IsOverlayEnabled()) ShowFriendsPanel();
|
||||
}
|
||||
@@ -481,6 +550,7 @@ namespace MegaKoop.UI
|
||||
selectedPlayerSteamId = string.Empty;
|
||||
memberReadyCache.Clear();
|
||||
UpdateUIFromSteam();
|
||||
inviteOverlayRequested = false;
|
||||
}
|
||||
|
||||
private void HandleLobbyCreatedSync()
|
||||
@@ -579,6 +649,7 @@ namespace MegaKoop.UI
|
||||
if (!IsInLobby)
|
||||
{
|
||||
// Create a lobby first; overlay will auto-open in callbacks
|
||||
inviteOverlayRequested = true;
|
||||
CreateLobby();
|
||||
}
|
||||
else
|
||||
|
||||
17703
UI/UI_Canvas 1.prefab
Normal file
17703
UI/UI_Canvas 1.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
UI/UI_Canvas 1.prefab.meta
Normal file
7
UI/UI_Canvas 1.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd82d2a29e7d6074384455d591a597e8
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17162
UI/UI_Canvas.prefab
Normal file
17162
UI/UI_Canvas.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
UI/UI_Canvas.prefab.meta
Normal file
7
UI/UI_Canvas.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f73add37dd781d47af917c56220d19b
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17122
UI/UI_Canvas_low_Fix.prefab
Normal file
17122
UI/UI_Canvas_low_Fix.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
UI/UI_Canvas_low_Fix.prefab.meta
Normal file
7
UI/UI_Canvas_low_Fix.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 440f89caf615ada4aa0202b06d7586fe
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user