Added the support for the conjure gamepad
This commit is contained in:
parent
6b53e212d5
commit
21076df932
55
.vscode/settings.json
vendored
Normal file
55
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"files.exclude":
|
||||
{
|
||||
"**/.DS_Store":true,
|
||||
"**/.git":true,
|
||||
"**/.gitmodules":true,
|
||||
"**/*.booproj":true,
|
||||
"**/*.pidb":true,
|
||||
"**/*.suo":true,
|
||||
"**/*.user":true,
|
||||
"**/*.userprefs":true,
|
||||
"**/*.unityproj":true,
|
||||
"**/*.dll":true,
|
||||
"**/*.exe":true,
|
||||
"**/*.pdf":true,
|
||||
"**/*.mid":true,
|
||||
"**/*.midi":true,
|
||||
"**/*.wav":true,
|
||||
"**/*.gif":true,
|
||||
"**/*.ico":true,
|
||||
"**/*.jpg":true,
|
||||
"**/*.jpeg":true,
|
||||
"**/*.png":true,
|
||||
"**/*.psd":true,
|
||||
"**/*.tga":true,
|
||||
"**/*.tif":true,
|
||||
"**/*.tiff":true,
|
||||
"**/*.3ds":true,
|
||||
"**/*.3DS":true,
|
||||
"**/*.fbx":true,
|
||||
"**/*.FBX":true,
|
||||
"**/*.lxo":true,
|
||||
"**/*.LXO":true,
|
||||
"**/*.ma":true,
|
||||
"**/*.MA":true,
|
||||
"**/*.obj":true,
|
||||
"**/*.OBJ":true,
|
||||
"**/*.asset":true,
|
||||
"**/*.cubemap":true,
|
||||
"**/*.flare":true,
|
||||
"**/*.mat":true,
|
||||
"**/*.meta":true,
|
||||
"**/*.prefab":true,
|
||||
"**/*.unity":true,
|
||||
"build/":true,
|
||||
"Build/":true,
|
||||
"Library/":true,
|
||||
"library/":true,
|
||||
"obj/":true,
|
||||
"Obj/":true,
|
||||
"ProjectSettings/":true,
|
||||
"temp/":true,
|
||||
"Temp/":true
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc355dd4cf1e6173beaeb22c2858cbe1
|
||||
timeCreated: 1488828285
|
||||
guid: df1387ab23758dd4f9e36ec1aab17005
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f597f19f656ba56eae4f6a3a7cc528f4
|
||||
timeCreated: 1488828285
|
||||
guid: d4c9b5af1f2acb5498e569269f0c75c4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/ConjureOS/Scripts/ArcadeMenu.meta
Normal file
3
Assets/ConjureOS/Scripts/ArcadeMenu.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21d4daaf24a1497b942bb1c26aaad40b
|
||||
timeCreated: 1697466850
|
||||
93
Assets/ConjureOS/Scripts/ArcadeMenu/ConjureArcadeMenu.cs
Normal file
93
Assets/ConjureOS/Scripts/ArcadeMenu/ConjureArcadeMenu.cs
Normal file
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using ConjureOS.Input;
|
||||
|
||||
namespace ConjureOS.ArcadeMenu
|
||||
{
|
||||
public class ConjureArcadeMenu : MonoBehaviour
|
||||
{
|
||||
public event Action OnOpen;
|
||||
|
||||
#if !ENABLE_INPUT_SYSTEM && ENABLE_LEGACY_INPUT_MANAGER
|
||||
[SerializeField]
|
||||
private string homeButton = "Home";
|
||||
#endif
|
||||
|
||||
public bool IsOpened { get; private set; } = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
#if !ENABLE_INPUT_SYSTEM && ENABLE_LEGACY_INPUT_MANAGER
|
||||
if (!IsButtonAvailable(homeButton))
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"ConjureOS: {nameof(homeButton)} in {nameof(ConjureArcadeMenu)} must be a valid action name ('{homeButton}' is not set up). " +
|
||||
"To modify actions, go to 'Edit > Project Settings > Input Manager'.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !ENABLE_INPUT_SYSTEM && ENABLE_LEGACY_INPUT_MANAGER
|
||||
private bool IsButtonAvailable(string buttonName)
|
||||
{
|
||||
try
|
||||
{
|
||||
UnityEngine.Input.GetButton(buttonName);
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool WasButtonPressedThisFrame(string buttonName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return UnityEngine.Input.GetButtonDown(buttonName);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void Update()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
foreach (ConjureArcadeController arcadeController in ConjureArcadeController.allControllers)
|
||||
{
|
||||
if (arcadeController.home.wasPressedThisFrame)
|
||||
{
|
||||
OpenArcadeMenu();
|
||||
}
|
||||
}
|
||||
#elif ENABLE_LEGACY_INPUT_MANAGER
|
||||
if (WasButtonPressedThisFrame(homeButton))
|
||||
{
|
||||
OpenArcadeMenu();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OpenArcadeMenu()
|
||||
{
|
||||
if (IsOpened)
|
||||
{
|
||||
return;
|
||||
}
|
||||
IsOpened = true;
|
||||
|
||||
// This will eventually open the arcade menu.
|
||||
// However, for now, it will only close the game.
|
||||
OnOpen?.Invoke();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
#endif
|
||||
Application.Quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42abcca807f2495aa5d59ff8d0570ed6
|
||||
timeCreated: 1697466858
|
||||
@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48e08dc33330d11e9d4a1b246c52e4f6
|
||||
timeCreated: 1488828285
|
||||
guid: c2ef9ab0502fe5b4b981fc372678110e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/ConjureOS/Scripts/CustomWindow/ConjureArcadeGUI.cs
Normal file
34
Assets/ConjureOS/Scripts/CustomWindow/ConjureArcadeGUI.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace ConjureOS.CustomWindow
|
||||
{
|
||||
public class ConjureArcadeGUI
|
||||
{
|
||||
public struct Style
|
||||
{
|
||||
public const int UniformPadding = 10;
|
||||
public const int TextSizeError = 10;
|
||||
public readonly static Color32 ColorError = new Color(0.84f, 0.19f, 0.19f);
|
||||
public readonly static Color32 ColorSuccess = new Color(0.19f, 0.84f, 0.35f);
|
||||
|
||||
public static GUIStyle ErrorStyle = GenerateGUIStyle(ColorError);
|
||||
public static GUIStyle SuccessStyle = GenerateGUIStyle(ColorSuccess);
|
||||
|
||||
private static GUIStyle GenerateGUIStyle(Color32 color)
|
||||
{
|
||||
GUIStyle errorStyle = new GUIStyle();
|
||||
errorStyle.normal.textColor = color;
|
||||
errorStyle.fontSize = TextSizeError;
|
||||
errorStyle.wordWrap = true;
|
||||
|
||||
return errorStyle;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Message
|
||||
{
|
||||
public const string MetadataFailedMessage = "{0} error{1} have been detected.";
|
||||
public const string MetadataConfirmedMessage = "No errors detected. The game is ready to be published.";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ccef78ea2487524fb2c803e16661a6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,25 @@
|
||||
#if UNITY_EDITOR
|
||||
using ConjureOS.MetadataWindow;
|
||||
using ConjureOS.UploaderWindow;
|
||||
using UnityEditor;
|
||||
|
||||
namespace ConjureOS.CustomWindow
|
||||
{
|
||||
public class ConjureArcadeMenuItem
|
||||
{
|
||||
private const string MenuName = "Conjure Arcade/";
|
||||
|
||||
[MenuItem(MenuName + "Game Metadata Editor")]
|
||||
private static void OpenGameMetadataWindow()
|
||||
{
|
||||
EditorWindow.GetWindow(typeof(ConjureArcadeMetadataWindow));
|
||||
}
|
||||
|
||||
[MenuItem(MenuName + "Upload Game")]
|
||||
private static void OpenUploadGameWindow()
|
||||
{
|
||||
EditorWindow.GetWindow(typeof(ConjureArcadeGameUploaderWindow));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35055e949c56f364fb3146744c04237c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/ConjureOS/Scripts/GlobalObject.meta
Normal file
3
Assets/ConjureOS/Scripts/GlobalObject.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6700d94db788419897417a8bed51208a
|
||||
timeCreated: 1697466157
|
||||
@ -0,0 +1,57 @@
|
||||
using ConjureOS.ArcadeMenu;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace ConjureOS.GlobalObject
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoad]
|
||||
#endif
|
||||
public static class ConjureGlobalObjectInitializer
|
||||
{
|
||||
public const string GlobalObjectName = "ConjureGlobalObject";
|
||||
public static readonly System.Type[] GlobalObjectComponentTypes =
|
||||
{
|
||||
typeof(ConjureArcadeMenu)
|
||||
};
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static ConjureGlobalObjectInitializer()
|
||||
{
|
||||
InitializeGlobalObject();
|
||||
}
|
||||
#endif
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
||||
private static void InitializeGlobalObject()
|
||||
{
|
||||
GameObject globalObject = GameObject.Find(GlobalObjectName);
|
||||
if (!globalObject)
|
||||
{
|
||||
globalObject = new GameObject(GlobalObjectName);
|
||||
}
|
||||
InitializeComponentsOnGlobalObject(globalObject);
|
||||
}
|
||||
|
||||
private static void InitializeComponentsOnGlobalObject(GameObject globalObject)
|
||||
{
|
||||
foreach (var globalObjectComponentType in GlobalObjectComponentTypes)
|
||||
{
|
||||
if (globalObject.GetComponent(globalObjectComponentType))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!globalObjectComponentType.IsSubclassOf(typeof(MonoBehaviour)))
|
||||
{
|
||||
Debug.LogError($"ConjureOS: Cannot add component '{nameof(globalObjectComponentType.FullName)}' to global object because it is not a component.");
|
||||
continue;
|
||||
}
|
||||
|
||||
globalObject.AddComponent(globalObjectComponentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 039be1ac3aad4e8ebe52affd281ad81c
|
||||
timeCreated: 1697466243
|
||||
@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed09910c0094cb27be8f3ca264680da3
|
||||
timeCreated: 1488828285
|
||||
guid: 86ca34d4ff4ff724c962255b02e88d47
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
135
Assets/ConjureOS/Scripts/Input/ConjureArcadeController.cs
Normal file
135
Assets/ConjureOS/Scripts/Input/ConjureArcadeController.cs
Normal file
@ -0,0 +1,135 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable ClassNeverInstantiated.Global
|
||||
// Reason: It's normal that some stuff is not used here because this is meant to be used as a library.
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
// Reason: According to our code guidelines, property should be UpperCamelCase.
|
||||
// However, to be consistent with other input devices in Unity (e.g. Joystick, Gamepad) we will use lowerCamelCase here.
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
[InputControlLayout(stateType = typeof(ConjureArcadeControllerState), displayName = "Conjure Arcade Controller")]
|
||||
public class ConjureArcadeController : InputDevice
|
||||
{
|
||||
public static event Action<ConjureArcadeController> OnControllerAdded;
|
||||
public static event Action<ConjureArcadeController> OnControllerRemoved;
|
||||
|
||||
public ConjureArcadeStickControl stick { get; protected set; }
|
||||
|
||||
public ButtonControl home { get; protected set; }
|
||||
public ButtonControl start { get; protected set; }
|
||||
|
||||
public ButtonControl button1 { get; protected set; }
|
||||
public ButtonControl button2 { get; protected set; }
|
||||
public ButtonControl button3 { get; protected set; }
|
||||
|
||||
public ButtonControl buttonA { get; protected set; }
|
||||
public ButtonControl buttonB { get; protected set; }
|
||||
public ButtonControl buttonC { get; protected set; }
|
||||
|
||||
public static ConjureArcadeController current { get; private set; }
|
||||
public static ConjureArcadeController[] allControllers => allInstances.ToArray();
|
||||
public static int ControllerCount => count;
|
||||
|
||||
/// <summary>
|
||||
/// The controller index of this specific Conjure Arcade Controller.
|
||||
/// The value will be between 0 and <see cref="ControllerCount"/> - 1.
|
||||
/// If the value is -1, it means this controller was not initialized correctly and is not valid.
|
||||
/// </summary>
|
||||
public int ControllerIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return allInstances.IndexOf(this);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a Conjure Arcade Controller exist for the following index.
|
||||
/// </summary>
|
||||
public static bool ExistForIndex(int controllerIndex)
|
||||
{
|
||||
return allInstances.Exists(instance => instance.ControllerIndex == controllerIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Conjure Arcade Controller associated with the specific controller index.
|
||||
/// </summary>
|
||||
/// <returns>The controller if it exist for the specific index or null if it does not exist.</returns>
|
||||
public static ConjureArcadeController GetForIndex(int controllerIndex)
|
||||
{
|
||||
return allInstances.Find(instance => instance.ControllerIndex == controllerIndex);
|
||||
}
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
stick = GetChildControl<ConjureArcadeStickControl>("stick");
|
||||
|
||||
home = GetChildControl<ButtonControl>("home");
|
||||
start = GetChildControl<ButtonControl>("start");
|
||||
|
||||
button1 = GetChildControl<ButtonControl>("button1");
|
||||
button2 = GetChildControl<ButtonControl>("button2");
|
||||
button3 = GetChildControl<ButtonControl>("button3");
|
||||
|
||||
buttonA = GetChildControl<ButtonControl>("buttonA");
|
||||
buttonB = GetChildControl<ButtonControl>("buttonB");
|
||||
buttonC = GetChildControl<ButtonControl>("buttonC");
|
||||
|
||||
base.FinishSetup();
|
||||
}
|
||||
|
||||
public override void MakeCurrent()
|
||||
{
|
||||
base.MakeCurrent();
|
||||
current = this;
|
||||
}
|
||||
|
||||
protected override void OnAdded()
|
||||
{
|
||||
base.OnAdded();
|
||||
|
||||
if (!allInstances.Contains(this))
|
||||
{
|
||||
allInstances.Add(this);
|
||||
++count;
|
||||
OnControllerAdded?.Invoke(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnRemoved()
|
||||
{
|
||||
if (current == this)
|
||||
{
|
||||
current = null;
|
||||
}
|
||||
|
||||
if (allInstances.Remove(this))
|
||||
{
|
||||
--count;
|
||||
OnControllerRemoved?.Invoke(this);
|
||||
}
|
||||
|
||||
base.OnRemoved();
|
||||
}
|
||||
|
||||
private static int count;
|
||||
private static readonly List<ConjureArcadeController> allInstances = new();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84cdd6b6829c4f5e9e31a78f96d5b9b8
|
||||
timeCreated: 1695757344
|
||||
@ -0,0 +1,31 @@
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
public static class ConjureArcadeControllerInfo
|
||||
{
|
||||
// The information in this class will need to change if we change the way the controller is made.
|
||||
// Everything in this class needs to be static since it is used at compile time to setup the Conjure Arcade Controller state description.
|
||||
|
||||
public const string Interface = "HID";
|
||||
public const string Product = "Generic USB Joystick "; // The extra spaces are normal as they are part of the product name created by the board's vendor
|
||||
|
||||
public const int StateSizeInBytes = 8;
|
||||
public const int ReportIdByte = 0;
|
||||
public const int StickXByte = 1;
|
||||
public const int StickYByte = 1;
|
||||
public const int ButtonByte = 7;
|
||||
|
||||
public enum ButtonBit : uint
|
||||
{
|
||||
Home = 0,
|
||||
Start = 1,
|
||||
|
||||
One = 2,
|
||||
Two = 3,
|
||||
Three = 4,
|
||||
|
||||
A = 5,
|
||||
B = 6,
|
||||
C = 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e67d24a4d1184f43933bdd96b2720cbd
|
||||
timeCreated: 1695758710
|
||||
@ -0,0 +1,53 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
// Reason: This is a configuration class with specific requirements for its interface.
|
||||
|
||||
// ReSharper disable StringLiteralTypo
|
||||
// ReSharper disable CommentTypo
|
||||
// Reason: SHRT is not a typo in this case.
|
||||
|
||||
// Inspired by: https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/HID.html
|
||||
// This class describes the data received by the controller in a way that can be read by the new input system.
|
||||
// If the physical controller ever changes, this class will need to be reworked.
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Size = ConjureArcadeControllerInfo.StateSizeInBytes)]
|
||||
public struct ConjureArcadeControllerState : IInputStateTypeInfo
|
||||
{
|
||||
public FourCC format => new FourCC('H', 'I', 'D');
|
||||
|
||||
[FieldOffset(ConjureArcadeControllerInfo.ReportIdByte)]
|
||||
public byte reportId;
|
||||
|
||||
[InputControl(name = "stick", layout = "ConjureArcadeStick", format = "VC2B", displayName = "Stick", processors = "ConjureArcadeVector2(minX=0.0, maxX=1.0, minY=0.0, maxY=1.0, invertY)")]
|
||||
[InputControl(name = "stick/x", offset = 0, format = "BYTE", parameters = "clamp=false, invert=false, normalize=false")]
|
||||
[InputControl(name = "stick/left", offset = 0, format = "BYTE")]
|
||||
[InputControl(name = "stick/right", offset = 0, format = "BYTE")]
|
||||
[InputControl(name = "stick/y", offset = 1, format = "BYTE", parameters = "clamp=false, invert=false, normalize=false")]
|
||||
[InputControl(name = "stick/up", offset = 1, format = "BYTE")]
|
||||
[InputControl(name = "stick/down", offset = 1, format = "BYTE")]
|
||||
[FieldOffset(ConjureArcadeControllerInfo.StickXByte)]
|
||||
public byte stickX;
|
||||
[FieldOffset(ConjureArcadeControllerInfo.StickYByte)]
|
||||
public byte stickY;
|
||||
|
||||
[InputControl(name = "home", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Home, displayName = "Home")]
|
||||
[InputControl(name = "start", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Start, displayName = "Start")]
|
||||
[InputControl(name = "button1", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.One, displayName = "Button 1", shortDisplayName = "1")]
|
||||
[InputControl(name = "button2", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Two, displayName = "Button 2", shortDisplayName = "2")]
|
||||
[InputControl(name = "button3", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.Three, displayName = "Button 3", shortDisplayName = "3")]
|
||||
[InputControl(name = "buttonA", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.A, displayName = "Button A", shortDisplayName = "A")]
|
||||
[InputControl(name = "buttonB", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.B, displayName = "Button B", shortDisplayName = "B")]
|
||||
[InputControl(name = "buttonC", layout = "Button", bit = (uint) ConjureArcadeControllerInfo.ButtonBit.C, displayName = "Button C", shortDisplayName = "C")]
|
||||
[FieldOffset(ConjureArcadeControllerInfo.ButtonByte)]
|
||||
public byte buttons;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c07dbb7bcebd4245be59b93c86cee5fd
|
||||
timeCreated: 1695758555
|
||||
46
Assets/ConjureOS/Scripts/Input/ConjureArcadeStickControl.cs
Normal file
46
Assets/ConjureOS/Scripts/Input/ConjureArcadeStickControl.cs
Normal file
@ -0,0 +1,46 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem.Controls;
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
// ReSharper disable ClassNeverInstantiated.Global
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// Reason: It's normal that some stuff is not used here because this is meant to be used as a library.
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
// Reason: According to our code guidelines, property should be UpperCamelCase.
|
||||
// However, to be consistent with other input controls in Unity (e.g. StickControl) we will use lowerCamelCase here.
|
||||
|
||||
// This class exists to allow the Conjure arcade stick input to work with the input system.
|
||||
// It uses the ConjureArcadeValue processor in order to define the down/left/right/up buttons.
|
||||
// It is registered in when ConjureInputSystem is initialized and is used for the stick input in the controller state.
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
public class ConjureArcadeStickControl : Vector2Control
|
||||
{
|
||||
[InputControl(useStateFrom = "y", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", synthetic = true, displayName = "Up")]
|
||||
[InputControl(name = "x", minValue = -1f, maxValue = 1f, layout = "Axis", processors = "ConjureArcadeValue(min=0.0, max=1.0)", format = "BYTE", sizeInBits = 8)]
|
||||
[InputControl(name = "y", minValue = -1f, maxValue = 1f, layout = "Axis", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", format ="BYTE", sizeInBits = 8, offset = 1)]
|
||||
public ButtonControl up { get; set; }
|
||||
|
||||
[InputControl(useStateFrom = "y" , processors = "ConjureArcadeValue(min=0.0, max=1.0)", synthetic = true, displayName = "Down")]
|
||||
public ButtonControl down { get; set; }
|
||||
|
||||
[InputControl(useStateFrom = "x", processors = "ConjureArcadeValue(min=0.0, max=1.0, invert)", synthetic = true, displayName = "Left")]
|
||||
public ButtonControl left { get; set; }
|
||||
|
||||
[InputControl(useStateFrom = "x", processors = "ConjureArcadeValue(min=0.0, max=1.0)", synthetic = true, displayName = "Right")]
|
||||
public ButtonControl right { get; set; }
|
||||
|
||||
protected override void FinishSetup()
|
||||
{
|
||||
base.FinishSetup();
|
||||
up = GetChildControl<ButtonControl>("up");
|
||||
down = GetChildControl<ButtonControl>("down");
|
||||
left = GetChildControl<ButtonControl>("left");
|
||||
right = GetChildControl<ButtonControl>("right");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef8fe9c76d3e4dcda92b275b68348e8e
|
||||
timeCreated: 1695780776
|
||||
@ -0,0 +1,79 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
// ReSharper disable ConvertToConstant.Local
|
||||
// Reason: Attributes cannot be made into constants here since they are changed by Unity's internal input system.
|
||||
|
||||
// Those classes exist to allow the conversion of the stick input into a normalized (-1.0, 1.0) range.
|
||||
// They are registered when ConjureInputSystem is initialized and are used for stick inputs in the controller state and the stick control.
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class ConjureArcadeVector2Processor : InputProcessor<Vector2>
|
||||
{
|
||||
private readonly float minX = -1.0f;
|
||||
private readonly float maxX = 1.0f;
|
||||
private readonly bool invertX = false;
|
||||
|
||||
private readonly float minY = -1.0f;
|
||||
private readonly float maxY = 1.0f;
|
||||
private readonly bool invertY = false;
|
||||
|
||||
private readonly float deadZone = 0.1f;
|
||||
|
||||
public override Vector2 Process(Vector2 value, InputControl control)
|
||||
{
|
||||
return new Vector2(
|
||||
ConjureArcadeStickProcessorHelper.ProcessValue(value.x, minX, maxX, deadZone, invertX),
|
||||
ConjureArcadeStickProcessorHelper.ProcessValue(value.y, minY, maxY, deadZone, invertY));
|
||||
}
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public class ConjureArcadeValueProcessor : InputProcessor<float>
|
||||
{
|
||||
private readonly float min = -1.0f;
|
||||
private readonly float max = 1.0f;
|
||||
private readonly bool invert = false;
|
||||
|
||||
private readonly float deadZone = 0.1f;
|
||||
|
||||
public override float Process(float value, InputControl control)
|
||||
{
|
||||
return ConjureArcadeStickProcessorHelper.ProcessValue(value, min, max, deadZone, invert);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class ConjureArcadeStickProcessorHelper
|
||||
{
|
||||
private const float MinStickValue = -1.0f;
|
||||
private const float MaxStickValue = 1.0f;
|
||||
private const float StickRange = MaxStickValue - MinStickValue;
|
||||
|
||||
internal static float ProcessValue(float originalValue, float min, float max, float deadZone, bool invert)
|
||||
{
|
||||
float zero = (min + max) / 2;
|
||||
if (Mathf.Approximately(originalValue, zero))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float originalRange = max - min;
|
||||
if (Mathf.Approximately(originalRange, 0.0f))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float processedValue = (((originalValue - min) * StickRange) / originalRange) + MinStickValue;
|
||||
processedValue = Mathf.Clamp(processedValue, MinStickValue, MaxStickValue);
|
||||
processedValue = invert ? -processedValue : processedValue;
|
||||
processedValue = processedValue > -deadZone && processedValue < deadZone ? 0.0f : processedValue;
|
||||
|
||||
return processedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2261cfa8c104770bad23d12a5194f9c
|
||||
timeCreated: 1695774290
|
||||
38
Assets/ConjureOS/Scripts/Input/ConjureInputSystem.cs
Normal file
38
Assets/ConjureOS/Scripts/Input/ConjureInputSystem.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem.Layouts;
|
||||
using UnityEngine.InputSystem;
|
||||
#endif
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoad]
|
||||
#endif
|
||||
public static class ConjureInputSystem
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
static ConjureInputSystem()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSplashScreen)]
|
||||
private static void Initialize()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
InputSystem.RegisterProcessor(typeof(ConjureArcadeVector2Processor), "ConjureArcadeVector2");
|
||||
InputSystem.RegisterProcessor(typeof(ConjureArcadeValueProcessor), "ConjureArcadeValue");
|
||||
|
||||
InputSystem.RegisterLayout<ConjureArcadeStickControl>("ConjureArcadeStick");
|
||||
|
||||
InputSystem.RegisterLayout<ConjureArcadeController>(
|
||||
matches: new InputDeviceMatcher()
|
||||
.WithInterface(ConjureArcadeControllerInfo.Interface)
|
||||
.WithProduct(ConjureArcadeControllerInfo.Product));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4f9c6e992674c1bbcb497a7e194b0c6
|
||||
timeCreated: 1695755563
|
||||
109
Assets/ConjureOS/Scripts/Input/InputActionAssetExtension.cs
Normal file
109
Assets/ConjureOS/Scripts/Input/InputActionAssetExtension.cs
Normal file
@ -0,0 +1,109 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
// ReSharper disable InvalidXmlDocComment
|
||||
// Reason: We don't want to comment the "this" parameter in the extension functions.
|
||||
|
||||
namespace ConjureOS.Input
|
||||
{
|
||||
public static class InputActionAssetExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Assign a specific Conjure Arcade Controller to this Input Action Asset.
|
||||
/// All other Conjure Arcade Controllers will be disabled for this asset.
|
||||
/// If the controller cannot be found for the controller index, there will be no assigned Conjure Arcade Controller.
|
||||
/// </summary>
|
||||
/// <param name="keepOtherDevices">
|
||||
/// If this is false, all devices will be disabled for this Input Action Asset except for the Conjure Arcade Controller associated to the given controller index.
|
||||
/// If this is true, the devices that are not Conjure Arcade Controller (e.g. mouse/keyboard) will not be disabled.
|
||||
/// </param>
|
||||
public static void AssignConjureController(this InputActionAsset inputActionAsset, int controllerIndex, bool keepOtherDevices = true)
|
||||
{
|
||||
List<InputDevice> inputDevices = new List<InputDevice>();
|
||||
if (keepOtherDevices)
|
||||
{
|
||||
if (inputActionAsset.devices == null)
|
||||
{
|
||||
inputDevices.AddRange(InputSystem.devices);
|
||||
}
|
||||
else
|
||||
{
|
||||
inputDevices = new List<InputDevice>(inputActionAsset.devices);
|
||||
}
|
||||
|
||||
inputDevices.RemoveAll(inputDevice => inputDevice is ConjureArcadeController);
|
||||
}
|
||||
|
||||
ConjureArcadeController controller = ConjureArcadeController.GetForIndex(controllerIndex);
|
||||
if (controller != null)
|
||||
{
|
||||
inputDevices.Add(controller);
|
||||
}
|
||||
|
||||
inputActionAsset.devices = inputDevices.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not it is possible to assign a specific controller index to this Input Action Asset.
|
||||
/// </summary>
|
||||
public static bool CanAssignConjureController(this InputActionAsset inputActionAsset, int controllerIndex)
|
||||
{
|
||||
return ConjureArcadeController.ExistForIndex(controllerIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the controller index of the Conjure Arcade Controller associated with this Input Action Asset.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller index found.
|
||||
/// If there was no Conjure Arcade Controller associated with this Input Action Asset, return false.
|
||||
/// If there was multiple Conjure Arcade Controllers associated with this Input Action Asset, return the index of the first controller found.
|
||||
/// </returns>
|
||||
public static int GetConjureControllerIndex(this InputActionAsset inputActionAsset)
|
||||
{
|
||||
ConjureArcadeController[] controllers = GetConjureArcadeControllersFromDevices(inputActionAsset.devices);
|
||||
if (controllers.Length == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return controllers[0].ControllerIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the controller index of all the Conjure Arcade Controllers associated with this Input Action Asset.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller indexes found.
|
||||
/// If there was no Conjure Arcade Controller associated with this Input Action Asset, return an empty array.
|
||||
/// </returns>
|
||||
public static int[] GetConjureControllerIndexes(this InputActionAsset inputActionAsset)
|
||||
{
|
||||
ConjureArcadeController[] controllers = GetConjureArcadeControllersFromDevices(inputActionAsset.devices);
|
||||
return controllers.Select(controller => controller.ControllerIndex).ToArray();
|
||||
}
|
||||
|
||||
private static ConjureArcadeController[] GetConjureArcadeControllersFromDevices(ReadOnlyArray<InputDevice>? devices)
|
||||
{
|
||||
if (devices == null)
|
||||
{
|
||||
return ConjureArcadeController.allControllers;
|
||||
}
|
||||
|
||||
List<ConjureArcadeController> controllers = new List<ConjureArcadeController>();
|
||||
foreach (InputDevice inputDevice in devices)
|
||||
{
|
||||
if (inputDevice is ConjureArcadeController device)
|
||||
{
|
||||
controllers.Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
return controllers.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce5f252f61584da1be15a1aed6373337
|
||||
timeCreated: 1697552346
|
||||
8
Assets/ConjureOS/Scripts/MetadataWindow.meta
Normal file
8
Assets/ConjureOS/Scripts/MetadataWindow.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fb8b8a42abb6ff4aa3af61ff2fa57a6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,30 @@
|
||||
%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: 6977c269ceb8edc4298ee30193e8a838, type: 3}
|
||||
m_Name: ConjureArcadeMetadata
|
||||
m_EditorClassIdentifier:
|
||||
gameTitle: Overmelted
|
||||
version: 0.1.0
|
||||
description: An overcooked inspired game where you gotta work in team to smith
|
||||
weapons, tools and armors for you clients. The levels are quick and packed with
|
||||
action for up to two players
|
||||
minNumPlayer: 1
|
||||
maxNumPlayer: 2
|
||||
useLeaderboard: 0
|
||||
thumbnail: {fileID: 2800000, guid: 4082b7995fb3a974fb4b5853d98e37fb, type: 3}
|
||||
gameplayImage: {fileID: 2800000, guid: f77d9fb0ed4f7ad459db7c688a37d2f9, type: 3}
|
||||
developers:
|
||||
- Jimmy Tremblay-Bernier
|
||||
genres:
|
||||
- selectedGenre: 14
|
||||
- selectedGenre: 28
|
||||
id:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9cd8c3ac9c7ce34896c85d0fcd2aa5c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
118
Assets/ConjureOS/Scripts/MetadataWindow/ConjureArcadeMetadata.cs
Normal file
118
Assets/ConjureOS/Scripts/MetadataWindow/ConjureArcadeMetadata.cs
Normal file
@ -0,0 +1,118 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ConjureOS.MetadataWindow
|
||||
{
|
||||
[Serializable]
|
||||
public class ConjureArcadeMetadata : ScriptableObject
|
||||
{
|
||||
// Save location
|
||||
public const string MetadataAssetPath = "Assets/ConjureOS/Scripts/MetadataWindow/ConjureArcadeMetadata.asset";
|
||||
|
||||
// Properties Validation
|
||||
public const int GameTitleLimit = 100;
|
||||
public const int DescriptionLimit = 250;
|
||||
public const int DevelopersNameLimit = 100;
|
||||
public const int MaxSelectedGenres = 3;
|
||||
public const float MaxThumbnailFileSize = 1024; // In Kb
|
||||
public const float MaxGameplayImageFileSize = 1024; // In Kb
|
||||
public static readonly float[] RequiredThumbnailAR = { 16f, 9f }; // Aspect Ratio
|
||||
public static readonly float[] RequiredGameplayImageAR = { 1f, 1f }; // Aspect Ratio
|
||||
public static readonly string[] GenreOptions =
|
||||
{
|
||||
"Platformer", "Shooter", "Fighting", "Beat 'em up", "Stealth", "Survival",
|
||||
"Rhythm", "Horror", "Metroidvania", "Puzzle", "RPG", "Roguelike",
|
||||
"Simulation", "Strategy", "Action", "Adventure", "RTS", "MOBA",
|
||||
"Battle Royale", "Racing", "Sports", "Board", "Idle", "Trivia",
|
||||
"Art", "Educational", "Sandbox", "Open World", "Other"
|
||||
};
|
||||
|
||||
// Editable settings
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("The title of the game. Can't exceed 100 characters.")]
|
||||
private string gameTitle;
|
||||
public string GameTitle => gameTitle;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("Current version of the game. Must follow the format 'x.x.x' where x are either numbers or letters.")]
|
||||
private string version;
|
||||
public string Version => version;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[TextArea]
|
||||
[Tooltip("Small description of the game. Can't exceed 250 characters.")]
|
||||
private string description;
|
||||
public string Description => description;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("The minimum required number of players to play the game.")]
|
||||
private int minNumPlayer = 1;
|
||||
public int MinNumPlayer => minNumPlayer;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("The maximum required number of players to play the game.")]
|
||||
private int maxNumPlayer = 1;
|
||||
public int MaxNumPlayer => maxNumPlayer;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("Indicates if the game uses a leaderboard.")]
|
||||
private bool useLeaderboard;
|
||||
public bool UseLeaderboard => useLeaderboard;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("Thumbnail image of the game. Displayed in the game selection screen. The image format must be 16:9, and its size can't exceed 1 MB.")]
|
||||
private Texture2D thumbnail;
|
||||
public Texture2D Thumbnail => thumbnail;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("An image that shows what the game looks like. The image format must be 1:1, and its size can't exceed 1 MB.")]
|
||||
private Texture2D gameplayImage;
|
||||
public Texture2D GameplayImage => gameplayImage;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("The names of the game developers.")]
|
||||
private string[] developers;
|
||||
public string[] Developers => developers;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
[Tooltip("Genres associated with the game.")]
|
||||
private GameGenre[] genres;
|
||||
public GameGenre[] Genres => genres;
|
||||
|
||||
|
||||
// Uneditable settings
|
||||
[SerializeField, HideInInspector]
|
||||
private string id;
|
||||
public string Id => id;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private DateTime releaseDate;
|
||||
public DateTime ReleaseDate => releaseDate;
|
||||
|
||||
[SerializeField, HideInInspector]
|
||||
private DateTime lastGameUpdate;
|
||||
public DateTime LastGameUpdate => lastGameUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Updates all uneditable settings
|
||||
/// </summary>
|
||||
public void UpdateUneditableData()
|
||||
{
|
||||
// Generate GUID
|
||||
if (string.IsNullOrEmpty(id))
|
||||
{
|
||||
id = Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
// Generate dates
|
||||
if (releaseDate == DateTime.MinValue)
|
||||
{
|
||||
releaseDate = DateTime.Now;
|
||||
}
|
||||
|
||||
lastGameUpdate = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6977c269ceb8edc4298ee30193e8a838
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,292 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ConjureOS.MetadataWindow
|
||||
{
|
||||
public class ConjureArcadeMetadataValidator
|
||||
{
|
||||
// String errors
|
||||
private const string EmptyStringError = "Text field cannot be empty. ";
|
||||
private const string CharLimitExceededError = "The field should contain less than {0} characters. ";
|
||||
private const string VersionFormatError = "The version doesn't match the required format 'x.y.z'.";
|
||||
private const string DevelopersCharLimitExceedError = "One or more names exceed the maximum characters limit of {0}.";
|
||||
|
||||
// Min/max player errors
|
||||
private const string IncorrectPlayerValueError = "Incorrect value. The number of players can't be 0 or lower. ";
|
||||
private const string MinPlayerHigherThanMaxError = "Minimum number of players can't be higher than the maximum. ";
|
||||
private const string MaxPlayerLowerThanMinError = "Maximum number of players can't be lower than the minimum. ";
|
||||
|
||||
// Image errors
|
||||
private const string MissingImageError = "No image was selected. ";
|
||||
private const string InvalidAspectRatioError = "Invalid aspect ratio. Aspect ratio of the image should be {0}:{1}. ";
|
||||
private const string InvalidFileSizeError = "Invalid file size. File size should be lower than {0} MB. ";
|
||||
private const string InvalidImagePathError = "Invalid path. Chosen picture should be placed inside the 'Assets/' folder. ";
|
||||
|
||||
// Other errors
|
||||
private const string SameGenreSelectedMultipleTimeError = "Same genre is selected twice or more";
|
||||
|
||||
// Metadata error messages
|
||||
private string gameTitleErrorMessage = "";
|
||||
public string GameTitleErrorMessage => gameTitleErrorMessage;
|
||||
|
||||
private string versionErrorMessage = "";
|
||||
public string VersionErrorMessage => versionErrorMessage;
|
||||
|
||||
private string descriptionErrorMessage = "";
|
||||
public string DescriptionErrorMessage => descriptionErrorMessage;
|
||||
|
||||
private string developersErrorMessage = "";
|
||||
public string DevelopersErrorMessage => developersErrorMessage;
|
||||
|
||||
private string minNumPlayerErrorMessage = "";
|
||||
public string MinNumPlayerErrorMessage => minNumPlayerErrorMessage;
|
||||
|
||||
private string maxNumPlayerErrorMessage = "";
|
||||
public string MaxNumPlayerErrorMessage => maxNumPlayerErrorMessage;
|
||||
|
||||
private string thumbnailErrorMessage = "";
|
||||
public string ThumbnailErrorMessage => thumbnailErrorMessage;
|
||||
|
||||
private string gameplayImageErrorMessage = "";
|
||||
public string GameplayImageErrorMessage => gameplayImageErrorMessage;
|
||||
|
||||
private string genresErrorMessage = "";
|
||||
public string GenresErrorMessage => genresErrorMessage;
|
||||
|
||||
|
||||
private List<int> developersErrorIndex = new List<int>(); // Used to indicate which index have an error
|
||||
public List<int> DevelopersErrorIndex => developersErrorIndex;
|
||||
|
||||
private int errorCount = -1; // Starts at -1 because no validation have been done yet
|
||||
public int ErrorCount => errorCount;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validate the specified game metadata
|
||||
/// </summary>
|
||||
/// <param name="metadata">The metadata to be validated</param>
|
||||
/// <returns>Return true if metadata are valid. Otherwise, returns false.</returns>
|
||||
public bool ValidateMetadata(ConjureArcadeMetadata metadata)
|
||||
{
|
||||
errorCount = 0;
|
||||
|
||||
// Validate text fields
|
||||
ValidateTextField(metadata.GameTitle, ConjureArcadeMetadata.GameTitleLimit, out gameTitleErrorMessage);
|
||||
ValidateVersion(metadata.Version);
|
||||
ValidateTextField(metadata.Description, ConjureArcadeMetadata.DescriptionLimit, out descriptionErrorMessage);
|
||||
|
||||
// Validate player fields
|
||||
ValidateNumPlayerFields(metadata.MinNumPlayer, metadata.MaxNumPlayer);
|
||||
|
||||
// Validate image fields
|
||||
Texture2D thumbnailTexture = metadata.Thumbnail;
|
||||
ValidateImageField(thumbnailTexture, ConjureArcadeMetadata.RequiredThumbnailAR, ConjureArcadeMetadata.MaxThumbnailFileSize, out thumbnailErrorMessage);
|
||||
|
||||
Texture2D gameplayImageTexture = metadata.GameplayImage;
|
||||
ValidateImageField(gameplayImageTexture, ConjureArcadeMetadata.RequiredGameplayImageAR, ConjureArcadeMetadata.MaxGameplayImageFileSize, out gameplayImageErrorMessage);
|
||||
|
||||
// Other validations
|
||||
ValidateDevelopersList(metadata.Developers);
|
||||
ValidateGenresList(metadata.Genres);
|
||||
|
||||
return errorCount == 0;
|
||||
}
|
||||
|
||||
private void ValidateTextField(string text, int limit, out string outErrorMessage)
|
||||
{
|
||||
outErrorMessage = "";
|
||||
|
||||
// Check for empty string
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
outErrorMessage = EmptyStringError;
|
||||
errorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if string exceeds char limit
|
||||
if (limit > 0)
|
||||
{
|
||||
if (text.Length > limit)
|
||||
{
|
||||
outErrorMessage = string.Format(CharLimitExceededError, limit);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateVersion(string version)
|
||||
{
|
||||
versionErrorMessage = "";
|
||||
|
||||
// Required format is "x.y.z"
|
||||
Regex rx = new Regex(@"^[a-zA-Z0-9]+\.[a-zA-Z0-9]+\.[a-zA-Z-0-9]+$");
|
||||
var matches = rx.Match(version);
|
||||
if (!matches.Success)
|
||||
{
|
||||
versionErrorMessage += VersionFormatError;
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateNumPlayerFields(int minNumPlayer, int maxNumPlayer)
|
||||
{
|
||||
minNumPlayerErrorMessage = "";
|
||||
maxNumPlayerErrorMessage = "";
|
||||
|
||||
if (minNumPlayer <= 0)
|
||||
{
|
||||
minNumPlayerErrorMessage += IncorrectPlayerValueError;
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (maxNumPlayer <= 0)
|
||||
{
|
||||
maxNumPlayerErrorMessage += IncorrectPlayerValueError;
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
if (minNumPlayer > maxNumPlayer)
|
||||
{
|
||||
minNumPlayerErrorMessage += MinPlayerHigherThanMaxError;
|
||||
maxNumPlayerErrorMessage += MaxPlayerLowerThanMinError;
|
||||
errorCount += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateImageField(Texture2D image, float[] desiredRatio, float maxFileSize, out string outErrorMessage)
|
||||
{
|
||||
outErrorMessage = "";
|
||||
|
||||
if (image == null)
|
||||
{
|
||||
outErrorMessage += MissingImageError;
|
||||
errorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Verifying file size and aspect ratio
|
||||
string imageRelativePath = AssetDatabase.GetAssetPath(image);
|
||||
if (imageRelativePath.StartsWith("Assets/"))
|
||||
{
|
||||
// We check and remove "Assets" at the start of the relative path because
|
||||
// Application.dataPath already gives us the path to the assets folder
|
||||
string imageAbsolutePath = Application.dataPath + imageRelativePath.Substring(6);
|
||||
|
||||
long length = new System.IO.FileInfo(imageAbsolutePath).Length;
|
||||
if (length / 1024f > maxFileSize)
|
||||
{
|
||||
// File is bigger
|
||||
outErrorMessage += string.Format(InvalidFileSizeError, maxFileSize);
|
||||
errorCount++;
|
||||
}
|
||||
|
||||
// Verifying aspect ratio
|
||||
float delta = 0.00001f;
|
||||
float[] originalImageDimension = GetOriginalImageDimension(imageRelativePath);
|
||||
float ratioW = originalImageDimension[0] / desiredRatio[0];
|
||||
float ratioH = originalImageDimension[1] / desiredRatio[1];
|
||||
if (Mathf.Abs(ratioW - ratioH) > delta)
|
||||
{
|
||||
outErrorMessage += string.Format(InvalidAspectRatioError, desiredRatio[0], desiredRatio[1]);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Images should be located inside the Assets folder
|
||||
outErrorMessage += InvalidImagePathError;
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateGenresList(GameGenre[] genres)
|
||||
{
|
||||
genresErrorMessage = "";
|
||||
|
||||
// Check if a genre has been selected twice or more
|
||||
for (int i = 0; i < genres.Length - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < genres.Length; j++)
|
||||
{
|
||||
if (i == j)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (genres[i].selectedGenre == genres[j].selectedGenre)
|
||||
{
|
||||
genresErrorMessage += SameGenreSelectedMultipleTimeError;
|
||||
errorCount++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float[] GetOriginalImageDimension(string assetPath)
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
|
||||
if (importer != null)
|
||||
{
|
||||
object[] args = new object[2] { 0, 0 };
|
||||
MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
mi.Invoke(importer, args);
|
||||
|
||||
width = (int)args[0];
|
||||
height = (int)args[1];
|
||||
}
|
||||
|
||||
return new float[] { width, height };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate a developers list
|
||||
/// </summary>
|
||||
/// <param name="developers">The developers list to be analyzed</param>
|
||||
public void ValidateDevelopersList(string[] developers)
|
||||
{
|
||||
developersErrorIndex.Clear();
|
||||
developersErrorMessage = "";
|
||||
for (int i = 0; i < developers.Length; i++)
|
||||
{
|
||||
if (developers[i].Length > ConjureArcadeMetadata.DevelopersNameLimit)
|
||||
{
|
||||
developersErrorMessage += string.Format(DevelopersCharLimitExceedError, ConjureArcadeMetadata.DevelopersNameLimit);
|
||||
developersErrorIndex.Add(i);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <returns>Returns the validation state based on the current amount of errors detected</returns>
|
||||
public MetadataValidationStateType GetValidationStateType()
|
||||
{
|
||||
if (errorCount < 0)
|
||||
{
|
||||
// Smaller than 0, which means data haven't been verified yet
|
||||
return MetadataValidationStateType.NotVerified;
|
||||
}
|
||||
else if (errorCount == 0)
|
||||
{
|
||||
// No error, means it's a success
|
||||
return MetadataValidationStateType.Validated;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Errors were detected
|
||||
return MetadataValidationStateType.Failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edace48768db8a54e8806e8d703c6efa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,301 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using ConjureOS.CustomWindow;
|
||||
|
||||
namespace ConjureOS.MetadataWindow
|
||||
{
|
||||
public class ConjureArcadeMetadataWindow : EditorWindow
|
||||
{
|
||||
private const string WindowName = "Arcade Game Metadata Editor";
|
||||
|
||||
// Game Metadata
|
||||
private static ConjureArcadeMetadata metadata;
|
||||
private ConjureArcadeMetadataValidator metadataValidator;
|
||||
private SerializedObject serializedObject;
|
||||
|
||||
// Metadata Properties
|
||||
private SerializedProperty gameTitleProperty;
|
||||
private SerializedProperty versionProperty;
|
||||
private SerializedProperty descriptionProperty;
|
||||
private SerializedProperty minNumPlayerProperty;
|
||||
private SerializedProperty maxNumPlayerProperty;
|
||||
private SerializedProperty useLeaderboardProperty;
|
||||
private SerializedProperty thumbnailProperty;
|
||||
private SerializedProperty gameplayImageProperty;
|
||||
private SerializedProperty developersProperty;
|
||||
private SerializedProperty genresProperty;
|
||||
|
||||
private ReorderableList developersList;
|
||||
private ReorderableList genresList;
|
||||
|
||||
// UI Properties
|
||||
private Vector2 scrollPos = Vector2.zero;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
metadataValidator = new ConjureArcadeMetadataValidator();
|
||||
titleContent = new GUIContent(WindowName);
|
||||
|
||||
if (!metadata)
|
||||
{
|
||||
OnLoad();
|
||||
}
|
||||
|
||||
serializedObject = new SerializedObject(metadata);
|
||||
SetUpProperties(serializedObject);
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void OnLoad()
|
||||
{
|
||||
if (!metadata)
|
||||
{
|
||||
metadata = AssetDatabase.LoadAssetAtPath<ConjureArcadeMetadata>(ConjureArcadeMetadata.MetadataAssetPath);
|
||||
|
||||
// Data exists
|
||||
if (metadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
metadata = CreateInstance<ConjureArcadeMetadata>();
|
||||
|
||||
AssetDatabase.CreateAsset(metadata, ConjureArcadeMetadata.MetadataAssetPath);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
// Add padding to the window
|
||||
int globalSpace = 2;
|
||||
int uniformPadding = ConjureArcadeGUI.Style.UniformPadding;
|
||||
RectOffset padding = new RectOffset(uniformPadding, uniformPadding, 0, 0);
|
||||
Rect area = new Rect(
|
||||
padding.right,
|
||||
padding.top,
|
||||
position.width - (padding.left),
|
||||
position.height - (padding.top + padding.bottom));
|
||||
|
||||
// Generate input fields
|
||||
GUILayout.BeginArea(area);
|
||||
|
||||
// Scrollbar
|
||||
RectOffset vertScrollbarPadding = new RectOffset(uniformPadding, 0, 0, 0);
|
||||
GUIStyle vertScrollbarSkin = new GUIStyle(GUI.skin.verticalScrollbar);
|
||||
vertScrollbarSkin.margin = vertScrollbarPadding;
|
||||
|
||||
scrollPos = GUILayout.BeginScrollView(scrollPos, false, true, new GUIStyle(GUI.skin.horizontalScrollbar), vertScrollbarSkin);
|
||||
|
||||
GUILayout.Space(uniformPadding);
|
||||
GUILayout.Label("GAME METADATA", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUILayout.PropertyField(gameTitleProperty, new GUIContent("Game Title"));
|
||||
ShowErrorMessage(metadataValidator.GameTitleErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(versionProperty, new GUIContent("Version"));
|
||||
ShowErrorMessage(metadataValidator.VersionErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(descriptionProperty, new GUIContent("Description"), GUILayout.Height(150));
|
||||
ShowErrorMessage(metadataValidator.DescriptionErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(minNumPlayerProperty, new GUIContent("Min Number of Players"));
|
||||
ShowErrorMessage(metadataValidator.MinNumPlayerErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(maxNumPlayerProperty, new GUIContent("Max Number of Players"));
|
||||
ShowErrorMessage(metadataValidator.MaxNumPlayerErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(useLeaderboardProperty, new GUIContent("Use Leaderboard"));
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(thumbnailProperty, new GUIContent("Thumbnail"));
|
||||
ShowErrorMessage(metadataValidator.ThumbnailErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
EditorGUILayout.PropertyField(gameplayImageProperty, new GUIContent("Gameplay Image"));
|
||||
ShowErrorMessage(metadataValidator.GameplayImageErrorMessage);
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
GUILayout.Space(10);
|
||||
developersList.DoLayoutList();
|
||||
ShowErrorMessage(metadataValidator.DevelopersErrorMessage);
|
||||
|
||||
GUILayout.Space(10);
|
||||
UpdateReorderableListInteractions(genresList, ConjureArcadeMetadata.MaxSelectedGenres);
|
||||
genresList.DoLayoutList();
|
||||
ShowErrorMessage(metadataValidator.GenresErrorMessage);
|
||||
|
||||
GUILayout.Space(10);
|
||||
|
||||
// Show release date and last change date ONLY if a date has been set
|
||||
if (metadata.ReleaseDate != DateTime.MinValue)
|
||||
{
|
||||
GUILayout.Label("Release Date: " + metadata.ReleaseDate.ToString());
|
||||
}
|
||||
if (metadata.LastGameUpdate != DateTime.MinValue)
|
||||
{
|
||||
GUILayout.Label("Last Change: " + metadata.LastGameUpdate.ToString());
|
||||
}
|
||||
|
||||
// Validate properties and save data
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
GUILayout.Space(30);
|
||||
if (GUILayout.Button("Execute Validation", GUILayout.Width(150)))
|
||||
{
|
||||
metadataValidator.ValidateMetadata(metadata);
|
||||
}
|
||||
|
||||
GUILayout.Space(globalSpace);
|
||||
|
||||
ShowValidationResultMessage();
|
||||
|
||||
GUILayout.Space(uniformPadding);
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void ShowErrorMessage(string errorMessage)
|
||||
{
|
||||
if (errorMessage != string.Empty)
|
||||
{
|
||||
GUILayout.Label(errorMessage, ConjureArcadeGUI.Style.ErrorStyle);
|
||||
GUILayout.Space(3);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowValidationResultMessage()
|
||||
{
|
||||
MetadataValidationStateType validationState = metadataValidator.GetValidationStateType();
|
||||
|
||||
switch (validationState)
|
||||
{
|
||||
case MetadataValidationStateType.NotVerified:
|
||||
// No message is displayed
|
||||
return;
|
||||
|
||||
case MetadataValidationStateType.Validated:
|
||||
// No error, means it's a success
|
||||
GUILayout.Label(ConjureArcadeGUI.Message.MetadataConfirmedMessage, ConjureArcadeGUI.Style.SuccessStyle);
|
||||
GUILayout.Space(3);
|
||||
break;
|
||||
|
||||
case MetadataValidationStateType.Failed:
|
||||
// Errors were detected
|
||||
string plural = (metadataValidator.ErrorCount > 1) ? "s" : "";
|
||||
string formatedMessage = string.Format(ConjureArcadeGUI.Message.MetadataFailedMessage, metadataValidator.ErrorCount, plural);
|
||||
ShowErrorMessage(formatedMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUpProperties(SerializedObject serializedObject)
|
||||
{
|
||||
// Get data
|
||||
gameTitleProperty = serializedObject.FindProperty("gameTitle");
|
||||
versionProperty = serializedObject.FindProperty("version");
|
||||
descriptionProperty = serializedObject.FindProperty("description");
|
||||
minNumPlayerProperty = serializedObject.FindProperty("minNumPlayer");
|
||||
maxNumPlayerProperty = serializedObject.FindProperty("maxNumPlayer");
|
||||
useLeaderboardProperty = serializedObject.FindProperty("useLeaderboard");
|
||||
thumbnailProperty = serializedObject.FindProperty("thumbnail");
|
||||
gameplayImageProperty = serializedObject.FindProperty("gameplayImage");
|
||||
|
||||
// Get developers data and prepare list
|
||||
developersProperty = serializedObject.FindProperty("developers");
|
||||
developersList = new ReorderableList(serializedObject, developersProperty, true, true, true, true);
|
||||
developersList.drawElementCallback = DrawDevelopersListItems;
|
||||
developersList.drawHeaderCallback = DrawDevelopersListHeader;
|
||||
developersList.onReorderCallback = OnDevelopersReorder;
|
||||
|
||||
|
||||
// Get genres data and prepare list
|
||||
genresProperty = serializedObject.FindProperty("genres");
|
||||
genresList = new ReorderableList(serializedObject, genresProperty, true, true, true, true);
|
||||
genresList.drawElementCallback = DrawGenresListItems;
|
||||
genresList.drawHeaderCallback = DrawGenresListHeader;
|
||||
}
|
||||
|
||||
private void UpdateReorderableListInteractions(ReorderableList list, int countLimit)
|
||||
{
|
||||
// Hide or show the "Add" button only if the count limit has not been reached
|
||||
if (genresList.count >= countLimit)
|
||||
{
|
||||
list.displayAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.displayAdd = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ReorderableList Callbacks =====
|
||||
private void DrawGenresListItems(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
// Get the selected genre of the current item
|
||||
var element = genresProperty.GetArrayElementAtIndex(index);
|
||||
var selectedGenre = element.FindPropertyRelative(nameof(GameGenre.selectedGenre));
|
||||
|
||||
var popupHeight = EditorGUI.GetPropertyHeight(selectedGenre);
|
||||
|
||||
// Create popup
|
||||
selectedGenre.intValue = EditorGUI.Popup(new Rect(rect.x, rect.y, rect.width, popupHeight), selectedGenre.intValue, ConjureArcadeMetadata.GenreOptions);
|
||||
}
|
||||
|
||||
private void DrawDevelopersListItems(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
// Get the selected genre of the current item
|
||||
var element = developersProperty.GetArrayElementAtIndex(index);
|
||||
|
||||
// Create popup
|
||||
GUIStyle fieldErrorIndicatorStyle = new GUIStyle(EditorStyles.textField);
|
||||
fieldErrorIndicatorStyle.normal.textColor = ConjureArcadeGUI.Style.ColorError;
|
||||
|
||||
for (int i = 0; i < metadataValidator.DevelopersErrorIndex.Count; i++)
|
||||
{
|
||||
if (index == metadataValidator.DevelopersErrorIndex[i])
|
||||
{
|
||||
element.stringValue = EditorGUI.TextField(new Rect(rect.x, rect.y, rect.width, rect.height), element.stringValue, fieldErrorIndicatorStyle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element.stringValue = EditorGUI.TextField(new Rect(rect.x, rect.y, rect.width, rect.height), element.stringValue);
|
||||
}
|
||||
|
||||
private void DrawGenresListHeader(Rect rect)
|
||||
{
|
||||
DrawListHeader(rect, "Genres");
|
||||
}
|
||||
|
||||
private void DrawDevelopersListHeader(Rect rect)
|
||||
{
|
||||
DrawListHeader(rect, "Developers");
|
||||
}
|
||||
|
||||
private void DrawListHeader(Rect rect, string name)
|
||||
{
|
||||
EditorGUI.LabelField(rect, name);
|
||||
}
|
||||
|
||||
private void OnDevelopersReorder(ReorderableList reList)
|
||||
{
|
||||
// On reorder of the developers list, data are revalidated because of the new order
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
metadataValidator.ValidateDevelopersList(metadata.Developers);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0cfd6670cf89b984bb971537d740f4c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/ConjureOS/Scripts/MetadataWindow/GameGenre.cs
Normal file
10
Assets/ConjureOS/Scripts/MetadataWindow/GameGenre.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace ConjureOS.MetadataWindow
|
||||
{
|
||||
[Serializable]
|
||||
public struct GameGenre
|
||||
{
|
||||
public int selectedGenre;
|
||||
}
|
||||
}
|
||||
11
Assets/ConjureOS/Scripts/MetadataWindow/GameGenre.cs.meta
Normal file
11
Assets/ConjureOS/Scripts/MetadataWindow/GameGenre.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2bf07614a284e334b8300836f4365f78
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,9 @@
|
||||
namespace ConjureOS.MetadataWindow
|
||||
{
|
||||
public enum MetadataValidationStateType
|
||||
{
|
||||
NotVerified,
|
||||
Validated,
|
||||
Failed
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90c3d1fd9b921034c964891b00a1594c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/ConjureOS/Scripts/UploadWindow.meta
Normal file
8
Assets/ConjureOS/Scripts/UploadWindow.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 696a1ff0be1f41e439b3185025356f09
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,122 @@
|
||||
#if UNITY_EDITOR
|
||||
using ConjureOS.MetadataWindow;
|
||||
using ConjureOS.CustomWindow;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ConjureOS.UploaderWindow
|
||||
{
|
||||
public class ConjureArcadeGameUploaderWindow : EditorWindow
|
||||
{
|
||||
private const string WindowName = "Arcade Game Uploader";
|
||||
|
||||
// Game Metadata
|
||||
private static ConjureArcadeMetadata metadata;
|
||||
private ConjureArcadeMetadataValidator metadataValidator;
|
||||
private ConjureArcadeUploadProcessor uploadProcessor;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
metadataValidator = new ConjureArcadeMetadataValidator();
|
||||
uploadProcessor = new ConjureArcadeUploadProcessor();
|
||||
titleContent = new GUIContent(WindowName);
|
||||
|
||||
if (!metadata)
|
||||
{
|
||||
OnLoad();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnLoad()
|
||||
{
|
||||
if (!metadata)
|
||||
{
|
||||
metadata = AssetDatabase.LoadAssetAtPath<ConjureArcadeMetadata>(ConjureArcadeMetadata.MetadataAssetPath);
|
||||
|
||||
// Data exists
|
||||
if (metadata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
metadata = CreateInstance<ConjureArcadeMetadata>();
|
||||
|
||||
AssetDatabase.CreateAsset(metadata, ConjureArcadeMetadata.MetadataAssetPath);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// Add padding to the window
|
||||
int sectionSpace = 20;
|
||||
int uniformPadding = ConjureArcadeGUI.Style.UniformPadding;
|
||||
RectOffset padding = new RectOffset(uniformPadding, uniformPadding, 0, 0);
|
||||
Rect area = new Rect(
|
||||
padding.right,
|
||||
padding.top,
|
||||
position.width - (padding.left),
|
||||
position.height - (padding.top + padding.bottom));
|
||||
|
||||
GUILayout.BeginArea(area);
|
||||
|
||||
// Web Server Info section
|
||||
GUILayout.Label("WEB SERVER INFO", EditorStyles.boldLabel);
|
||||
// TODO Add server connection data / fields
|
||||
|
||||
GUILayout.Space(sectionSpace);
|
||||
|
||||
// Metadata section
|
||||
GUILayout.Label("METADATA", EditorStyles.boldLabel);
|
||||
GUILayout.Label("Be sure to have valid metadata before uploading the game to the web server.", EditorStyles.wordWrappedLabel);
|
||||
|
||||
ShowValidationResultMessage();
|
||||
if (GUILayout.Button("Validate Metadata", GUILayout.Width(150)))
|
||||
{
|
||||
metadataValidator.ValidateMetadata(metadata);
|
||||
}
|
||||
|
||||
GUILayout.Space(sectionSpace);
|
||||
|
||||
// Build and Upload section
|
||||
GUILayout.Label("BUILD AND UPLOAD", EditorStyles.boldLabel);
|
||||
GUILayout.Label("When ready, you can build and upload the game to the web server.", EditorStyles.wordWrappedLabel);
|
||||
if (GUILayout.Button("Build & Upload", GUILayout.Width(150)))
|
||||
{
|
||||
uploadProcessor.BuildAndUpload(metadata, metadataValidator);
|
||||
GUIUtility.ExitGUI();
|
||||
}
|
||||
|
||||
GUILayout.EndArea();
|
||||
}
|
||||
|
||||
private void ShowValidationResultMessage()
|
||||
{
|
||||
MetadataValidationStateType validationState = metadataValidator.GetValidationStateType();
|
||||
|
||||
switch (validationState)
|
||||
{
|
||||
case MetadataValidationStateType.NotVerified:
|
||||
// No message is displayed
|
||||
return;
|
||||
|
||||
case MetadataValidationStateType.Validated:
|
||||
// No error, means it's a success
|
||||
GUILayout.Label(ConjureArcadeGUI.Message.MetadataConfirmedMessage, ConjureArcadeGUI.Style.SuccessStyle);
|
||||
GUILayout.Space(3);
|
||||
break;
|
||||
|
||||
case MetadataValidationStateType.Failed:
|
||||
// Errors were detected
|
||||
string plural = (metadataValidator.ErrorCount > 1) ? "s" : "";
|
||||
string formatedMessage =
|
||||
string.Format(ConjureArcadeGUI.Message.MetadataFailedMessage, metadataValidator.ErrorCount, plural) +
|
||||
string.Format(" Please, fix the error{0} in the Game Metadata window ('Arcade > Game Metadata Editor').", plural);
|
||||
GUILayout.Label(formatedMessage, ConjureArcadeGUI.Style.ErrorStyle);
|
||||
GUILayout.Space(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd1c153b5930bca4aa2b62c24b229838
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,239 @@
|
||||
#if UNITY_EDITOR
|
||||
using ConjureOS.MetadataWindow;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ConjureOS.UploaderWindow
|
||||
{
|
||||
public class ConjureArcadeUploadProcessor
|
||||
{
|
||||
private const string logConjureArcade = "Conjure Arcade: ";
|
||||
|
||||
private const string GameFolder = "game\\";
|
||||
private const string MediasFolder = "medias\\";
|
||||
private const string TempFolder = "temp\\";
|
||||
private const string MetadataFileName = "metadata.txt";
|
||||
|
||||
/// <summary>
|
||||
/// Build and upload the game to the web server.
|
||||
/// Must use valid Conjure Arcade metadata, or the process will fail.
|
||||
/// </summary>
|
||||
/// <param name="metadata">The Conjure Arcade metadata of the game</param>
|
||||
/// <param name="metadataValidator">The metadata validator</param>
|
||||
public void BuildAndUpload(ConjureArcadeMetadata metadata, ConjureArcadeMetadataValidator metadataValidator)
|
||||
{
|
||||
// Step 1: Validate metadata
|
||||
if (!metadataValidator.ValidateMetadata(metadata))
|
||||
{
|
||||
ShowErrorDialog(
|
||||
"Some entries in the game metadata are incorrect. " +
|
||||
"You must fix them in order to upload the game to the web server.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Step 2: Build game
|
||||
string fileName; // Name of the executable file
|
||||
string fileExtension; // Extension of the executable file
|
||||
string buildDirectoryPath; // Path to the build directory
|
||||
string tempDirectoryPath; // Path to the temp directory, located inside the build directory
|
||||
try
|
||||
{
|
||||
// Get current build settings
|
||||
BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions();
|
||||
buildPlayerOptions = BuildPlayerWindow.DefaultBuildMethods.GetBuildPlayerOptions(buildPlayerOptions);
|
||||
|
||||
// Get file and directory data
|
||||
fileName = Path.GetFileNameWithoutExtension(buildPlayerOptions.locationPathName);
|
||||
fileExtension = Path.GetExtension(buildPlayerOptions.locationPathName);
|
||||
buildDirectoryPath = Path.GetDirectoryName(buildPlayerOptions.locationPathName) + "\\";
|
||||
tempDirectoryPath = buildDirectoryPath + TempFolder;
|
||||
|
||||
// Change Build Settings build directory to the temp directory
|
||||
// Generated location for the game is of the format "...BuildDirectory\temp\game\ProductName.extension"
|
||||
buildPlayerOptions.locationPathName =
|
||||
tempDirectoryPath +
|
||||
GameFolder +
|
||||
fileName +
|
||||
fileExtension;
|
||||
|
||||
// Build the game
|
||||
BuildPipeline.BuildPlayer(buildPlayerOptions);
|
||||
}
|
||||
catch (BuildPlayerWindow.BuildMethodException)
|
||||
{
|
||||
// Exception called when the user manually closes the "File Chooser" window
|
||||
Debug.Log(logConjureArcade + "Build & Upload canceled.");
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ShowErrorDialog("An error occured when building the game.");
|
||||
Debug.LogError(e);
|
||||
return;
|
||||
}
|
||||
|
||||
// "game" folder content is compressed
|
||||
CompressAndDelete(tempDirectoryPath + GameFolder, tempDirectoryPath + "game.zip");
|
||||
|
||||
|
||||
// Step 3: Copy images to the temp directory
|
||||
string mediasDirectoryPath = tempDirectoryPath + MediasFolder;
|
||||
string thumbnailPath = CopyAndRenameImage(metadata.Thumbnail, mediasDirectoryPath, "thumbnail");
|
||||
string gameplayImagePath = CopyAndRenameImage(metadata.GameplayImage, mediasDirectoryPath, "gameplayImage");
|
||||
|
||||
|
||||
// Step 4: Generate metadata inside the temp directory
|
||||
metadata.UpdateUneditableData();
|
||||
string metadataContent = GenerateMetadata(metadata, thumbnailPath, gameplayImagePath, fileName + fileExtension);
|
||||
if (!WriteMetadataFile(metadataContent, tempDirectoryPath))
|
||||
{
|
||||
ShowErrorDialog("An error occured when generating the metadata file.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Step 5: Convert all files int a ".conj"
|
||||
string conjFilePath = buildDirectoryPath + fileName + ".conj";
|
||||
CompressAndDelete(tempDirectoryPath, conjFilePath);
|
||||
|
||||
|
||||
// Step 6: Upload game and metadata to the webserver
|
||||
// TODO Add server connection / upload
|
||||
|
||||
|
||||
// Step 7: Show success feedback to the user
|
||||
Debug.Log(logConjureArcade + "Game was build and upload to the web server.");
|
||||
EditorUtility.DisplayDialog(
|
||||
"Success",
|
||||
"Game was build and upload to the web server.",
|
||||
"Ok");
|
||||
}
|
||||
|
||||
private static void ShowErrorDialog(string description)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Fail to Build and Upload Game", description, "Ok");
|
||||
Debug.LogError(logConjureArcade + description);
|
||||
}
|
||||
|
||||
private static string CopyAndRenameImage(Texture2D image, string newDirectoryPath, string newFileName)
|
||||
{
|
||||
string relativePath = AssetDatabase.GetAssetPath(image);
|
||||
|
||||
// We check and remove "Assets" at the start of the relative path because
|
||||
// Application.dataPath already gives us the path to the assets folder
|
||||
// Ex: Assets/Images/ --> Images/
|
||||
string oldAbsolutePath = Application.dataPath + relativePath.Substring(6);
|
||||
|
||||
// We find the image, copy it to the new folder (newDirectoryPath), change its name and keep its extension
|
||||
FileInfo file = new FileInfo(oldAbsolutePath);
|
||||
string fullFileName = string.Format("{0}{1}", newFileName, file.Extension);
|
||||
if (file.Exists)
|
||||
{
|
||||
// Delete file in new directory if it already exists
|
||||
string newFilePath = string.Format("{0}{1}", newDirectoryPath, fullFileName);
|
||||
|
||||
if (!Directory.Exists(newDirectoryPath))
|
||||
{
|
||||
// Check if new directory exists, and create it
|
||||
// If folder doesn't exist, the file cannot be copied
|
||||
Directory.CreateDirectory(newDirectoryPath);
|
||||
}
|
||||
else if (File.Exists(newFilePath))
|
||||
{
|
||||
// Check if file exists, and delete it
|
||||
File.Delete(newFilePath);
|
||||
}
|
||||
|
||||
file.CopyTo(newFilePath);
|
||||
}
|
||||
|
||||
return fullFileName;
|
||||
}
|
||||
|
||||
private string GenerateMetadata(
|
||||
ConjureArcadeMetadata metadata,
|
||||
string thumbnailFileName,
|
||||
string gameplayImageFileName,
|
||||
string fileName)
|
||||
{
|
||||
string newLine = Environment.NewLine;
|
||||
string content = "";
|
||||
content +=
|
||||
"id: " + metadata.Id + newLine +
|
||||
"game: " + metadata.GameTitle + newLine +
|
||||
"version: " + metadata.Version + newLine +
|
||||
"description: " + metadata.Description + newLine +
|
||||
"players: " + metadata.MinNumPlayer + "-" + metadata.MaxNumPlayer + newLine +
|
||||
"leaderboard: " + metadata.UseLeaderboard + newLine +
|
||||
"thumbnailPath: " + thumbnailFileName + newLine +
|
||||
"imagePath: " + gameplayImageFileName + newLine +
|
||||
"release: " + FormatDate(metadata.ReleaseDate) + newLine +
|
||||
"modification: " + FormatDate(metadata.LastGameUpdate) + newLine +
|
||||
"file: " + GameFolder + fileName + newLine;
|
||||
|
||||
// Adding developers
|
||||
content += "developers: ";
|
||||
foreach (string developer in metadata.Developers)
|
||||
{
|
||||
content += developer + ", ";
|
||||
}
|
||||
content += newLine;
|
||||
|
||||
// Adding genres
|
||||
content += "genres:" + newLine;
|
||||
foreach (GameGenre gameGenre in metadata.Genres)
|
||||
{
|
||||
string genre = ConjureArcadeMetadata.GenreOptions[gameGenre.selectedGenre];
|
||||
content += " " + genre + newLine;
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
private bool WriteMetadataFile(string content, string directoryPath)
|
||||
{
|
||||
string fullPath = directoryPath + MetadataFileName;
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
File.Delete(fullPath);
|
||||
}
|
||||
|
||||
// Write content
|
||||
using (FileStream fs = File.Create(fullPath))
|
||||
{
|
||||
byte[] encodedContent = new System.Text.UTF8Encoding(true).GetBytes(content);
|
||||
fs.Write(encodedContent, 0, encodedContent.Length);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CompressAndDelete(string sourceDirectoryPath, string destinationArchiveFileName)
|
||||
{
|
||||
ZipFile.CreateFromDirectory(sourceDirectoryPath, destinationArchiveFileName);
|
||||
Directory.Delete(sourceDirectoryPath, true);
|
||||
}
|
||||
|
||||
private string FormatDate(DateTime date)
|
||||
{
|
||||
return
|
||||
date.Day.ToString() + "-" +
|
||||
date.Month.ToString() + "-" +
|
||||
date.Year.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67065d97fd394ab428022e93d776bcac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Gameplay.PNG
Normal file
BIN
Assets/Gameplay.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
127
Assets/Gameplay.PNG.meta
Normal file
127
Assets/Gameplay.PNG.meta
Normal file
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10d56716671742243b83b63164772384
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
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: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
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: 3
|
||||
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: 3
|
||||
buildTarget: Server
|
||||
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: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Gameplay.jpg
(Stored with Git LFS)
Normal file
BIN
Assets/Gameplay.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
127
Assets/Gameplay.jpg.meta
Normal file
127
Assets/Gameplay.jpg.meta
Normal file
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f77d9fb0ed4f7ad459db7c688a37d2f9
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
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: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
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: 3
|
||||
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: 3
|
||||
buildTarget: Server
|
||||
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: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -47,6 +47,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "56e35fc7-3515-47d8-b863-76845c6f4447",
|
||||
"path": "<ConjureArcadeController>/start",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Join",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "b38c5aaa-31ba-4881-b6c9-a2316c144b2d",
|
||||
@ -68,6 +79,17 @@
|
||||
"action": "Leave",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "9cea3501-b3f2-45a9-a359-5ae29f83da77",
|
||||
"path": "<ConjureArcadeController>/button2",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Leave",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -118,6 +118,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "b714db0b-e69a-4f21-938e-4f18ee1dc89d",
|
||||
"path": "<ConjureArcadeController>/stick",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Move",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "4d10aaef-32d6-4c7a-8449-1c849dda257e",
|
||||
@ -140,6 +151,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "9d8d83a4-3c84-43f8-9803-b7b08077dbd4",
|
||||
"path": "<ConjureArcadeController>/button2",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "SecondaryAction",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "b0bf774f-f879-4c0c-8608-96f39ad24d03",
|
||||
@ -162,6 +184,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "ac1c47b6-b41f-4497-a860-f9f9a9b77211",
|
||||
"path": "<ConjureArcadeController>/button1",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "PrimaryAction",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "e9736063-d308-4c4a-a55d-4b8db3126a92",
|
||||
@ -184,6 +217,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "3352fcb0-4077-4135-96ac-d6e80b239aa5",
|
||||
"path": "<ConjureArcadeController>/start",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Pause",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "2502bf06-81a2-4053-a57d-be08e7cb61c6",
|
||||
@ -205,6 +249,17 @@
|
||||
"action": "SwitchPlayer",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "9bbb6b94-304e-42b1-aa57-b4c8eadf99f9",
|
||||
"path": "<ConjureArcadeController>/buttonA",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "SwitchPlayer",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -317,6 +317,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": true
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "eb39813a-66de-41e9-a7ee-f6b5ab305254",
|
||||
"path": "<ConjureArcadeController>/stick",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Navigate",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "aa21891e-8f0b-40c8-ba7e-fd97e7ca38e5",
|
||||
@ -328,6 +339,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "f5a82c0f-021d-42d6-981e-316cf08c637f",
|
||||
"path": "<ConjureArcadeController>/button1",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Submit",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "5de9312c-2df2-40ab-b3fc-3f64bdba64c5",
|
||||
@ -339,6 +361,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "e4c84fc6-a05a-4d3b-891b-184add45ce56",
|
||||
"path": "<ConjureArcadeController>/button2",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Cancel",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "6134beac-34df-4c4a-ae23-e5fac7cc7b2e",
|
||||
|
||||
BIN
Assets/MainMenu.PNG
Normal file
BIN
Assets/MainMenu.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
127
Assets/MainMenu.PNG.meta
Normal file
127
Assets/MainMenu.PNG.meta
Normal file
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87ea2a8e44e913e43850f3a9b4e9a884
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
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: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
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: 3
|
||||
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: 3
|
||||
buildTarget: Server
|
||||
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: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/MainMenu.jpg
(Stored with Git LFS)
Normal file
BIN
Assets/MainMenu.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
127
Assets/MainMenu.jpg.meta
Normal file
127
Assets/MainMenu.jpg.meta
Normal file
@ -0,0 +1,127 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4082b7995fb3a974fb4b5853d98e37fb
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 12
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
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: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
swizzle: 50462976
|
||||
cookieLightType: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
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: 3
|
||||
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: 3
|
||||
buildTarget: Server
|
||||
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: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
nameFileIdTable: {}
|
||||
mipmapLimitGroupName:
|
||||
pSDRemoveMatte: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,85 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Conjure.Input;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.UI;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
using InputDevice = UnityEngine.InputSystem.InputDevice;
|
||||
|
||||
public class MenuInputManager : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField, Required] private InputSystemUIInputModule inputSystemUIInputModule;
|
||||
[SerializeField, Required] private InputServerReference inputServerReference;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>();
|
||||
}
|
||||
|
||||
public void OnJoin(int playerSeat)
|
||||
|
||||
{
|
||||
if (inputSystemUIInputModule.actionsAsset.devices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputManagerServer inputManagerServer = inputServerReference.Value.GetComponent<InputManagerServer>();
|
||||
|
||||
List<InputDevice> devices =
|
||||
new List<InputDevice>(inputSystemUIInputModule.actionsAsset.devices.Value.ToArray());
|
||||
|
||||
PlayerEnum player = inputManagerServer.GetPlayerFromInt(playerSeat);
|
||||
|
||||
// shouldn't be reachable
|
||||
if (player == PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevice currentDevice = FindDeviceById(inputManagerServer.GetDeviceIdFromPlayerEnum(player));
|
||||
|
||||
// shouldn't be reachable
|
||||
if (currentDevice is not null)
|
||||
{
|
||||
devices.Add(currentDevice);
|
||||
}
|
||||
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>(devices.ToArray());
|
||||
}
|
||||
|
||||
public void OnLeave(int playerSeat)
|
||||
{
|
||||
if (inputSystemUIInputModule.actionsAsset.devices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputManagerServer inputManagerServer = inputServerReference.Value.GetComponent<InputManagerServer>();
|
||||
|
||||
if (playerSeat == 0 && inputManagerServer.GetNumberPlayers() == 0)
|
||||
{
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevice currentDevice = FindDeviceById(inputManagerServer.GetDeviceIdFromPlayerEnum(PlayerEnum.Player1));
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>(new []{currentDevice});
|
||||
}
|
||||
|
||||
private InputDevice FindDeviceById(int deviceId)
|
||||
{
|
||||
foreach (InputDevice currentDevice in InputSystem.devices)
|
||||
{
|
||||
if (currentDevice.deviceId == deviceId)
|
||||
{
|
||||
return currentDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -16,5 +16,35 @@ MonoBehaviour:
|
||||
deleteDllAfterBuilds: 1
|
||||
AutomateForAllAOTPlatforms: 1
|
||||
automateForPlatforms: 0900000014000000
|
||||
lastScan: 638328066783784121
|
||||
supportSerializedTypes: []
|
||||
lastScan: 638354871209628840
|
||||
supportSerializedTypes:
|
||||
- TypeName: System.Collections.Generic.Dictionary`2[[Conjure.Input.PlayerEnum,
|
||||
Assembly-CSharp],[System.Int32, mscorlib]], mscorlib
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: System.Collections.Generic.EnumEqualityComparer`1[[Conjure.Input.PlayerEnum,
|
||||
Assembly-CSharp]], mscorlib
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: UnityEngine.GameObject, UnityEngine.CoreModule
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: System.Collections.Generic.IEqualityComparer`1[[Conjure.Input.PlayerEnum,
|
||||
Assembly-CSharp]], mscorlib
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: Conjure.Interraction.IInteractable, Assembly-CSharp
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: System.Int32, mscorlib
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: Conjure.Input.PlayerEnum, Assembly-CSharp
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: Obvious.Soap.ScriptableEventNoParam, Obvious.Soap
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
- TypeName: Obvious.Soap.Vector3Variable, Obvious.Soap
|
||||
IsCustom: 0
|
||||
Emit: 1
|
||||
|
||||
@ -13,7 +13,7 @@ MonoBehaviour:
|
||||
m_Name: InspectorConfig
|
||||
m_EditorClassIdentifier:
|
||||
enableOdinInInspector: 1
|
||||
defaultEditorBehaviour: 15
|
||||
defaultEditorBehaviour: 11
|
||||
processMouseMoveInInspector: 1
|
||||
drawingConfig:
|
||||
configs: []
|
||||
|
||||
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.12731713, g: 0.13414738, b: 0.121078536, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.12731749, g: 0.13414757, b: 0.1210787, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -273,6 +273,50 @@ Transform:
|
||||
type: 3}
|
||||
m_PrefabInstance: {fileID: 356792912}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &908587195
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 908587197}
|
||||
- component: {fileID: 908587196}
|
||||
m_Layer: 0
|
||||
m_Name: ConjureGlobalObject
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!114 &908587196
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 908587195}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 42abcca807f2495aa5d59ff8d0570ed6, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!4 &908587197
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 908587195}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1111584621
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -383,7 +427,7 @@ MonoBehaviour:
|
||||
PrefabModificationsReferencedUnityObjects: []
|
||||
PrefabModifications: []
|
||||
SerializationNodes: []
|
||||
sceneToLoad: {fileID: 102900000, guid: c71ef66ffab2d95479284caa29000a51, type: 3}
|
||||
scene: MainMenu
|
||||
--- !u!114 &2107510171
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -422,3 +466,4 @@ SceneRoots:
|
||||
m_Roots:
|
||||
- {fileID: 181845378}
|
||||
- {fileID: 320152712}
|
||||
- {fileID: 908587197}
|
||||
|
||||
@ -38,7 +38,7 @@ RenderSettings:
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 0}
|
||||
m_IndirectSpecularColor: {r: 0.1838259, g: 0.22910246, b: 0.30390218, a: 1}
|
||||
m_IndirectSpecularColor: {r: 0.18382604, g: 0.22910279, b: 0.30390263, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
@ -1486,14 +1486,13 @@ MonoBehaviour:
|
||||
type: 3}
|
||||
m_TargetAssemblyTypeName: Conjure.SceneNavigation, Assembly-CSharp
|
||||
m_MethodName: StartGame
|
||||
m_Mode: 2
|
||||
m_Mode: 5
|
||||
m_Arguments:
|
||||
m_ObjectArgument: {fileID: 102900000, guid: a8881575ffff7b64dac12cdf05a8b5b4,
|
||||
type: 3}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEditor.SceneAsset, UnityEditor.CoreModule
|
||||
m_ObjectArgument: {fileID: 0}
|
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||
m_IntArgument: 0
|
||||
m_FloatArgument: 0
|
||||
m_StringArgument:
|
||||
m_StringArgument: Level1
|
||||
m_BoolArgument: 0
|
||||
m_CallState: 2
|
||||
--- !u!114 &576113626
|
||||
@ -2474,7 +2473,7 @@ Canvas:
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_VertexColorAlwaysGammaSpace: 1
|
||||
m_AdditionalShaderChannelsFlag: 7
|
||||
m_AdditionalShaderChannelsFlag: 31
|
||||
m_UpdateRectTransformForStandalone: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 0
|
||||
|
||||
@ -10,11 +10,11 @@ namespace Conjure.GameInitialization
|
||||
public class FirstSceneSelector : SerializedMonoBehaviour
|
||||
{
|
||||
[Required]
|
||||
[SerializeField] private SceneAsset sceneToLoad;
|
||||
[SerializeField] private String scene;
|
||||
|
||||
public void LoadFirstScene()
|
||||
{
|
||||
SceneManager.LoadScene(sceneToLoad.name);
|
||||
SceneManager.LoadScene(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,71 +1,70 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Conjure.Input;
|
||||
using Obvious.Soap;
|
||||
using Obvious.Soap.Attributes;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class GameJoiner : SerializedMonoBehaviour
|
||||
namespace Conjure.Input
|
||||
{
|
||||
[Required, SerializeField]
|
||||
private ScriptableEventInt onJoinEvent;
|
||||
[Required, SerializeField]
|
||||
private ScriptableEventInt onLeaveEvent;
|
||||
|
||||
[SerializeField, Required]
|
||||
private InputServerReference inputManagerGameobjectReference;
|
||||
|
||||
private InputManagerServer _inputManagerServer;
|
||||
|
||||
private void Awake()
|
||||
public class GameJoiner : SerializedMonoBehaviour
|
||||
{
|
||||
if (inputManagerGameobjectReference.Value is not null)
|
||||
{
|
||||
_inputManagerServer = inputManagerGameobjectReference.Value.GetComponent<InputManagerServer>();
|
||||
}
|
||||
[Required, SerializeField]
|
||||
private ScriptableEventInt onJoinEvent;
|
||||
[Required, SerializeField]
|
||||
private ScriptableEventInt onLeaveEvent;
|
||||
|
||||
if (_inputManagerServer is null)
|
||||
[SerializeField, Required]
|
||||
private InputServerReference inputManagerGameobjectReference;
|
||||
|
||||
private InputManagerServer _inputManagerServer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
throw new NullReferenceException(
|
||||
$"The gameobject referenced by {inputManagerGameobjectReference.name} should have a InputManagerServer Component attached");
|
||||
if (inputManagerGameobjectReference.Value is not null)
|
||||
{
|
||||
_inputManagerServer = inputManagerGameobjectReference.Value.GetComponent<InputManagerServer>();
|
||||
}
|
||||
|
||||
if (_inputManagerServer is null)
|
||||
{
|
||||
throw new NullReferenceException(
|
||||
$"The gameobject referenced by {inputManagerGameobjectReference.name} should have a InputManagerServer Component attached");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Join(InputAction.CallbackContext context)
|
||||
{
|
||||
InputDevice device = context.control.device;
|
||||
|
||||
// CHECK IF MAPPED TO A PLAYER
|
||||
if (_inputManagerServer.GetPlayerFromDeviceId(device.deviceId) != PlayerEnum.None)
|
||||
public void Join(InputAction.CallbackContext context)
|
||||
{
|
||||
return;
|
||||
InputDevice device = context.control.device;
|
||||
|
||||
// CHECK IF MAPPED TO A PLAYER
|
||||
if (_inputManagerServer.GetPlayerFromDeviceId(device.deviceId) != PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TRY TO REGISTER IF THERE'S A SLOT FREE
|
||||
PlayerEnum player = _inputManagerServer.RegisterDevice(device.deviceId);
|
||||
if (player == PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
onJoinEvent.Raise((int)player);
|
||||
}
|
||||
|
||||
// TRY TO REGISTER IF THERE'S A SLOT FREE
|
||||
PlayerEnum player = _inputManagerServer.RegisterDevice(device.deviceId);
|
||||
if (player == PlayerEnum.None)
|
||||
public void Leave(InputAction.CallbackContext context)
|
||||
{
|
||||
return;
|
||||
}
|
||||
InputDevice device = context.control.device;
|
||||
PlayerEnum player = _inputManagerServer.GetPlayerFromDeviceId(device.deviceId);
|
||||
|
||||
onJoinEvent.Raise((int)player);
|
||||
}
|
||||
|
||||
|
||||
public void Leave(InputAction.CallbackContext context)
|
||||
{
|
||||
InputDevice device = context.control.device;
|
||||
PlayerEnum player = _inputManagerServer.GetPlayerFromDeviceId(device.deviceId);
|
||||
|
||||
if (player == PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_inputManagerServer.UnregisterDevice(device.deviceId);
|
||||
if (player == PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_inputManagerServer.UnregisterDevice(device.deviceId);
|
||||
|
||||
onLeaveEvent.Raise((int)player);
|
||||
onLeaveEvent.Raise((int)player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
Assets/Scripts/Conjure/Input/InputManager.cs
Normal file
24
Assets/Scripts/Conjure/Input/InputManager.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using Obvious.Soap;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Conjure.Input
|
||||
{
|
||||
public class InputManager : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField] private PlayerEnum player = PlayerEnum.Player1;
|
||||
[SerializeField] private Vector3Variable[] vectorVariables = new Vector3Variable[2];
|
||||
|
||||
[ReadOnly]
|
||||
[BoxGroup("Debug")]
|
||||
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
int id = context.control.device.deviceId;
|
||||
|
||||
Vector2 direction = context.action.ReadValue<Vector2>();
|
||||
vectorVariables[(int)player].Value = new Vector3(direction.x, 0, direction.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Assets/Scripts/Conjure/Input/MenuInputManager.cs
Normal file
86
Assets/Scripts/Conjure/Input/MenuInputManager.cs
Normal file
@ -0,0 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.UI;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
using InputDevice = UnityEngine.InputSystem.InputDevice;
|
||||
|
||||
namespace Conjure.Input
|
||||
{
|
||||
public class MenuInputManager : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField, Required] private InputSystemUIInputModule inputSystemUIInputModule;
|
||||
[SerializeField, Required] private InputServerReference inputServerReference;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>();
|
||||
}
|
||||
|
||||
public void OnJoin(int playerSeat)
|
||||
|
||||
{
|
||||
if (inputSystemUIInputModule.actionsAsset.devices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputManagerServer inputManagerServer = inputServerReference.Value.GetComponent<InputManagerServer>();
|
||||
|
||||
List<InputDevice> devices =
|
||||
new List<InputDevice>(inputSystemUIInputModule.actionsAsset.devices.Value.ToArray());
|
||||
|
||||
PlayerEnum player = inputManagerServer.GetPlayerFromInt(playerSeat);
|
||||
|
||||
// shouldn't be reachable
|
||||
if (player == PlayerEnum.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevice currentDevice = FindDeviceById(inputManagerServer.GetDeviceIdFromPlayerEnum(player));
|
||||
|
||||
// shouldn't be reachable
|
||||
if (currentDevice is not null)
|
||||
{
|
||||
devices.Add(currentDevice);
|
||||
}
|
||||
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>(devices.ToArray());
|
||||
}
|
||||
|
||||
public void OnLeave(int playerSeat)
|
||||
{
|
||||
if (inputSystemUIInputModule.actionsAsset.devices == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InputManagerServer inputManagerServer = inputServerReference.Value.GetComponent<InputManagerServer>();
|
||||
|
||||
if (playerSeat == 0 && inputManagerServer.GetNumberPlayers() == 0)
|
||||
{
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
InputDevice currentDevice = FindDeviceById(inputManagerServer.GetDeviceIdFromPlayerEnum(PlayerEnum.Player1));
|
||||
inputSystemUIInputModule.actionsAsset.devices = new ReadOnlyArray<InputDevice>(new []{currentDevice});
|
||||
}
|
||||
|
||||
private InputDevice FindDeviceById(int deviceId)
|
||||
{
|
||||
foreach (InputDevice currentDevice in InputSystem.devices)
|
||||
{
|
||||
if (currentDevice.deviceId == deviceId)
|
||||
{
|
||||
return currentDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Conjure.Input;
|
||||
using Obvious.Soap;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class InputManager : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField] private PlayerEnum player = PlayerEnum.Player1;
|
||||
[SerializeField] private Vector3Variable[] vectorVariables = new Vector3Variable[2];
|
||||
|
||||
[ReadOnly]
|
||||
[BoxGroup("Debug")]
|
||||
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
int id = context.control.device.deviceId;
|
||||
|
||||
Vector2 direction = context.action.ReadValue<Vector2>();
|
||||
vectorVariables[(int)player].Value = new Vector3(direction.x, 0, direction.y);
|
||||
}
|
||||
}
|
||||
35
Assets/Scripts/Conjure/JoinUi.cs
Normal file
35
Assets/Scripts/Conjure/JoinUi.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Conjure.Input;
|
||||
using Sirenix.OdinInspector;
|
||||
using Obvious.Soap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Conjure
|
||||
{
|
||||
public class JoinUi : SerializedMonoBehaviour
|
||||
{
|
||||
[SerializeField, ReadOnly] private InputManagerServer inputManagerServer;
|
||||
[SerializeField, Required] private InputServerReference inputManagerGameobjectReference;
|
||||
[SerializeField, Required] private EventListenerNoParam OnUpdateEvent;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (inputManagerGameobjectReference is null)
|
||||
{
|
||||
throw new NullReferenceException($"inputManagerGameobjectReference shouldn't be null on {transform.name}");
|
||||
}
|
||||
if (inputManagerGameobjectReference.Value is null)
|
||||
{
|
||||
throw new NullReferenceException($"inputManagerGameobjectReference shouldn't be null on {inputManagerGameobjectReference.name}");
|
||||
}
|
||||
inputManagerServer = inputManagerGameobjectReference.Value.GetComponent<InputManagerServer>();
|
||||
|
||||
//OnUpdateEvent.OnEventRaised();
|
||||
}
|
||||
|
||||
private void UpdateVisual()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Conjure/JoinUi.cs.meta
Normal file
3
Assets/Scripts/Conjure/JoinUi.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cfeb73d1adc480bb87433ceaa1b5387
|
||||
timeCreated: 1699897492
|
||||
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
@ -12,9 +13,9 @@ namespace Conjure
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
public static void StartGame(SceneAsset scene)
|
||||
public static void StartGame(String scene)
|
||||
{
|
||||
SceneManager.LoadScene(scene.name);
|
||||
SceneManager.LoadScene(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,33 +82,33 @@ MonoBehaviour:
|
||||
m_Textures:
|
||||
blueNoise64LTex: {fileID: 0}
|
||||
bayerMatrixTex: {fileID: 0}
|
||||
m_PrefilteringModeMainLightShadows: 1
|
||||
m_PrefilteringModeAdditionalLight: 4
|
||||
m_PrefilteringModeAdditionalLightShadows: 1
|
||||
m_PrefilterXRKeywords: 0
|
||||
m_PrefilteringModeForwardPlus: 1
|
||||
m_PrefilteringModeDeferredRendering: 1
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 1
|
||||
m_PrefilterDebugKeywords: 0
|
||||
m_PrefilterWriteRenderingLayers: 0
|
||||
m_PrefilterHDROutput: 0
|
||||
m_PrefilterSSAODepthNormals: 0
|
||||
m_PrefilterSSAOSourceDepthLow: 0
|
||||
m_PrefilterSSAOSourceDepthMedium: 0
|
||||
m_PrefilterSSAOSourceDepthHigh: 0
|
||||
m_PrefilterSSAOInterleaved: 0
|
||||
m_PrefilterSSAOBlueNoise: 0
|
||||
m_PrefilterSSAOSampleCountLow: 0
|
||||
m_PrefilterSSAOSampleCountMedium: 0
|
||||
m_PrefilterSSAOSampleCountHigh: 0
|
||||
m_PrefilterDBufferMRT1: 0
|
||||
m_PrefilterDBufferMRT2: 0
|
||||
m_PrefilterDBufferMRT3: 0
|
||||
m_PrefilterSoftShadowsQualityLow: 0
|
||||
m_PrefilterSoftShadowsQualityMedium: 0
|
||||
m_PrefilterSoftShadowsQualityHigh: 0
|
||||
m_PrefilteringModeMainLightShadows: 3
|
||||
m_PrefilteringModeAdditionalLight: 3
|
||||
m_PrefilteringModeAdditionalLightShadows: 2
|
||||
m_PrefilterXRKeywords: 1
|
||||
m_PrefilteringModeForwardPlus: 0
|
||||
m_PrefilteringModeDeferredRendering: 0
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 0
|
||||
m_PrefilterDebugKeywords: 1
|
||||
m_PrefilterWriteRenderingLayers: 1
|
||||
m_PrefilterHDROutput: 1
|
||||
m_PrefilterSSAODepthNormals: 1
|
||||
m_PrefilterSSAOSourceDepthLow: 1
|
||||
m_PrefilterSSAOSourceDepthMedium: 1
|
||||
m_PrefilterSSAOSourceDepthHigh: 1
|
||||
m_PrefilterSSAOInterleaved: 1
|
||||
m_PrefilterSSAOBlueNoise: 1
|
||||
m_PrefilterSSAOSampleCountLow: 1
|
||||
m_PrefilterSSAOSampleCountMedium: 1
|
||||
m_PrefilterSSAOSampleCountHigh: 1
|
||||
m_PrefilterDBufferMRT1: 1
|
||||
m_PrefilterDBufferMRT2: 1
|
||||
m_PrefilterDBufferMRT3: 1
|
||||
m_PrefilterSoftShadowsQualityLow: 1
|
||||
m_PrefilterSoftShadowsQualityMedium: 1
|
||||
m_PrefilterSoftShadowsQualityHigh: 1
|
||||
m_PrefilterSoftShadows: 0
|
||||
m_PrefilterScreenCoord: 0
|
||||
m_PrefilterNativeRenderPass: 0
|
||||
m_PrefilterScreenCoord: 1
|
||||
m_PrefilterNativeRenderPass: 1
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ShadowCascades: 0
|
||||
|
||||
@ -82,33 +82,33 @@ MonoBehaviour:
|
||||
m_Textures:
|
||||
blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
|
||||
bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
|
||||
m_PrefilteringModeMainLightShadows: 1
|
||||
m_PrefilteringModeAdditionalLight: 4
|
||||
m_PrefilteringModeAdditionalLightShadows: 1
|
||||
m_PrefilterXRKeywords: 0
|
||||
m_PrefilteringModeForwardPlus: 1
|
||||
m_PrefilteringModeDeferredRendering: 1
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 1
|
||||
m_PrefilterDebugKeywords: 0
|
||||
m_PrefilterWriteRenderingLayers: 0
|
||||
m_PrefilterHDROutput: 0
|
||||
m_PrefilterSSAODepthNormals: 0
|
||||
m_PrefilterSSAOSourceDepthLow: 0
|
||||
m_PrefilterSSAOSourceDepthMedium: 0
|
||||
m_PrefilterSSAOSourceDepthHigh: 0
|
||||
m_PrefilterSSAOInterleaved: 0
|
||||
m_PrefilterSSAOBlueNoise: 0
|
||||
m_PrefilterSSAOSampleCountLow: 0
|
||||
m_PrefilterSSAOSampleCountMedium: 0
|
||||
m_PrefilterSSAOSampleCountHigh: 0
|
||||
m_PrefilterDBufferMRT1: 0
|
||||
m_PrefilterDBufferMRT2: 0
|
||||
m_PrefilterDBufferMRT3: 0
|
||||
m_PrefilterSoftShadowsQualityLow: 0
|
||||
m_PrefilterSoftShadowsQualityMedium: 0
|
||||
m_PrefilterSoftShadowsQualityHigh: 0
|
||||
m_PrefilteringModeMainLightShadows: 3
|
||||
m_PrefilteringModeAdditionalLight: 3
|
||||
m_PrefilteringModeAdditionalLightShadows: 2
|
||||
m_PrefilterXRKeywords: 1
|
||||
m_PrefilteringModeForwardPlus: 0
|
||||
m_PrefilteringModeDeferredRendering: 0
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 0
|
||||
m_PrefilterDebugKeywords: 1
|
||||
m_PrefilterWriteRenderingLayers: 1
|
||||
m_PrefilterHDROutput: 1
|
||||
m_PrefilterSSAODepthNormals: 1
|
||||
m_PrefilterSSAOSourceDepthLow: 1
|
||||
m_PrefilterSSAOSourceDepthMedium: 1
|
||||
m_PrefilterSSAOSourceDepthHigh: 1
|
||||
m_PrefilterSSAOInterleaved: 1
|
||||
m_PrefilterSSAOBlueNoise: 1
|
||||
m_PrefilterSSAOSampleCountLow: 1
|
||||
m_PrefilterSSAOSampleCountMedium: 1
|
||||
m_PrefilterSSAOSampleCountHigh: 1
|
||||
m_PrefilterDBufferMRT1: 1
|
||||
m_PrefilterDBufferMRT2: 1
|
||||
m_PrefilterDBufferMRT3: 1
|
||||
m_PrefilterSoftShadowsQualityLow: 1
|
||||
m_PrefilterSoftShadowsQualityMedium: 1
|
||||
m_PrefilterSoftShadowsQualityHigh: 1
|
||||
m_PrefilterSoftShadows: 0
|
||||
m_PrefilterScreenCoord: 0
|
||||
m_PrefilterNativeRenderPass: 0
|
||||
m_PrefilterScreenCoord: 1
|
||||
m_PrefilterNativeRenderPass: 1
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ShadowCascades: 0
|
||||
|
||||
@ -82,33 +82,33 @@ MonoBehaviour:
|
||||
m_Textures:
|
||||
blueNoise64LTex: {fileID: 0}
|
||||
bayerMatrixTex: {fileID: 0}
|
||||
m_PrefilteringModeMainLightShadows: 1
|
||||
m_PrefilteringModeAdditionalLight: 4
|
||||
m_PrefilteringModeAdditionalLightShadows: 1
|
||||
m_PrefilterXRKeywords: 0
|
||||
m_PrefilteringModeForwardPlus: 1
|
||||
m_PrefilteringModeDeferredRendering: 1
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 1
|
||||
m_PrefilterDebugKeywords: 0
|
||||
m_PrefilterWriteRenderingLayers: 0
|
||||
m_PrefilterHDROutput: 0
|
||||
m_PrefilterSSAODepthNormals: 0
|
||||
m_PrefilterSSAOSourceDepthLow: 0
|
||||
m_PrefilterSSAOSourceDepthMedium: 0
|
||||
m_PrefilterSSAOSourceDepthHigh: 0
|
||||
m_PrefilterSSAOInterleaved: 0
|
||||
m_PrefilterSSAOBlueNoise: 0
|
||||
m_PrefilterSSAOSampleCountLow: 0
|
||||
m_PrefilterSSAOSampleCountMedium: 0
|
||||
m_PrefilterSSAOSampleCountHigh: 0
|
||||
m_PrefilterDBufferMRT1: 0
|
||||
m_PrefilterDBufferMRT2: 0
|
||||
m_PrefilterDBufferMRT3: 0
|
||||
m_PrefilterSoftShadowsQualityLow: 0
|
||||
m_PrefilterSoftShadowsQualityMedium: 0
|
||||
m_PrefilterSoftShadowsQualityHigh: 0
|
||||
m_PrefilteringModeMainLightShadows: 0
|
||||
m_PrefilteringModeAdditionalLight: 1
|
||||
m_PrefilteringModeAdditionalLightShadows: 0
|
||||
m_PrefilterXRKeywords: 1
|
||||
m_PrefilteringModeForwardPlus: 0
|
||||
m_PrefilteringModeDeferredRendering: 0
|
||||
m_PrefilteringModeScreenSpaceOcclusion: 0
|
||||
m_PrefilterDebugKeywords: 1
|
||||
m_PrefilterWriteRenderingLayers: 1
|
||||
m_PrefilterHDROutput: 1
|
||||
m_PrefilterSSAODepthNormals: 1
|
||||
m_PrefilterSSAOSourceDepthLow: 1
|
||||
m_PrefilterSSAOSourceDepthMedium: 1
|
||||
m_PrefilterSSAOSourceDepthHigh: 1
|
||||
m_PrefilterSSAOInterleaved: 1
|
||||
m_PrefilterSSAOBlueNoise: 1
|
||||
m_PrefilterSSAOSampleCountLow: 1
|
||||
m_PrefilterSSAOSampleCountMedium: 1
|
||||
m_PrefilterSSAOSampleCountHigh: 1
|
||||
m_PrefilterDBufferMRT1: 1
|
||||
m_PrefilterDBufferMRT2: 1
|
||||
m_PrefilterDBufferMRT3: 1
|
||||
m_PrefilterSoftShadowsQualityLow: 1
|
||||
m_PrefilterSoftShadowsQualityMedium: 1
|
||||
m_PrefilterSoftShadowsQualityHigh: 1
|
||||
m_PrefilterSoftShadows: 0
|
||||
m_PrefilterScreenCoord: 0
|
||||
m_PrefilterNativeRenderPass: 0
|
||||
m_PrefilterScreenCoord: 1
|
||||
m_PrefilterNativeRenderPass: 1
|
||||
m_ShaderVariantLogLevel: 0
|
||||
m_ShadowCascades: 0
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"com.unity.cinemachine": "2.9.7",
|
||||
"com.unity.collab-proxy": "2.1.0",
|
||||
"com.unity.collab-proxy": "2.2.0",
|
||||
"com.unity.connect.share": "4.2.3",
|
||||
"com.unity.feature.characters-animation": "1.0.0",
|
||||
"com.unity.feature.development": "1.0.1",
|
||||
"com.unity.ide.rider": "3.0.26",
|
||||
"com.unity.ide.visualstudio": "2.0.21",
|
||||
"com.unity.ide.visualstudio": "2.0.22",
|
||||
"com.unity.ide.vscode": "1.2.5",
|
||||
"com.unity.inputsystem": "1.7.0",
|
||||
"com.unity.localization": "1.4.5",
|
||||
@ -15,7 +15,7 @@
|
||||
"com.unity.render-pipelines.universal": "14.0.9",
|
||||
"com.unity.test-framework": "1.1.33",
|
||||
"com.unity.textmeshpro": "3.0.6",
|
||||
"com.unity.timeline": "1.7.5",
|
||||
"com.unity.timeline": "1.7.6",
|
||||
"com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.6",
|
||||
"com.unity.ugui": "1.0.0",
|
||||
"com.unity.visualscripting": "1.9.1",
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.addressables": {
|
||||
"version": "1.21.18",
|
||||
"version": "1.21.19",
|
||||
"depth": 1,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.scriptablebuildpipeline": "1.21.20",
|
||||
"com.unity.scriptablebuildpipeline": "1.21.21",
|
||||
"com.unity.modules.assetbundle": "1.0.0",
|
||||
"com.unity.modules.imageconversion": "1.0.0",
|
||||
"com.unity.modules.jsonserialize": "1.0.0",
|
||||
@ -50,7 +50,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.collab-proxy": {
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
@ -97,7 +97,7 @@
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.animation.rigging": "1.2.1",
|
||||
"com.unity.timeline": "1.7.5",
|
||||
"com.unity.timeline": "1.7.6",
|
||||
"com.unity.cinemachine": "2.9.5",
|
||||
"com.unity.formats.fbx": "4.2.1"
|
||||
}
|
||||
@ -107,8 +107,8 @@
|
||||
"depth": 0,
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.ide.visualstudio": "2.0.21",
|
||||
"com.unity.ide.rider": "3.0.25",
|
||||
"com.unity.ide.visualstudio": "2.0.22",
|
||||
"com.unity.ide.rider": "3.0.26",
|
||||
"com.unity.ide.vscode": "1.2.5",
|
||||
"com.unity.editorcoroutines": "1.0.0",
|
||||
"com.unity.performance.profile-analyzer": "1.2.2",
|
||||
@ -136,7 +136,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.ide.visualstudio": {
|
||||
"version": "2.0.21",
|
||||
"version": "2.0.22",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
@ -245,13 +245,13 @@
|
||||
"source": "builtin",
|
||||
"dependencies": {
|
||||
"com.unity.mathematics": "1.2.1",
|
||||
"com.unity.burst": "1.8.4",
|
||||
"com.unity.burst": "1.8.9",
|
||||
"com.unity.render-pipelines.core": "14.0.9",
|
||||
"com.unity.shadergraph": "14.0.9"
|
||||
}
|
||||
},
|
||||
"com.unity.scriptablebuildpipeline": {
|
||||
"version": "1.21.20",
|
||||
"version": "1.21.21",
|
||||
"depth": 2,
|
||||
"source": "registry",
|
||||
"dependencies": {},
|
||||
@ -327,7 +327,7 @@
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.timeline": {
|
||||
"version": "1.7.5",
|
||||
"version": "1.7.6",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
{
|
||||
"MonoBehaviour": {
|
||||
"Version": 3,
|
||||
"Version": 4,
|
||||
"EnableBurstCompilation": true,
|
||||
"EnableOptimisations": true,
|
||||
"EnableSafetyChecks": false,
|
||||
"EnableDebugInAllBuilds": false,
|
||||
"UsePlatformSDKLinker": false,
|
||||
"DebugDataKind": 0,
|
||||
"EnableArmv9SecurityFeatures": false,
|
||||
"CpuMinTargetX32": 0,
|
||||
"CpuMaxTargetX32": 0,
|
||||
"CpuMinTargetX64": 0,
|
||||
"CpuMaxTargetX64": 0,
|
||||
"CpuTargetsX32": 6,
|
||||
"CpuTargetsX64": 72
|
||||
"CpuTargetsX64": 72,
|
||||
"OptimizeFor": 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"MonoBehaviour": {
|
||||
"Version": 3,
|
||||
"Version": 4,
|
||||
"DisabledWarnings": ""
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ PlayerSettings:
|
||||
targetDevice: 2
|
||||
useOnDemandResources: 0
|
||||
accelerometerFrequency: 60
|
||||
companyName: DefaultCompany
|
||||
companyName: Conjure
|
||||
productName: Overmelted
|
||||
defaultCursor: {fileID: 0}
|
||||
cursorHotspot: {x: 0, y: 0}
|
||||
@ -48,6 +48,7 @@ PlayerSettings:
|
||||
defaultScreenHeightWeb: 600
|
||||
m_StereoRenderingPath: 0
|
||||
m_ActiveColorSpace: 1
|
||||
unsupportedMSAAFallback: 0
|
||||
m_SpriteBatchVertexThreshold: 300
|
||||
m_MTRendering: 1
|
||||
mipStripping: 0
|
||||
@ -563,7 +564,6 @@ PlayerSettings:
|
||||
switchScreenResolutionBehavior: 2
|
||||
switchUseCPUProfiler: 0
|
||||
switchEnableFileSystemTrace: 0
|
||||
switchUseGOLDLinker: 0
|
||||
switchLTOSetting: 0
|
||||
switchApplicationID: 0x01004b9000490000
|
||||
switchNSODependencies:
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
m_EditorVersion: 2022.3.11f1
|
||||
m_EditorVersionWithRevision: 2022.3.11f1 (d00248457e15)
|
||||
m_EditorVersion: 2022.3.13f1
|
||||
m_EditorVersionWithRevision: 2022.3.13f1 (5f90a5ebde0f)
|
||||
|
||||
@ -12,5 +12,6 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: de02f9e1d18f588468e474319d09a723, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
shaderVariantLimit: 128
|
||||
customInterpolatorErrorThreshold: 32
|
||||
customInterpolatorWarningThreshold: 16
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user