diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3b7888d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +## [1.0.0] - 2023-10-10 + +### First release of Shardy \ No newline at end of file diff --git a/CHANGELOG.md.meta b/CHANGELOG.md.meta new file mode 100644 index 0000000..e128513 --- /dev/null +++ b/CHANGELOG.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e0d7c4aaaa99b403e9b9da190915cb53 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0469674 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,44 @@ +# Code of Conduct - Shardy + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Any insults or humiliation based on nationality or actions related to collective responsibility +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at mail@mopsicus.ru. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version [1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and [2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md). \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md.meta b/CODE_OF_CONDUCT.md.meta new file mode 100644 index 0000000..f842f3e --- /dev/null +++ b/CODE_OF_CONDUCT.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 53a956e1e15f449b68fa769d028c4281 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..730dbd3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,92 @@ +# Contributing to Shardy + +First off, thanks for taking the time to contribute! โค๏ธ + +All types of contributions are encouraged and valued. See the sections below for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. ๐ŸŽ‰ + +> [!NOTE] +> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about: +> - Star the project +> - Tweet about it +> - Refer this project in your project's readme +> - Donate in any way convenient for you +> - Mention the project at local meetups and tell your friends/colleagues + +## Code of Conduct + +This project and everyone participating in it is governed by the [Shardy Code of Conduct](./CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to mail@mopsicus.ru. + +## I have a question + +Before you ask a question, it is best to search for existing [Issues](https://github.com/mopsicus/shardy-unity/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first. + +If you then still feel the need to ask a question and need clarification, we recommend the following: + +- Open an [Issue](https://github.com/mopsicus/shardy-unity/issues/new) +- Provide as much context as you can about what you're running into +- Provide project and platform versions (unity, android, ios, webgl, etc), depending on what seems relevant + +We will then take care of the issue as soon as possible. + +## Types of Contributions + +Thanks for taking the time to contribute, once again! Please check out the options for how you can start contributing. + +> [!IMPORTANT] +> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license. + +### Reporting Bugs + +A good bug report shouldnโ€™t leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible: + +- Make sure that you are using the latest version +- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions +- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/mopsicus/shardy-unity/issues?q=label%3Abug) +- Collect information about the bug: + - Stack trace (Traceback) + - OS, Platform and Version (Windows, Linux, macOS, x86, ARM) + - Unity version + - Platform target (Android, iOS, WebGL) + - Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant + - Possibly your input and the output + - Can you reliably reproduce the issue? And can you also reproduce it with older versions? + +### Suggesting Enhancements + +This section guides you through submitting an enhancement suggestion for Unity client for Shardy, including completely new features and minor improvements to existing functionality. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions. + +- Make sure that you are using the latest version +- Perform a [search](https://github.com/mopsicus/shardy-unity/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one +- Enhancement suggestions are tracked as [GitHub issues](https://github.com/mopsicus/shardy-unity/issues) +- Create new issue +- Use a **clear and descriptive title** for the issue to identify the suggestion +- Provide a **step-by-step description of the suggested enhancement** in as many details as possible +- **Explain why this enhancement would be useful** to most Shardy users. You may also want to point out the other projects that solved it better and which could serve as inspiration + +### Implementing Features + +Look through the [GitHub issues](https://github.com/mopsicus/shardy-unity/issues) for features. Anything tagged with "enhancement" is open to whoever wants to implement it. + +Ready to contribute? Here are the simple steps for local development: + +1. [Fork](https://github.com/mopsicus/shardy-unity/fork) the client for Shardy repo on GitHub +2. Clone your fork locally: + ``` + git clone git@github.com:YOUR_USERNAME/shardy-unity.git + ``` +3. Make sure you have the minimum 2022.3.x version of Unity installed +4. Create a branch for local development: + ``` + git checkout -b shardy-bugfix-or-feature + ``` +5. Implement what you wanted. Please make sure you add comments and stick to the existing code style +6. Use `.editorconfig` file to format and check warnings +7. Make sure there are no errors or warnings after assembly +8. Please, follow the [Conventional Commits](https://www.conventionalcommits.org), when you make a commit +9. Commit your changes and push your branch to GitHub: + ``` + git add . + git commit -m "feat(transport): Add UDP protocol" + git push origin shardy-bugfix-or-feature + ``` +10. Submit a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) through the GitHub website diff --git a/CONTRIBUTING.md.meta b/CONTRIBUTING.md.meta new file mode 100644 index 0000000..8ff0eec --- /dev/null +++ b/CONTRIBUTING.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9d61a1654618e42d1bf1a390f04257a9 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Documentation~/building.md b/Documentation~/building.md new file mode 100644 index 0000000..eec206f --- /dev/null +++ b/Documentation~/building.md @@ -0,0 +1,16 @@ +# ๐Ÿ‘พ Android and iOS + +There are no limitations for using Shardy on Android or iOS. You can create your own app for these platforms and be sure that everything will work well. + +Shardy uses the `IPv6` plugin on iOS to convert host and connection parameters. This is [required for AppStore](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW1) review, and your app may be rejected if you skip this step. + +In either case, you can use the [`TCP`](./reference.md#-transporttype) or `WebSocket` transport type as you see fit. + +# ๐Ÿ’ป WebGL + +Shardy can only work in WebGL builds with the [`WebSocket`](./reference.md#-websocket) transport, this is a limitation of Unity and C#. + +> [!IMPORTANT] +> You canโ€™t use any .NET networking classes within the Web platform because JavaScript code doesnโ€™t have direct access to internet protocol (IP) sockets to implement network connectivity. Specifically, Web doesnโ€™t support any .NET classes within the System.Net namespace. [Read Unity docs](https://docs.unity3d.com/Manual/webgl-networking.html). + +Since the `System.Net.Sockets` namespace is not supported on this platform, you cannot use the built-in WebSockets. To solve this "snag", Shardy uses a JavaScript plugin under the hood for WebGL builds, but everything is available from C# for the developer. Just use [`TransportType.WebSocket`](./reference.md#-transporttype) for your clients and services. diff --git a/Documentation~/index.md b/Documentation~/index.md new file mode 100644 index 0000000..a0fe286 --- /dev/null +++ b/Documentation~/index.md @@ -0,0 +1,53 @@ +# ๐Ÿ’ฌ What is Shardy? + +- [Overview](./overview.md#-overview) +- [For whom and why](./overview.md#-for-whom-and-why) +- [Why should I use it](./overview.md#-why-should-i-use-it) +- [Plans](./overview.md#-plans) + +# ๐Ÿš€ Getting started + +- [Welcome to Shardy](./welcome.md#-welcome-to-shardy) +- [Validator](./welcome.md#-validator) +- [Serializer](./welcome.md#-serializer) +- [Run HelloWorld](./welcome.md#-run-helloworld) +- [Debug and logging](./welcome.md#-debug-and-logging) + +# ๐Ÿ•น๏ธ Using + +- [Connecting to server](./using.md#-connecting-to-server) +- [Make request](./using.md#-make-request) +- [Send command](./using.md#-send-command) +- [Subscribe on command](./using.md#-subscribe-on-command) +- [Subscribe on request](./using.md#-subscribe-on-request) + +# ๐Ÿ—๏ธ Building + +- [Android and iOS](./building.md#-android-and-ios) +- [WebGL](./building.md#-webgl) + +# ๐Ÿ“‘ Reference + +- [Block](./reference.md#๏ธ-block) +- [BlockData](./reference.md#๏ธ-blockdata) +- [BlockType](./reference.md#๏ธ-blocktype) +- [Client](./reference.md#-client) +- [ClientOptions](./reference.md#-clientoptions) +- [Commander](./reference.md#-commander) +- [Connection](./reference.md#-connection) +- [DisconnectReason](./reference.md#-disconnectreason) +- [ISerializer](./reference.md#๏ธ-iserializer) +- [IValidator](./reference.md#-ivalidator) +- [Logger](./reference.md#-logger) +- [Payload](./reference.md#-payload) +- [PayloadData](./reference.md#-payloaddata) +- [PayloadType](./reference.md#-payloadtype) +- [Protocol](./reference.md#๏ธ-protocol) +- [Pulse](./reference.md#-pulse) +- [ReceivedData](./reference.md#-receiveddata) +- [Transport](./reference.md#-transport) +- [TransportType](./reference.md#-transporttype) +- [Utils](./reference.md#๏ธ-utils) +- [ValidatorState](./reference.md#๏ธ-validatorstate) +- [WebSocket](./reference.md#๏ธ-websocket) +- [WebSocketManager](./reference.md#๏ธ-websocketmanager) \ No newline at end of file diff --git a/Documentation~/overview.md b/Documentation~/overview.md new file mode 100644 index 0000000..6cf1255 --- /dev/null +++ b/Documentation~/overview.md @@ -0,0 +1,44 @@ +# ๐Ÿ’ฌ Overview + +This package is a Unity client for Shardy. It provides RPC framework with simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. + +[Shardy](https://github.com/mopsicus/shardy) is a server framework for online games and applications for Node.js. It provides the basic development framework for building microservices solutions: mobile, social, web, multiplayer games, realtime applications, chats, middleware services, etc. + +The main goal of Shardy is to give simple free solution for building almost any kind of online project. ๐Ÿ’ช + +# ๐Ÿฅท For whom and why + +Shardy grew out of a few scripts for internal use, as is often the case. It was mostly used as a local game backend. It was inspired by a rather famous old project - Pomelo. The package format and general concept of the RPC framework were taken from there. New features were added - the code became more complex. In the end, it was decided to rewrite everything, add WebSocket support and share it. + +I made it alone, primarily for my own needs, after several iterations of rewriting the entire codebase ๐Ÿ˜„ I'm not claiming that Shardy will work for your project, but it's a really simple solution for adding multiplayer to your game. + +If you have minimal knowledge of Node.js and TypeScript, you can easily [launch your own service on Shardy](https://github.com/mopsicus/shardy-template) and use it as a server for your game or application. + +> [!NOTE] +> This package doesn't use any third-party libraries for its work. ๐Ÿ˜Ž + +# ๐Ÿš€ Why should I use it + +Start your project with Shardy and rest assured: + +- **easy to use:** work with a user-friendly API and don't worry about how it works under the hood +- **mobile platforms:** build your app for Android, iOS and WebGL from one network codebase +- **fast & lightweight:** core without any 3rd party libs, pure C# +- **full docs:** Shardy provides good docs with all necessary sections and API references, also all code is coverged by comments โœŒ๏ธ + +# ๐Ÿ—“๏ธ Plans + +The plans are truly grand! It is to create an ecosystem for developers who will be able to build their game backend out of existing Shardy services like bricks, and compose mobile clients from Shardy modules. + +First and foremost: +- base helpers +- binding UI +- event bus +- scene/screen manager +- localization +- sound manager +- ads manager + +All of these modules will be as separate packages. The list is endless. + +Also in the plans: writing tutorials, more examples and open source game. And don't forget to [read about server-side plans](https://github.com/mopsicus/shardy/blob/main/Documentation~/overview.md#-plans) ๐ŸŒ \ No newline at end of file diff --git a/Documentation~/reference.md b/Documentation~/reference.md new file mode 100644 index 0000000..a5a347c --- /dev/null +++ b/Documentation~/reference.md @@ -0,0 +1,1152 @@ +# ๐Ÿงฑ Block + +The `Block` is one of the main parts of Shardy - it encodes and decodes raw data. + +Block is composed of two parts: **header** and **body**. The header part describes type and length of the block while body contains the binary payload. + +## Structure + +*type* โ€“ block type, 1 byte +- 0x01: handshake โ€“ handshake request from client to server and handshake response +- 0x02: handshake acknowledgement โ€“ handshake acknowledgement on request +- 0x03: heartbeat โ€“ empty block for check connection heartbeat +- 0x04: data โ€“ block with some data +- 0x05: kick โ€“ disconnect signal + +*length* โ€“ length of body, 3 bytes big-endian integer + +*body* โ€“ binary payload + +All transmitted data encoded to byte array and decoded to [`BlockData`](#blockdata) in [Protocol](#๏ธ-protocol), from where it is futher passed to [Commander](#-commander). + +`Block` contains 3 static methods: + +```csharp +/// +/// Encode block for transporting +/// +/// First byte is type +/// Next - length, and data +/// +/// Block type: data, kick or heartbeat +/// Body to send +/// Encoded type + body +public static byte[] Encode(BlockType type, byte[] body); + +/// +/// Decode block data +/// +/// Buffer with data to decode +/// Result with type as BlockType and body as byte array +public static BlockData Decode(byte[] data); + +/// +/// Check received block +/// +/// Byte index for BlockType +/// Is correct block or not +public static bool Check(BlockType type); +``` + +## BlockData + +`BlockData` is the structure of a single received block of data. The `Protocol` receives the type of received block and switch [`ProtocolState`](#protocolstate) if necessary, or passes the data to the `Commander` for block processing, handshaking or disconnection. + +```csharp +/// +/// Block result after decode +/// +public struct BlockData { + + /// + /// Type of block + /// + public BlockType Type; + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Block type + /// Data for block + public BlockData(BlockType type, byte[] body) { + Type = type; + Length = body.Length; + Body = body; + } +} +``` + +## BlockType + +All received blocks are typed. There are now 5 types of blocks available, as described in [structure](#structure): + +```csharp +/// +/// Block type to encode +/// +public enum BlockType { + + /// + /// Handshake process + /// + Handshake, + + /// + /// Acknowledgement for success verify + /// + HandshakeAcknowledgement, + + /// + /// Ping + /// + Heartbeat, + + /// + /// Data for command, request, response + /// + Data, + + /// + /// Kick from server, disconnect + /// + Kick +} +``` + +# ๐Ÿ‘ค Client + +`Client` is the main class for connecting and interacting with Shardy-services. When you want to send a request, command or subscribe to an event from the server, you have to use the `Client` class. + +The `Client` constructor receives 4 parameters: + +- [validator](#-ivalidator) โ€“ an instance of your handshake validation class +- [serializer](#-iserializer) โ€“ an instance of your serializer data class +- [client options](#clientoptions) (optional) โ€“ connection params such as [transport type](#-transporttype) and timeouts +- handshake data (optional) โ€“ prepared handshake data to be sent after a successful connection + +```csharp +/// +/// Client constructor +/// +/// Validator +/// Serializer +/// Client options (optional) +/// Handshake after connect (optional) +public Client(IValidator validator, ISerializer serializer, ClientOptions options = null, byte[] handshake = null); +``` + +By default `Client` uses the `TCP` transport type, but this can be changed to `WebSocket` via [`ClientOptions`](#clientoptions). + +Read how to create a `Client` and connect to the Shardy-service in the [Run HelloWorld](./welcome.md#-run-helloworld) section or [Connecting to server](./using.md#-connecting-to-server) section. + +Available methods: + +```csharp +/// +/// Connect to server +/// +/// Host to connect +/// Port to connect +public async void Connect(string host, int port); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Send command (event) to server +/// +/// Command name +/// Payload data +public void Command(string command, byte[] data = null); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Answer from server +/// Request id +public int Request(string request, Action callback); + +/// +/// Send response on request from server +/// +/// Request data +/// Data +public void Response(PayloadData request, byte[] data = null); + +/// +/// Send error on request from server +/// +/// Request data +/// Error message or code +/// Data +public void Error(PayloadData request, string error, byte[] data = null); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Payload data +/// Answer from server +/// Request id +public int Request(string request, byte[] data, Action callback); + +/// +/// Cancel request manually +/// +/// Request id +public void CancelRequest(int id); + +/// +/// Handshake to verify connection +/// +/// Data for handshake +public void Handshake(byte[] body = null); + +/// +/// Subscribe on command from server +/// +/// Command name +/// Callback to action +public void On(string command, Action callback); + +/// +/// Unsubscribe from command +/// If callback is null -> clear all of them +/// +/// Command name +/// Callback to unsubscribe +public void Off(string command, Action callback = null); + +/// +/// Subscribe on request from server that wait response +/// +/// Request name +/// Callback to action +public void OnRequest(string request, Action callback); + +/// +/// Unsubscribe from request from server that wait response +/// +/// Request name +/// Callback to unsubscribe +public void OffRequest(string request); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +In addition, `Client` has three callbacks to manage connection and handshake statuses: + +```csharp +/// +/// Event on connected +/// +public Action OnConnect = delegate { }; + +/// +/// Event on disconnected +/// +public Action OnDisconnect = delegate { }; + +/// +/// Event when ready to work +/// +public Action OnReady = delegate { }; +``` + +There is also a property to check the current state of the connection: + +```csharp +/// +/// Is client connected +/// +public bool IsConnected; +``` + +## ClientOptions + +`ClientOptions` is used to pass pre-configured connection parameters to `Client`: + +- transport type โ€“ type of connection transport: tcp or websocket +- buffer size โ€“ lenght of loaded data +- request timeout โ€“ timeout (ms) for RPC requests +- pulse interval โ€“ interval (ms) for checking connection heartbeat + +```csharp +/// +/// Client and connection options +/// +public class ClientOptions { + + /// + /// Transport type: TCP or WebSocket + /// + public TransportType Type = TransportType.Tcp; + + /// + /// Transport buffer size + /// + public int BufferSize = 1024; + + /// + /// Timeout for RPC request (ms) + /// + public float RequestTimeout = 10000f; + + /// + /// Interval for checking server (ms) + /// + public float PulseInterval = 1000f; + + /// + /// Options constructor + /// + /// Transport type + public ClientOptions(TransportType type = TransportType.Tcp) { + Type = type; + } + + /// + /// Options constructor + /// + /// Transport type + /// Transport buffer size, Kb + /// Timeout for RPC request, ms + /// Interval for checking server, ms + public ClientOptions(TransportType type, int buffer, float timeout, float pulse) { + Type = type; + BufferSize = buffer; + RequestTimeout = timeout; + PulseInterval = pulse; + } +} +``` + +# ๐Ÿ”ฉ Commander + +The `Commander` is the next important part of Shardy โ€“ it controls how to receive and send blocks, what command or request to invoke, and when to disconnect a client or send a heartbeat. + +This is a private class for [`Client`](#-client) and all methods are not called directly, only from the `Client` instance. + +```csharp +/// +/// Start use +/// +public void Start(); + +/// +/// Add callback for request +/// +/// Request id +/// Request command +/// Request's params +/// Callback for request +void AddRequest(int id, string command, byte[] param, Action callback); + +/// +/// Remove request from list +/// +/// Request id +public void CancelRequest(int id); + +/// +/// Subscribe callback on command +/// +/// Command name +/// Callback for command +public void AddCommand(string command, Action callback); + +/// +/// Unsubscribe callback from command +/// If callback is null -> clear all of them +/// +/// Command name +/// Callback for command +public void CancelCommand(string command, Action callback); + +/// +/// Subscribe to request from server that wait response +/// +/// Request name +/// Callback on RPC +public void AddOnRequest(string request, Action callback); + +/// +/// Unsubscribe from request from server that wait response +/// +/// Request name +public void CancelOnRequest(string request); + +/// +/// Exec callback for RPC from server +/// +/// Request data +public void InvokeOnRequest(PayloadData payload); + +/// +/// Send handshake +/// +/// Data to handshake +public void Handshake(byte[] data); + +/// +/// Send acknowledge +/// +/// Data to acknowledge +public void Acknowledge(byte[] data); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Send command (event) to server with params +/// +/// Command name +/// Payload data +public void Command(string command, byte[] data); + +/// +/// Send request to server and wait response +/// +/// Request name +/// Payload data +/// Answer from server +/// Request id +public int Request(string request, byte[] data, Action callback); + +/// +/// Send response on request from server +/// +/// Request data +/// Data +public void Response(PayloadData request, byte[] data = null); + +/// +/// Send error on request from server +/// +/// Request data +/// Error message or code +/// Data +public void Error(PayloadData request, string error, byte[] data = null); + +/// +/// Clear all events +/// +public void Clear(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +# ๐ŸŒ Connection + +`ะกonnection` determines how to read and write to the socket depending on which [`TransportType`](#transporttype) is selected. + +`ะกonnection` is a private class used in [`Transport`](#-transport) to receive and send data. It also detects connection loss and converts IP to IPv6 on iOS clients. + +## DisconnectReason + +In normal cases, when a client disconnects, `Client` returns the disconnect code `Normal`. If disconnection occurs at the handshake stage, the `Handshake` code will be returned. + +```csharp +/// +/// Disconnect reasons +/// +public enum DisconnectReason { + + /// + /// Normal disconnect + /// + Normal, + + /// + /// Have no answer on ping command + /// + Timeout, + + /// + /// Handshake validation failed + /// + Handshake, + + /// + /// Server is closed` + /// + ServerDown, + + /// + /// Some error occurs + /// + Unknown +} +``` + +# ๐Ÿ—๏ธ ISerializer + +Shardy supports custom serialization of transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. `ISerializer` is just an interface for your own serializer implementation. + +The main goal of this class is to encode [`PayloadData`](#payloaddata) to byte array and decode it back. + +```csharp +/// +/// Serializer interface, uses in Payload +/// +public interface ISerializer { + + /// + /// Serialize data to byte array + /// + /// Target data + /// Encoded data + byte[] Encode(PayloadData body); + + /// + /// Deserialize data + /// + /// Encoded data + /// Data to use + PayloadData Decode(byte[] body); + +} +``` + +# ๐Ÿชช IValidator + +Shardy provides an interface for handshake validation. You can implement your own handshake data structure and validation for all stages. + +Encode and validate any client-side or server-side data in the handshake process to control connected users and allow or deny them to invoke commands. + +> [!IMPORTANT] +> If your implementation does not need to do a two-step handshake, you can set "stubs" on these methods. + +When a client connects to the server, it must successfully complete the handshake before it can begin. Shardy uses a two-step handshake for connections. + +Stages of handshake: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +```csharp +/// +/// Handshake interface for client-server validation +/// +public interface IValidator { + + /// + /// Validate acknowledgement data + /// + /// Data for validate + /// Validation result + ValidatorState VerifyAcknowledgement(byte[] body); + + /// + /// Get handshake data for send + /// + /// Data for handshake + /// Data for handshake + byte[] Handshake(byte[] body = null); + + /// + /// Get acknowledgement data for send + /// + /// Data from handshake + /// Data for acknowledge + byte[] Acknowledgement(byte[] body); + +} +``` + +## ValidatorState + +Each verify method must return a typed `ValidatorState` response after processing. + +```csharp +/// +/// Validator state +/// +public enum ValidatorState { + + /// + /// Handshake passed + /// + Success, + + /// + /// Handshake failed + /// + Failed +} +``` + +# ๐Ÿ“ Logger + +Shardy provides a simple built-in logger. This is a wrapper for the `Console.WriteLine` and `UnityEngine.Debug.Log` methods with a few useful additions. + +```csharp +/// +/// Log info +/// +/// Data to log +/// Log label +/// Log color +public static void Info(object data, string label = "", LogColor color = LogColor.Default); + +/// +/// Log warning +/// +/// Data to log +/// Log label +/// Log color +public static void Warning(object data, string label = "", LogColor color = LogColor.Yellow); + +/// +/// Log error +/// +/// Data to log +/// Log label +/// Log color +public static void Error(object data, string label = "", LogColor color = LogColor.Red); +``` + +`LogColor` is an enum associated with preset colors. These colors are chosen for better visualization in the Unity console. + +```csharp +/// +/// Get HEX color for log +/// +/// Color index +static string GetColor(LogColor color) { + return color switch { + LogColor.Red => "#EE4B2B", + LogColor.Orange => "#FFAC1C", + LogColor.Yellow => "#FFFF8F", + LogColor.Green => "#50C878", + LogColor.Blue => "#89CFF0", + LogColor.Purple => "#BF40BF", + _ => "#CCCCCC", + }; +} +``` + +# โ„น๏ธ Payload + +`Payload` is a static class that handles the encoding and decoding of raw data to and from [`PayloadData`](#payloaddata). It is a private class for [`Commander`](#-commander), which encodes data before sending it and decodes it after receiving it. + +```csharp +/// +/// Encode data for transfer +/// +/// Service serializer +/// Type of data +/// Request name +/// Request id +/// Data +/// Data +/// Encoded data +public static byte[] Encode(ISerializer serializer, PayloadType type, string name, int id, byte[] data, string error); + +/// +/// Decode received block +/// +/// Service serializer +/// Encoded data +/// Payload data to use in commander +public static PayloadData Decode(ISerializer serializer, byte[] data); + +/// +/// Check payload for available type +/// +/// Payload data to check +public static bool Check(PayloadData payload); +``` + +The `check` method controls that the received data is correct and available for processing. + +## PayloadData + +When [`Client`](#-client) receives data, `PayloadData` is the last structure of the entire data processing chain. `PayloadData` is the data containing the command/request meta-info and the received data, if it exists. The [`PayloadType`](#payloadtype) type in `PayloadData` determines how the data will be processed. + +```csharp +public struct PayloadData { + + /// + /// Type of data + /// + public PayloadType Type; + + /// + /// Command or request name + /// + public string Name; + + /// + /// Request id + /// + public int Id; + + /// + /// Data + /// + public byte[] Data; + + /// + /// Error message or code + /// + public string Error; + + /// + /// Constructor + /// + /// Payload type + /// Command or request name + /// Request id + /// Data + /// Error message or code + public PayloadData(PayloadType type, string name, int id, byte[] data, string error) { + Type = type; + Id = id; + Name = name; + Data = data; + Error = error; + } +} +``` + +## PayloadType + +The `PayloadType` defines how the data will be processed. + +```csharp +/// +/// Payload type command +/// +public enum PayloadType { + + /// + /// Request and expect answer + /// + Request, + + /// + /// Command without answer, event + /// + Command, + + /// + /// Response on request + /// + Response +} +``` + +# โ›“๏ธ Protocol + +`Protocol` is an another internal class that links [`Commander`](#-commander) with [`Transport`](#-transport) and determines state of app: start, handshake or work. Each received [`Block`](#-block) from [`Transport`](#-transport) is detected, decoded to `BlockData` and passed to the `Commander` depending on the current [`Protocol State`](#-protocolstate). + +`Commander` can invoke these public methods: + +```csharp +/// +/// Start protocol and transport +/// +public void Start() { + +/// +/// Send data to connection +/// +/// Serialized command data +public void Send(byte[] body); + +/// +/// Send heartbeat to connection +/// +public void Heartbeat(); + +/// +/// Send handshake to connection +/// +/// Handshake data +public void Handshake(byte[] body); + +/// +/// Send acknowledgement +/// +/// Acknowledge data +public void Acknowledge(byte[] body); + +/// +/// Disconnect from server +/// +public void Disconnect(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +## ProtocolState + +The `Commander` can only accept requests and commands if the client has passed the handshake and the protocol state is set to `Work`. + +```csharp +/// +/// Protocol state +/// +enum ProtocolState { + + /// + /// Init state, wait for handshake + /// + Start, + + /// + /// Handshake is in progress + /// + Handshake, + + /// + /// Work state after success handshake + /// + Work, + + /// + /// Protocol closed, any actions ignored + /// + Closed +} +``` + +# ๐Ÿ’“ Pulse + +`Pulse` is an internal class for handling the heartbeat of a connection. It uses param `PulseInterval` from the [`ClientOptions`](#clientoptions). + +When Shardy receives any command, handshake or heartbeat, the `checks` counter in `Pulse` is reset. Every `PulseInterval` this class checks the `checks` counter and if the counter value is greater than one, it invokes a callback to send a heartbeat. + +```csharp +/// +/// Reset timer when commands received +/// +public void Reset(); + +/// +/// Stop and switch off service +/// +public void Clear(); +``` + +The `Clear` method is used to stop the timer when the connection is destroyed. + +## ReceivedData + +`ReceivedData` is a temporary structure for received data. It is used in [`Connection`](#-connection) and [`Transport`](#-transport) to control the length of the received data. + +```csharp +/// +/// Data received from socket +/// +public struct ReceivedData { + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + +} +``` + +# ๐Ÿš„ Transport + +`Transport` is one of the main parts of Shardy โ€“ it controls how data will be sent and received. + +`Transport` receives data from [`Connection`](#-connection), determines the size of the [`Block`](#-block), checks its type, and starts receiving its entire length. Once received, it passes the data to [`Protocol`](#๏ธ-protocol). + +The [`Protocol`](#๏ธ-protocol) can use these public methods or `Transport`: the `start` method is used to set initial state and begin receiveing data, the `dispatch` method is used to send data, the `close` method is used to terminate transmission, and the `destroy` method is used when the connection is destroyed. + +```csharp +/// +/// Start receiving data +/// +public void Start(); + +/// +/// Send data to socket +/// +/// Bytes array +public async void Dispatch(byte[] buffer); + +/// +/// Close this transport +/// +public void Close(); + +/// +/// Destroy all +/// +public void Destroy(); +``` + +Under the hood, the `Transport` monitors its `TransportState` and reads the right part of the data or stops the transmission. + +```csharp +/// +/// Transporter state +/// +enum TransportState { + + /// + /// Receive head data + /// + Head, + + /// + /// Receive body data + /// + Body, + + /// + /// Transport is closed, no more data received + /// + Closed +} +``` + +## TransportType + +Shardy can work with `TCP` sockets or `WebSockets`. When you configure your client, pass the desired transport type via [`ClientOptions`](#clientoptions). + +```csharp +/// +/// Type of transport +/// +public enum TransportType { + + /// + /// TCP sockets transport + /// + Tcp, + + /// + /// Websockets transport + /// + WebSocket +} +``` + +# ๐Ÿ› ๏ธ Utils + +`Utils` is a small static class with a few useful functions. + +```csharp +/// +/// Custom timer for WebGL compatibility +/// +/// Interval for timer, ms +/// Cancellation source +/// Callback on tick +public static async Task SetTimer(float interval, CancellationTokenSource cancellation, Action callback); + +/// +/// Make delay +/// Hack to prevent using Task.Delay in WebGL +/// +/// Delay in ms +public static async Task SetDelay(float delay); + +/// +/// Extension to add cancellation for task +/// +public static async Task WithCancellation(this Task task, CancellationToken cancellationToken); + +/// +/// Extension to add cancellation for task +/// +public static async Task WithCancellation(this Task task, CancellationToken cancellationToken); + +/// +/// Convert data to string +/// +public static string DataToString(byte[] data); + +/// +/// Convert data to log string +/// +public static string DataToDebug(byte[] data); + +/// +/// Escape string for log +/// +/// Input string +static string ToLiteral(string data); +``` + +# ๐Ÿ”Œ WebSocket + +`WebSocket` class is used only for [WebGL](./building.md#-webgl) builds. This is a wrapper for JS plugin and used in [`WebSocketManager`](#๏ธ-websocketmanager) as an unit for websocket connections. + +> [!NOTE] +> When you create an app with the WebSocket transport type on Android or iOS, a native implementation of WebSocket is used. + +Available methods: + +```csharp +/// +/// Create websocket +/// +public WebSocket(); + +/// +/// Create websocket +/// +/// Optional subprotocol +public WebSocket(string subprotocol); + +/// +/// Create websocket +/// +/// Optional subprotocols list +public WebSocket(List subprotocols); + +/// +/// Current state +/// +public WebSocketStateCode State; + +/// +/// Connect to server +/// +public async Task Connect(string url); + +/// +/// Close connection +/// +/// Close code +/// Reason +public bool Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) +; +/// +/// Send data as buffer +/// +/// Array of bytes +public async Task Send(byte[] data); + +/// +/// Receive data from socket +/// +/// Buffer to write +/// Received length +public async Task Receive(byte[] buffer); +``` + +It also uses the standard WebSocket status and error codes: + +```csharp +/// +/// Websocket state codes +/// +enum WebSocketStateCode { + Connecting, + Open, + Closing, + Closed, + Error +} + +/// +/// Return error codes +/// +enum WebSocketErrorCode { + NotFound = -1, + AlreadyConnected = -2, + NotConnected = -3, + AlreadyClosing = -4, + AlreadyClosed = -5, + NotOpened = -6, + CloseFail = -7, + SendFail = -8, + Unknown = -999 +} + +/// +/// Websocket code for close +/// +enum WebSocketCloseCode { + NotSet = 0, + Normal = 1000, + Away = 1001, + ProtocolError = 1002, + UnsupportedData = 1003, + Undefined = 1004, + NoStatus = 1005, + Abnormal = 1006, + InvalidData = 1007, + PolicyViolation = 1008, + TooBig = 1009, + MandatoryExtension = 1010, + ServerError = 1011, + TlsHandshakeFailure = 1015 +} +``` + +# ๐ŸŽ›๏ธ WebSocketManager + +`WebSocketManager` is a static private class for managing all [`WebSocket`](#-websocket) connections, only for WebGL builds. + +`WebSocketManager` creates websockets in the JS plugin, sets identifiers and callbacks from the plugin to the C# wrapper. + +```csharp +/// +/// Set debug mode +/// +public static void SetDebug(bool value); + +/// +/// Set callbacks +/// +public static void Init(); + +/// +/// Add new socket +/// +/// Websocket instance +/// Id +public static int Add(WebSocket socket); + +/// +/// Remove websocket instance +/// +/// Instance id +public static void Destroy(int id); +``` + +`SetDebug` takes the value `true` if the `SHARDY_DEBUG_RAW` condition is enabled. \ No newline at end of file diff --git a/Documentation~/using.md b/Documentation~/using.md new file mode 100644 index 0000000..5d19be7 --- /dev/null +++ b/Documentation~/using.md @@ -0,0 +1,153 @@ +# ๐ŸŒ Connecting to server + +To connect to the Shardy-service you have to use [`Client`](./reference.md#-client) class. Client's contructor receives some params: + +- [validator](./reference.md#-ivalidator) โ€“ custom validation class for handshake stages +- [serializer](./reference.md#-iserializer) โ€“ custom serializer of all transmitted data +- [options](./reference.md#clientoptions) (optional) โ€“ connection parameters, such as transport type and timeouts +- handshake (optional) โ€“ handshake data could be passed as last param + +> [!IMPORTANT] +> Make sure the serializer and handshake validator are the same as the service you are connecting to. + +When `Client` is created, add callbacks for events and call `connect` to connect to the server. + +```csharp +_client = new Client(new MyHandshake(), new MySerializer()); +_client.OnConnect += OnConnect; +_client.OnDisconnect += OnDisconnect; +_client.OnReady += OnReady; + +void OnConnect(bool status) { +// connect event +// status is a flag indicating whether the connection is successful or not + +// here you can send the handshake data if it was not passed through constructor +// +// if handshake data passed through constructor you shouldn't invoke Handshake() method manually + if (status) { + var data = Encoding.UTF8.GetBytes("handshake_data"); + _client.Handshake(data); + } +} + +void OnDisconnect(DisconnectReason reason) { +// disconnect event with reason +} + +void OnReady() { +// ready event, client has successfully completed the handshake +// +// ready for receive and send data +} + +_client.Connect("127.0.0.1", 30000); +``` + +# โ›“๏ธ Make request + +> [!NOTE] +> The general difference between requests and commands that is other side must respond to requests and doesn't respond to commands. So this means that when you make a request, you have a callback with response data. And when you send a command, you are simply notifying the other side about something. + +To make a request - just use the `Request` method of the [`Client`](./reference.md#-client) and pass the name of the request: + +```csharp +_client.Request("test", (response) => { + Console.WriteLine($"received test data: ${response.ToString()}"); +}); +``` + +The second parameter is a callback with response data. You can use it as a lambda expression, as in the snippet above, or make an external method for it: + +```csharp +_client.Request("test", OnTest); + +void OnTest(PayloadData data) { + Console.WriteLine($"received test data: ${response.ToString()}"); +} +``` + +If the service does not respond or the request takes too long to complete, you will get an error in [`PayloadData`](./reference.md#payloaddata). The `Error` property is usually empty, but if an error occurred, it contains an error code or message. + +And of course you can make requests with param: + +```csharp +var data = Encoding.UTF8.GetBytes("some_data"); +_client.Request("test", data, (response) => { + if (!string.IsNullOrEmpty(response.Error)) { + // handle error here + return; + } + Console.WriteLine($"received test data: ${response.ToString()}"); +}); +``` + +Shardy accept byte array as param, so you can pass any data to request. Make sure you can deserialize and read this data on the server side ๐Ÿ™„ + +# ๐Ÿ’จ Send command + +To send a command - use the `Command` method of the `Client` and pass the name of the command: + +```csharp +_client.Command("start"); +``` + +Sending command with param: + +```csharp +var data = Encoding.UTF8.GetBytes("some_data"); +_client.Command("start", data); +``` + +The command has no callback, you just send an event/notification and don't wait for a response. + +# ๐Ÿ“ญ Subscribe on command + +You can subscribe to a command from the server and process it each time it arrives. This is a popular method of updating data. + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +Also you can make an external method for it: + +```csharp +_client.On("lookup", OnLookup); + +void OnLookup(PayloadData data) { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +} +``` + +And you can unsubscribe from it and no longer process these events: + +```csharp +_client.Off("lookup", OnLookup); +``` + +# ๐Ÿ“ฎ Subscribe on request + +In rare cases you can make a request from the server to the client, this is also possible. When the server makes a request, it waits for a response, so the client must respond when it receives it, otherwise the server will timeout. + +To subscribe to a request, use the `OnRequest` method: + +```csharp +_client.OnRequest("status", (data) => { + Console.WriteLine($"received request data: ${data.ToString()}"); + // if comment lines below, you will give timeout on your backend + _client.Response(data, Encoding.UTF8.GetBytes("some_data_from_client")); + // or you can send error on received request + _client.Error(data, "error_code"); +}); +``` + +> [!IMPORTANT] +> When you make a response or send an error to a received request from the server, you must pass the received payload data as the first parameter because it contains the necessary data from the request. + +And you can also unsubscribe from it: + +```csharp +_client.OffRequest("status", OnRequestCallback); +``` \ No newline at end of file diff --git a/Documentation~/welcome.md b/Documentation~/welcome.md new file mode 100644 index 0000000..0ba595c --- /dev/null +++ b/Documentation~/welcome.md @@ -0,0 +1,130 @@ +# ๐Ÿ™Œ Welcome to Shardy + +Shardy is a simple backend framework for Node.js written on TypeScript. + +This package is a Unity client for Shardy. It provides an RPC framework with a simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. It uses its own transport package structure, handshake stages, and custom serializer. You can't use it without [Shardy backend](https://github.com/mopsicus/shardy) because all the features are designed to work in tandem. + +# ๐Ÿชช Validator + +Shardy provides a flexible handshake procedure: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +If your implementation does not need to do a two-step handshake, you can set "stubs" on these methods. [See demo](../Samples/Demo/) for that. The last step of the handshake procedure invokes `VerifyAcknowledgement` and returns [`ValidatorState`](./reference.md#validatorstate): success or failure, there you can set the stub if needed. + +Your handshake [validator](./reference.md#-ivalidator) class is passed to the [`Client`](./reference.md#-client) constructor as the first parameter, the next is the serializer. + +# ๐Ÿงฑ Serializer + +Shardy uses a custom serializer for all transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. You have to create your own serializer class by inheriting the [`Serializer`](./reference.md#-iserializer) class, implement encode/decode methods and pass it to your service and client. The main goal โ€“ encode [`PayloadData`](./reference.md#payloaddata) to byte array before sending and back after receiving. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to Buffer for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +I have plans to do some tutorials on the most popular serializers for Unity and their use with Shardy. Stay tuned. + +> [!IMPORTANT] +> Make sure your serialization and validation are the same on the server and client + +# โœจ Run HelloWorld + +Let's create a simple project. Do it in your favorite version of Unity, but don't use a version less than 2020.3.x :) + +1. Create project +2. Install Shardy + + Get it from [releases page](https://github.com/mopsicus/shardy-unity/releases) or add the line to `Packages/manifest.json` and module will be installed directly from Git url: + + ``` + "com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", + ``` + +3. Implement your validator and serializer classes +4. Create `Client` and connect to server + ```csharp + void Awake() { + _client = new Client(new MyValidator(), new MySerializer()); + ... + } + + void Connect() { + _client.Connect("127.0.0.1", 30000); + } + ``` + +5. Make a request or send command + ```csharp + void TestRequest() { + _client.Request("test", (response) => { + Console.WriteLine($"received test data: ${response.ToString()}"); + }); + } + ``` + +> [!NOTE] +> This is a simple example, of course, without a backend you cannot connect and send a command + +Read how to run the [test backend](https://github.com/mopsicus/shardy/blob/main/docs/service.md#-using-template) on Shardy and explore how to [make requests and handle errors](./using.md#๏ธ-make-request) in the Unity client. + +# ๐Ÿ“ Debug and logging + +Shardy uses its own static class [`Logger`](./reference.md#-logger) with several addons: + +1. Labeling +2. Time formatting +3. Coloring + +```csharp +public static void Info(object data, string label = "", LogColor color = LogColor.Default); +``` + +You can set a label/tag for your message to group them, and set a custom color if desired. Shardy logger contains the common methods: *info*, *warning* and *error*. + +The time format is pre-configured and is similar to a timestamp with a time zone: + +```csharp +/// +/// Date/time format for log +/// +const string DATE_FORMAT = "yyyy-MM-ddTHH:mm:ss.msZ"; +``` + +All debug outputs are wrapped with preprocessor directives and can be enabled or disabled. Add `SHARDY_DEBUG` to show all log messages without errors and stacktraces. For more detailed logs, add `SHARDY_DEBUG_RAW` to the project scripting define symbols. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..efde165 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2024 Mopsicus + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/LICENSE.md.meta b/LICENSE.md.meta new file mode 100644 index 0000000..2e9dbf9 --- /dev/null +++ b/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c761f20b47f5c464cb48979d9ec0ee71 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media.meta b/Media.meta new file mode 100644 index 0000000..0a65ed9 --- /dev/null +++ b/Media.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fb2be8439745a43cc961a5b591409bd7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/demo-app.png b/Media/demo-app.png new file mode 100644 index 0000000..83a0239 Binary files /dev/null and b/Media/demo-app.png differ diff --git a/Media/demo-app.png.meta b/Media/demo-app.png.meta new file mode 100644 index 0000000..6a74e07 --- /dev/null +++ b/Media/demo-app.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 732010a06c6444e69a13614d173e17b7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 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: iPhone + 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: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/logo-unity-dark.png b/Media/logo-unity-dark.png new file mode 100644 index 0000000..b22129c Binary files /dev/null and b/Media/logo-unity-dark.png differ diff --git a/Media/logo-unity-dark.png.meta b/Media/logo-unity-dark.png.meta new file mode 100644 index 0000000..d97d95d --- /dev/null +++ b/Media/logo-unity-dark.png.meta @@ -0,0 +1,133 @@ +fileFormatVersion: 2 +guid: 3a8267927db1849d7b284d163a93e5a6 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 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 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/logo-unity.png b/Media/logo-unity.png new file mode 100644 index 0000000..89aee66 Binary files /dev/null and b/Media/logo-unity.png differ diff --git a/Media/logo-unity.png.meta b/Media/logo-unity.png.meta new file mode 100644 index 0000000..4b9bb99 --- /dev/null +++ b/Media/logo-unity.png.meta @@ -0,0 +1,133 @@ +fileFormatVersion: 2 +guid: c641f4be3553c4aeb991a6f152ccfa2b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 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 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: iPhone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Media/tic-tac-toe.png b/Media/tic-tac-toe.png new file mode 100644 index 0000000..f1067a9 Binary files /dev/null and b/Media/tic-tac-toe.png differ diff --git a/Media/tic-tac-toe.png.meta b/Media/tic-tac-toe.png.meta new file mode 100644 index 0000000..0dab28e --- /dev/null +++ b/Media/tic-tac-toe.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: a76f3d6023e554561b6c086620fe3d81 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 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: iPhone + 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: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c2e4b6 --- /dev/null +++ b/README.md @@ -0,0 +1,209 @@ +![Static Badge](https://img.shields.io/badge/english-118027) +![Static Badge](https://img.shields.io/badge/russian-0390fc) +

+ + + + Unity client Shardy + +

+

Unity client for Shardy

+

Framework for games and apps

+

+ Quick start ยท Docs ยท Shardy ยท Service template ยท Report Bug +

+ +# ๐Ÿ’ฌ Overview + +This package is a Unity client for Shardy. It provides RPC framework with simple user-friendly API: requests, commands and subscribe for communication with Shardy microservices. + +Shardy is a framework for online games and applications for Node.js. It provides the basic functionality for building microservices solutions: mobile, social, web, multiplayer games, realtime applications, chats, middleware services, etc. + +[Read about Shardy](https://github.com/mopsicus/shardy) ๐Ÿ’ช + +# โœจ Features + +- Simple API: request, response, subscribe, etc +- Socket and Websocket communication +- iOS, Android and WebGL support +- Lightweight and fast +- Support custom serialization +- Support custom handshake validation +- Connection heartbeat support +- Good reference materials: docs, snippets, samples +- No 3rd party libs + +# ๐Ÿš€ Usage + +### Installation + +Get it from [releases page](https://github.com/mopsicus/shardy-unity/releases) or add the line to `Packages/manifest.json` and module will be installed directly from Git url: + +``` +"com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", +``` + +### Environment setup + +For a better experience, you can set up an environment for local development. Since Shardy is developed with VS Code, all settings are provided for it. + +1. Use `Monokai Pro` or `eppz!` themes +2. Use `FiraCode` font +3. Install extensions: + - C# + - C# Dev Kit + - Unity +4. Enable `Inlay Hints` in C# extension +5. Install `Visual Studio Editor` package in Unity +6. Put `.editorconfig` in root project directory +7. Be cool + +### Quick start + +See the sample section to get a [demo app](./Samples~/Demo). This demo shows you how to use client's methods and options. If you want to test your own demo backend, see how to install and launch [service template](https://github.com/mopsicus/shardy-template). + +_Tested in Unity 2022.3.x, Android, iOS and WebGL._ + +

+ + Demo on Shardy + +

+ +### Tic-Tac-Toe + +Also, in sample section you can get [Tic-Tac-Toe](./Samples~/TicTacToe) multiplayer online game example. Explore the example to get in mind how you can organize your client-server communation and how to start developing your new multiplayer game or add a multiplayer feature to an existing game. + +

+ + Tic-Tac-Toe on Shardy + +

+ +See the [game server](https://github.com/mopsicus/shardy-tictactoe) for Tic-Tac-Toe. Get a simplest server example made on Shardy for testing and development. + +### Requests and commands + +The general difference between requests and commands that is other side must respond to requests and doesn't respond to commands. So this means that when you make a request, you have a callback with response data. And when you send a command, you are simply notifying the other side about something. + +Request: + +```csharp +_client.Request("test", (data) => { + Console.WriteLine($"received test data: ${data.ToString()}"); +}); +``` + +Command: + +```csharp +_client.Command("start"); +``` + +Subscribe: + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +Subscribe on request: + +```csharp +_client.OnRequest(request, (payload) => { + Console.WriteLine($"received request data: ${payload.ToString()}"); + // if comment line below, you will give timeout on your backend + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); +}); +``` + +### Validation + +When a client connects to the server, it must successfully complete the handshake before it can begin. Shardy uses a two-step handshake for connections. + +Stages of handshake: + +1. The client sends a handshake to the server +2. Server receives and verifies it: + - Sends an acknowledgement to the client + - Disconnects the client, if the verification fails +3. The client receives the acknowledgement and verifies it: + - Sends a reply acknowledgement to the server + - Disconnects, if the verification fails +4. After verifying the handshake and acknowledgement, the client and server can communicate with each other + +If your implementation doesn't need to do a two-step handshake, you can set "stubs" on these methods. + +Shardy provides an interface for handshake validation. You can implement your own handshake data structure and validation for all these stages. Create your validator class, implement `IValidator` interface methods and pass it to your service and client. + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +### Serialization + +Shardy supports custom serialization of transmitted data. You can use JSON, MessagePack, Protobuf, FlatBuffers, etc. or your own serializer. + +Create your serializer class, implement `ISerializer` methods and pass it to your service and client. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to byte array for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +See [documentation](./Documentation~/index.md) for information on all classes and methods. + +# ๐Ÿ—๏ธ Contributing + +We invite you to contribute and help improve Unity client for Shardy. Please see [contributing document](./CONTRIBUTING.md). ๐Ÿค— + +You also can contribute to the Shardy project by: + +- Helping other users +- Monitoring the issue queue +- Sharing it to your socials +- Referring it in your projects + +# ๐Ÿค Support + +You can support Shardy by using any of the ways below: + +* Bitcoin (BTC): 1VccPXdHeiUofzEj4hPfvVbdnzoKkX8TJ +* USDT (TRC20): TMHacMp461jHH2SHJQn8VkzCPNEMrFno7m +* TON: UQDVp346KxR6XxFeYc3ksZ_jOuYjztg7b4lEs6ulEWYmJb0f +* Visa, Mastercard via [Boosty](https://boosty.to/mopsicus/donate) +* MIR via [CloudTips](https://pay.cloudtips.ru/p/9f507669) + +# โœ‰๏ธ Contact + +Before you ask a question, it is best to search for existing [issues](https://github.com/mopsicus/shardy-unity/issues) that might help you. Anyway, you can ask any questions and send suggestions by [email](mailto:mail@mopsicus.ru) or [Telegram](https://t.me/mopsicus). + +# ๐Ÿ”‘ License + +Unity client for Shardy is licensed under the [MIT License](./LICENSE.md). Use it for free and be happy. ๐ŸŽ‰ \ No newline at end of file diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..2a6d9da --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7a3a2e11d4d2e4995929fcf1bce9a6b3 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..add2887 --- /dev/null +++ b/README.ru.md @@ -0,0 +1,209 @@ +![Static Badge](https://img.shields.io/badge/english-118027) +![Static Badge](https://img.shields.io/badge/russian-0390fc) +

+ + + + Unity ะบะปะธะตะฝั‚ Shardy + +

+

Unity ะบะปะธะตะฝั‚ ะดะปั Shardy

+

ะคั€ะตะนะผะฒะพั€ะบ ะดะปั ะธะณั€ ะธ ะฟั€ะธะปะพะถะตะฝะธะน

+

+ ะ‘ั‹ัั‚ั€ั‹ะน ัั‚ะฐั€ั‚ ยท ะ”ะพะบัƒะผะตะฝั‚ะฐั†ะธั ยท Shardy ยท ะŸั€ะธะผะตั€ ัะตั€ะฒะธัะฐ ยท ะžั‚ั‡ั‘ั‚ ะพะฑ ะพัˆะธะฑะบะต +

+ +# ๐Ÿ’ฌ ะžะฟะธัะฐะฝะธะต + +ะญั‚ะพ Unity ะบะปะธะตะฝั‚ ะดะปั Shardy. ะžะฝ ะฟั€ะตะดะพัั‚ะฐะฒะปัะตั‚ RPC-ั„ั€ะตะนะผะฒะพั€ะบ ั ะฟั€ะพัั‚ั‹ะผ ะธ ัƒะดะพะฑะฝั‹ะผ API: ะทะฐะฟั€ะพัั‹, ะบะพะผะฐะฝะดั‹ ะธ ะฟะพะดะฟะธัะบะธ ะดะปั ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะธั ั Shardy-ัะตั€ะฒะธัะฐะผะธ. + +Shardy โ€“ ัั‚ะพ ั„ั€ะตะนะผะฒะพั€ะบ ะดะปั ะพะฝะปะฐะนะฝ ะธะณั€ ะธ ะฟั€ะธะปะพะถะตะฝะธะน ะฝะฐ Node.js. ะžะฝ ะฟั€ะตะดะพัั‚ะฐะฒะปัะตั‚ ะฑะฐะทะพะฒัƒัŽ ั„ัƒะฝะบั†ะธะพะฝะฐะปัŒะฝะพัั‚ัŒ ะดะปั ะฟะพัั‚ั€ะพะตะฝะธั ะผะธะบั€ะพัะตั€ะฒะธัะฝั‹ั… ั€ะตัˆะตะฝะธะน: ะผะพะฑะธะปัŒะฝั‹ั…, ัะพั†ะธะฐะปัŒะฝั‹ั…, ะฒะตะฑ, ะผะฝะพะณะพะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะธั… ะธะณั€, ะฟั€ะธะปะพะถะตะฝะธะน ั€ะตะฐะปัŒะฝะพะณะพ ะฒั€ะตะผะตะฝะธ, ั‡ะฐั‚ะพะฒ, middleware ัะตั€ะฒะธัะพะฒ ะธ ั‚.ะฟ. + +[ะฃะทะฝะฐั‚ัŒ ะฟั€ะพ Shardy](https://github.com/mopsicus/shardy) ๐Ÿ’ช + +# โœจ ะ’ะพะทะผะพะถะฝะพัั‚ะธ + +- ะŸั€ะพัั‚ะพะน API: ะทะฐะฟั€ะพัั‹, ะบะพะผะฐะฝะดั‹, ะฟะพะดะฟะธัะบะธ ะธ ั‚.ะฟ. +- ะขั€ะฐะฝัะฟะพั€ั‚ ะดะฐะฝะฝั‹ั… ั‡ะตั€ะตะท ัะพะบะตั‚ั‹ ะธ ะฒะตะฑัะพะบะตั‚ั‹ +- iOS, Android ะธ WebGL ะฟะพะดะดะตั€ะถะบะฐ +- ะ›ะตะณะบะธะน ะธ ะฑั‹ัั‚ั€ั‹ะน +- ะŸะพะดะดะตั€ะถะบะฐ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะพะน ัะตั€ะธะฐะปะธะทะฐั†ะธะธ +- ะŸะพะดะดะตั€ะถะบะฐ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะพะน ะฒะฐะปะธะดะฐั†ะธะธ ั€ัƒะบะพะฟะพะถะฐั‚ะธะน (handshake) +- ะะฐัั‚ั€ะฐะธะฒะฐะตะผั‹ะน heartbeat ะดะปั ัะพะตะดะธะฝะตะฝะธั +- ะกะฟั€ะฐะฒะพั‡ะฝั‹ะต ะผะฐั‚ะตั€ะธะฐะปั‹: ะดะพะบัƒะผะตะฝั‚ะฐั†ะธั, ัะฝะธะฟะฟะตั‚ั‹, ะฟั€ะธะผะตั€ั‹ +- ะะต ะธัะฟะพะปัŒะทัƒัŽั‚ัั ัั‚ะพั€ะพะฝะฝะธะต ะฑะธะฑะปะธะพั‚ะตะบะธ + +# ๐Ÿš€ ะ˜ัะฟะพะปัŒะทะพะฒะฐะฝะธะต + +### ะฃัั‚ะฐะฝะพะฒะบะฐ + +ะกะบะฐั‡ะฐะนั‚ะต ะฟะฐะบะตั‚ ัะพ ัั‚ั€ะฐะฝะธั†ั‹ [ั€ะตะปะธะทะพะฒ](https://github.com/mopsicus/shardy-unity/releases) ะธะปะธ ะดะพะฑะฐะฒัŒั‚ะต ัั‚ั€ะพั‡ะบัƒ ะฝะธะถะต ะฒ ะฒะฐัˆ ั„ะฐะนะป `Packages/manifest.json` ะธ ะฟะฐะบะตั‚ ะฑัƒะดะตั‚ ัƒัั‚ะฐะฝะพะฒะปะตะฝ ะฟะพ ะฐะดั€ะตััƒ Git ั€ะตะฟะพะทะธั‚ะพั€ะธั: + +``` +"com.mopsicus.shardy": "https://github.com/mopsicus/shardy-unity.git", +``` + +### ะะฐัั‚ั€ะพะนะบะฐ ะพะบั€ัƒะถะตะฝะธั + +ะะฐัั‚ั€ะพะนั‚ะต ัะฒะพั‘ ะพะบั€ัƒะถะตะฝะธะต ะดะปั ะปะพะบะฐะปัŒะฝะพะน ั€ะฐะทั€ะฐะฑะพั‚ะบะธ ะดะปั ัƒะดะพะฑัั‚ะฒะฐ ะธ "ัะธะฝั…ั€ะพะฝะธะทะฐั†ะธะธ" ั ั‚ะตะบัƒั‰ะธะผ ะฟั€ะพะตะบั‚ะพะผ. ะขะฐะบ ะบะฐะบ Unity ะบะปะธะตะฝั‚ ะดะปั Shardy ั€ะฐะทั€ะฐะฑะฐั‚ั‹ะฒะฐะตั‚ัั ั ะธัะฟะพะปัŒะทะพะฒะฐะฝะธะตะผ ั€ะตะดะฐะบั‚ะพั€ะฐ VS Code, ั‚ะพ ะฒัะต ะฝะฐัั‚ั€ะพะนะบะธ ะธ ั€ะตะบะพะผะตะฝะดะฐั†ะธะธ ะฟั€ะตะดะปะพะถะตะฝั‹ ะดะปั ะฝะตะณะพ. + +1. ะ˜ัะฟะพะปัŒะทัƒะนั‚ะต `Monokai Pro` ะธะปะธ `eppz!` ั‚ะตะผัƒ +2. ะ˜ัะฟะพะปัŒะทัƒะนั‚ะต `FiraCode` ัˆั€ะธั„ั‚ +3. ะฃัั‚ะฐะฝะพะฒะธั‚ะต ั€ะฐััˆะธั€ะตะฝะธั: + - C# + - C# Dev Kit + - Unity +4. ะ’ะบะปัŽั‡ะธั‚ะต `Inlay Hints` ะฒ ะฝะฐัั‚ั€ะพะนะบะฐั… C# ั€ะฐััˆะธั€ะตะฝะธั +5. ะฃัั‚ะฐะฝะพะฒะธั‚ัŒ ะฟะฐะบะตั‚ `Visual Studio Editor` ะฒ ั€ะตะดะฐะบั‚ะพั€ะต Unity +6. ะŸะพะผะตัั‚ะธั‚ะต ั„ะฐะนะป `.editorconfig` ะฒ ะบะพั€ะฝะตะฒัƒัŽ ะฟะฐะฟะบัƒ ะฟั€ะพะตะบั‚ะฐ +7. ะฃั€ะฐ! + +### ะ‘ั‹ัั‚ั€ั‹ะน ัั‚ะฐั€ั‚ + +ะŸะพัะผะพั‚ั€ะธั‚ะต ั€ะฐะทะดะตะป ั ะฟั€ะธะผะตั€ะฐะผะธ ะธ ัะบะฐั‡ะฐะนั‚ะต [ะดะตะผะพ ะฟั€ะธะปะพะถะตะฝะธะต](./Samples~/Demo). ะญั‚ะพ ะดะตะผะพ ะฟะพะบะฐะถะตั‚ ะฒะฐะผ ะบะฐะบ ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ะผะตั‚ะพะดั‹ ะบะปะธะตะฝั‚ะฐ ะธ ะบะฐะบะธะต ะตัั‚ัŒ ะพะฟั†ะธะธ. ะ•ัะปะธ ะฒั‹ ั…ะพั‚ะธั‚ะต ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ ะดะปั ั‚ะตัั‚ะพะฒ ัะพะฑัั‚ะฒะตะฝะฝั‹ะน backend, ะฟะพัะผะพั‚ั€ะธั‚ะต ะบะฐะบ ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ ะธ ะทะฐะฟัƒัั‚ะธั‚ัŒ [ะฟั€ะธะผะตั€ ัะตั€ะฒะธัะฐ](https://github.com/mopsicus/shardy-template). + +_ะŸั€ะพั‚ะตัั‚ะธั€ะพะฒะฐะฝะพ ะฒ Unity 2022.3.x, Android, iOS ะธ WebGL._ + +

+ + Demo on Shardy + +

+ +### ะšั€ะตัั‚ะธะบะธ-ะะพะปะธะบะธ + +ะขะฐะบะถะต, ะธะท ั€ะฐะทะดะตะปะฐ ั ะฟั€ะธะผะตั€ะฐะผะธ ะฒั‹ ะผะพะถะตั‚ะต ะฒะทัั‚ัŒ ะดะตะผะพ ะบะปะธะตะฝั‚ะฐ ะดะปั ะผะฝะพะณะพะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบะพะน ะพะฝะปะฐะนะฝ ะธะณั€ั‹ [ะšั€ะตัั‚ะธะบะธ-ะะพะปะธะบะธ](./Samples~/TicTacToe). ะ˜ะทัƒั‡ะธั‚ะต ะฟั€ะธะผะตั€ ั‡ั‚ะพะฑั‹ ะฟะพะฝัั‚ัŒ, ะบะฐะบ ั€ะฐะฑะพั‚ะฐะตั‚ ะบะปะธะตะฝั‚-ัะตั€ะฒะตั€ะฝะพะต ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะธะต ะธ ะบะฐะบ ะฝะฐั‡ะฐั‚ัŒ ั€ะฐะทั€ะฐะฑะฐั‚ั‹ะฒะฐั‚ัŒ ัะฒะพัŽ ัะพะฑัั‚ะฒะตะฝะฝัƒัŽ ะพะฝะปะฐะนะฝ ะธะณั€ัƒ, ะธะปะธ ะบะฐะบ ะดะพะฑะฐะฒะธั‚ัŒ ะผัƒะปัŒั‚ะธะฟะปะตะตั€ ะฒ ัƒะถะต ััƒั‰ะตัั‚ะฒัƒัŽั‰ัƒัŽ. + +

+ + Tic-Tac-Toe on Shardy + +

+ +ะŸะพัะผะพั‚ั€ะธั‚ะต [ะฟั€ะธะผะตั€ ัะตั€ะฒะตั€ะฐ](https://github.com/mopsicus/shardy-tictactoe) ะดะปั ะธะณั€ั‹ ะšั€ะตัั‚ะธะบะธ-ะะพะปะธะบะธ. ะกะบะฐั‡ะฐะนั‚ะต, ะธะทัƒั‡ะธั‚ะต ะธ ะฟั€ะพั‚ะตัั‚ะธั€ัƒะนั‚ะต ะฟั€ะพัั‚ะพะน ะธะณั€ะพะฒะพะน ัะตั€ะฒะตั€ ัะดะตะปะฐะฝะฝั‹ะน ะฝะฐ Shardy. + +### ะ—ะฐะฟั€ะพัั‹ ะธ ะบะพะผะฐะฝะดั‹ + +ะ“ะปะฐะฒะฝะพะต ะพั‚ะปะธั‡ะธะต ะผะตะถะดัƒ ะทะฐะฟั€ะพัะฐะผะธ ะธ ะบะพะผะฐะฝะดะฐะผะธ โ€“ ัะตั€ะฒะตั€ะฝะฐั ัั‚ะพั€ะพะฝะฐ ะดะพะปะถะฝะฐ ะพั‚ะฒะตั‚ะธั‚ัŒ ะฝะฐ ะทะฐะฟั€ะพั ะธ ะฝะต ะดะพะปะถะฝะฐ ะฝะฐ ะบะพะผะฐะฝะดัƒ. ะญั‚ะพ ะพะทะฝะฐั‡ะฐะตั‚, ั‡ั‚ะพ ะบะพะณะดะฐ ะฒั‹ ะดะตะปะฐะตั‚ะต ะทะฐะฟั€ะพั, ัƒ ะฒะฐั ะตัั‚ัŒ ั„ัƒะฝะบั†ะธั ะพะฑั€ะฐั‚ะฝะพะณะพ ะฒั‹ะทะพะฒะฐ (callback) ะธ ะบะพะณะดะฐ ัะตั€ะฒะตั€ ะพั‚ะฒะตั‚ะธั‚, ะฒ ะฝะตั‘ ะฟั€ะธะดั‘ั‚ ั€ะตะทัƒะปัŒั‚ะฐั‚. ะšะพะณะดะฐ ะฒั‹ ะพั‚ะฟั€ะฐะฒะปัะตั‚ะต ะบะพะผะฐะฝะดัƒ, ั‚ะพ ะฒั‹ ะฟั€ะพัั‚ะพ "ะธะฝั„ะพั€ะผะธั€ัƒะตั‚ะต" ัะตั€ะฒะตั€ ะพ ั‡ั‘ะผ-ั‚ะพ. + +ะ—ะฐะฟั€ะพั: + +```csharp +_client.Request("test", (data) => { + Console.WriteLine($"received test data: ${data.ToString()}"); +}); +``` + +ะšะพะผะฐะฝะดะฐ: + +```csharp +_client.Command("start"); +``` + +ะŸะพะดะฟะธัะบะฐ: + +```csharp +_client.On("lookup", (data) => { + Console.WriteLine($"received lookup data: ${data.ToString()}"); +}); +``` + +ะŸะพะดะฟะธัะบะฐ ะฝะฐ ะทะฐะฟั€ะพั ั ัะตั€ะฒะตั€ะฐ: + +```csharp +_client.OnRequest(request, (payload) => { + Console.WriteLine($"received request data: ${payload.ToString()}"); + // ะตัะปะธ ะทะฐะบะพะผะผะตะฝั‚ะธั€ะพะฒะฐั‚ัŒ ัั‚ั€ะพะบัƒ ะฝะธะถะต, ะฒั‹ ะฟะพะปัƒั‡ะธั‚ะต ั‚ะฐะนะผะฐัƒั‚ ะฝะฐ ัะตั€ะฒะตั€ะต + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); +}); +``` + +### ะ’ะฐะปะธะดะฐั†ะธั + +ะšะพะณะดะฐ ะบะปะธะตะฝั‚ ะฟะพะดะบะปัŽั‡ะฐะตั‚ัั ะบ ัะตั€ะฒะตั€ัƒ, ะพะฝ ะดะพะปะถะตะฝ ัƒัะฟะตัˆะฝะพ ะทะฐะฒะตั€ัˆะธั‚ัŒ ั€ัƒะบะพะฟะพะถะฐั‚ะธะต (handshake) ะฟะตั€ะตะด ะฝะฐั‡ะฐะปะพะผ ั€ะฐะฑะพั‚ั‹. ะ’ Shardy ะธัะฟะพะปัŒะทัƒะตั‚ัั ะดะฒัƒั…ัั‚ะฐะฟะฝะพะต ั€ัƒะบะพะฟะพะถะฐั‚ะธะต ะดะปั ัะพะตะดะธะฝะตะฝะธะน. + +ะญั‚ะฐะฟั‹ ั€ัƒะบะพะฟะพะถะฐั‚ะธั: + +1. ะšะปะธะตะฝั‚ ะพั‚ะฟั€ะฐะฒะปัะตั‚ ะดะฐะฝะฝั‹ะต ั€ัƒะบะพะฟะพะถะฐั‚ะธั ะฝะฐ ัะตั€ะฒะตั€ +2. ะกะตั€ะฒะตั€ ะฟะพะปัƒั‡ะฐะตั‚ ะธ ะฟั€ะพะฒะตั€ัะตั‚ ะธั…: + - ะžั‚ั€ะฐะฒะปัะตั‚ ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธะต ะบะปะธะตะฝั‚ัƒ + - ะžั‚ะบะปัŽั‡ะฐะตั‚ ะบะปะธะตะฝั‚ะฐ, ะตัะปะธ ะฟั€ะพะฒะตั€ะบะฐ ะฝะต ะฟั€ะพัˆะปะฐ +3. ะšะปะธะตะฝั‚ ะฟะพะปัƒั‡ะฐะตั‚ ะดะฐะฝะฝั‹ะต ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธั ะธ ั‚ะพะถะต ะฟั€ะพะฒะตั€ัะตั‚ ะธั…: + - ะžั‚ะฟั€ะฐะฒะปัะตั‚ ะพั‚ะฒะตั‚ ะฝะฐ ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธะต ัะตั€ะฒะตั€ัƒ + - ะžั‚ะบะปัŽั‡ะฐะตั‚ัั, ะตัะปะธ ะฟั€ะพะฒะตั€ะบะฐ ะฝะต ะฟั€ะพัˆะปะฐ +4. ะŸะพัะปะต ัƒัะฟะตัˆะฝะพะณะพ ั€ัƒะบะพะฟะพะถะฐั‚ะธั ะธ ะฟะพะดั‚ะฒะตั€ะถะดะตะฝะธั, ะบะปะธะตะฝั‚ ะธ ัะตั€ะฒะตั€ ะผะพะณัƒั‚ ะพั‚ะฟั€ะฐะฒะปัั‚ัŒ ะดั€ัƒะณ ะดั€ัƒะณัƒ ะทะฐะฟั€ะพัั‹ ะธ ะบะพะผะฐะฝะดั‹. + +ะ•ัะปะธ ะฒ ะฒะฐัˆะตะน ั€ะตะฐะปะธะทะฐั†ะธะธ ะฝะตั‚ ะฝะตะพะฑั…ะพะดะธะผะพัั‚ะธ ะดะตะปะฐั‚ัŒ ะดะฒัƒั…ัั‚ะฐะฟะฝะพะต ั€ัƒะบะพะฟะพะถะฐั‚ะธะต, ะฒั‹ ะผะพะถะตั‚ะต ัƒัั‚ะฐะฝะพะฒะธั‚ัŒ "ะทะฐะณะปัƒัˆะบะธ" ะฝะฐ ัั‚ะธั… ะผะตั‚ะพะดะฐั…. + +Shardy ะฟั€ะตะดะพัั‚ะฐะฒะปัะตั‚ ะธะฝั‚ะตั€ั„ะตะนั ะดะปั ะฒะฐะปะธะดะฐั†ะธะธ ั€ัƒะบะพะฟะพะถะฐั‚ะธั. ะ’ั‹ ะผะพะถะตั‚ะต ั€ะตะฐะปะธะทะพะฒะฐั‚ัŒ ัะพะฑัั‚ะฒะตะฝะฝัƒัŽ ัั‚ั€ัƒะบั‚ัƒั€ัƒ ะดะฐะฝะฝั‹ั… ั€ัƒะบะพะฟะพะถะฐั‚ะธั ะธ ะฒะฐะปะธะดะฐั†ะธัŽ ะดะปั ะฒัะตั… ัั‚ะธั… ัั‚ะฐะฟะพะฒ. ะกะพะทะดะฐะนั‚ะต ัะฒะพะน ะบะปะฐัั ั ะฒะฐะปะธะดะฐั‚ะพั€ะพะผ, ั€ะตะปะธะทัƒะนั‚ะต ะธะฝั‚ะตั€ั„ะตะนั `IValidator` ะธ ะฟะตั€ะตะดะฐะนั‚ะต ะตะณะพ ะฒ ะบะพะฝัั‚ั€ัƒะบั‚ะพั€ ะบะปะธะตะฝั‚ะฐ. + +```csharp +using Shardy; + +class MyHandshake : IValidator { + + public ValidatorState VerifyAcknowledgement(byte[] body) { + // vefify acknowledgement data + } + + public byte[] Handshake(byte[] body = null) { + // data for initial handshake + } + + public byte[] Acknowledgement(byte[] body) { + // data for acknowledgement after handshake validation passed + } +} +``` + +### ะกะตั€ะธะฐะปะธะทะฐั†ะธั + +Shardy ะฟะพะดะดะตั€ะถะธะฒะฐะตั‚ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัŒัะบัƒัŽ ัะตั€ะธะฐะปะธะทะฐั†ะธัŽ ะฟะตั€ะตะดะฐะฒะฐะตะผั‹ั… ะดะฐะฝะฝั‹ั…. ะ’ั‹ ะผะพะถะตั‚ะต ะธัะฟะพะปัŒะทะพะฒะฐั‚ัŒ JSON, MessagePack, Protobuf, FlatBuffers ะธ ั‚.ะด. ะธะปะธ ัะฒะพะน ัะพะฑัั‚ะฒะตะฝะฝั‹ะน ัะตั€ะธะฐะปะธะทะฐั‚ะพั€. + +ะกะพะทะดะฐะนั‚ะต ัะฒะพะน ะบะปะฐัั ั ัะตั€ะธะฐะปะธะทะฐั‚ะพั€ะพะผ, ั€ะตะปะธะทัƒะนั‚ะต ะธะฝั‚ะตั€ั„ะตะนั `ISerializer` ะธ ะฟะตั€ะตะดะฐะนั‚ะต ะตะณะพ ะฒ ะบะพะฝัั‚ั€ัƒะบั‚ะพั€ ะบะปะธะตะฝั‚ะฐ. + +```csharp +using Shardy; + +class MyJsonSerializer : ISerializer { + + public byte[] Encode(PayloadData body) { + // encode PayloadData to byte array for transporting + } + + public PayloadData Decode(byte[] body) { + // decode recevied data and serialize to PayloadData + } +} +``` + +ะกะผะพั‚ั€ะธั‚ะต [ะดะพะบัƒะผะตะฝั‚ะฐั†ะธัŽ](./Documentation~/index.md) ั ะธะฝั„ะพั€ะผะฐั†ะธะตะน ะพ ะฒัะตั… ะบะปะฐััะฐั… ะธ ะผะตั‚ะพะดะฐั…. + +# ๐Ÿ—๏ธ ะ ะฐะทะฒะธั‚ะธะต + +ะœั‹ ะฟั€ะธะณะปะฐัˆะฐะตะผ ะฒะฐั ะฒะฝะตัั‚ะธ ัะฒะพะน ะฒะบะปะฐะด ะธ ะฟะพะผะพั‡ัŒ ัƒะปัƒั‡ัˆะธั‚ัŒ Unity ะบะปะธะตะฝั‚ ะดะปั Shardy. ะŸะพะถะฐะปัƒะนัั‚ะฐ, ะพะทะฝะฐะบะพะผัŒั‚ะตััŒ ั [ะดะพะบัƒะผะตะฝั‚ะพะผ](./CONTRIBUTING.md). ๐Ÿค— + +ะ’ั‹ ั‚ะฐะบะถะต ะผะพะถะตั‚ะต ะฒะฝะตัั‚ะธ ัะฒะพะน ะฒะบะปะฐะด ะฒ ะฟั€ะพะตะบั‚ Shardy: + +- ะŸะพะผะพะณะฐั ะดั€ัƒะณะธะผ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปัะผ +- ะœะพะฝะธั‚ะพั€ั ัะฟะธัะพะบ ััƒั‰ะตัั‚ะฒัƒัŽั‰ะธั… ะฟั€ะพะฑะปะตะผ +- ะ ะฐััะบะฐะทะฐะฒ ะพ ะฟั€ะพะตะบั‚ะต ะฒ ัะฒะพะธั… ัะพั†ัะตั‚ัั… +- ะ˜ัะฟะพะปัŒะทัƒั ะตะณะพ ะฒ ัะฒะพะธั… ะฟั€ะพะตะบั‚ะฐั… + +# ๐Ÿค ะŸะพะดะดะตั€ะถะบะฐ + +ะ’ั‹ ะผะพะถะตั‚ะต ะฟะพะดะดะตั€ะถะฐั‚ัŒ ะฟั€ะพะตะบั‚ ะปัŽะฑั‹ะผ ะธะท ัะฟะพัะพะฑะพะฒ ะฝะธะถะต: + +* Bitcoin (BTC): 1VccPXdHeiUofzEj4hPfvVbdnzoKkX8TJ +* USDT (TRC20): TMHacMp461jHH2SHJQn8VkzCPNEMrFno7m +* TON: UQDVp346KxR6XxFeYc3ksZ_jOuYjztg7b4lEs6ulEWYmJb0f +* ะšะฐั€ั‚ั‹ Visa, Mastercard ั‡ะตั€ะตะท [Boosty](https://boosty.to/mopsicus/donate) +* ะšะฐั€ั‚ั‹ ะœะ˜ะ  ั‡ะตั€ะตะท [CloudTips](https://pay.cloudtips.ru/p/9f507669) + +# โœ‰๏ธ ะšะพะฝั‚ะฐะบั‚ะฝะฐั ะธะฝั„ะพั€ะผะฐั†ะธั + +ะŸะตั€ะตะด ั‚ะตะผ ะบะฐะบ ะทะฐะดะฐั‚ัŒ ะฒะพะฟั€ะพั, ะปัƒั‡ัˆะธะผ ั€ะตัˆะตะฝะธะตะผ ะฑัƒะดะตั‚ ะฟะพัะผะพั‚ั€ะตั‚ัŒ ัƒะถะต ััƒั‰ะตัั‚ะฒัƒัŽั‰ะธะต [ะฟั€ะพะฑะปะตะผั‹](https://github.com/mopsicus/shardy-unity/issues), ัั‚ะพ ะผะพะถะตั‚ ะฟะพะผะพั‡ัŒ. ะ’ ะปัŽะฑะพะผ ัะปัƒั‡ะฐะต, ะฒั‹ ะผะพะถะตั‚ะต ะทะฐะดะฐั‚ัŒ ะปัŽะฑะพะน ะฒะพะฟั€ะพั ะธะปะธ ะพั‚ะฟั€ะฐะฒะธั‚ัŒ ะฟั€ะตะดะปะพะถะตะฝะธะต ะฟะพ [email](mailto:mail@mopsicus.ru) ะธะปะธ [Telegram](https://t.me/mopsicus). + +# ๐Ÿ”‘ ะ›ะธั†ะตะฝะทะธั + +Unity ะบะปะธะตะฝั‚ ะดะปั Shardy ะฒั‹ะฟัƒั‰ะตะฝ ะฟะพะด ะปะธั†ะตะฝะทะธะตะน [MIT](./LICENSE.md). ะ˜ัะฟะพะปัŒะทัƒะนั‚ะต ะฑะตัะฟะปะฐั‚ะฝะพ ะธ ั€ะฐะดัƒะนั‚ะตััŒ. ๐ŸŽ‰ \ No newline at end of file diff --git a/README.ru.md.meta b/README.ru.md.meta new file mode 100644 index 0000000..cfb0ed6 --- /dev/null +++ b/README.ru.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5d60f773fe8d7412884aabc0cd6e0219 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime.meta b/Runtime.meta new file mode 100644 index 0000000..90980d9 --- /dev/null +++ b/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d0d3c0715350147c2855eebe99a5e6a5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Block.cs b/Runtime/Block.cs new file mode 100644 index 0000000..238cd02 --- /dev/null +++ b/Runtime/Block.cs @@ -0,0 +1,62 @@ +using System; + +namespace Shardy { + + /// + /// Block data for transport + /// + class Block { + + /// + /// Length of block head + /// + public const int HEAD_SIZE = 4; + + /// + /// Encode block for transporting + /// + /// First byte is type + /// Next - length, and data + /// + /// Block type: data, kick or heartbeat + /// Body to send + /// Encoded type + body + public static byte[] Encode(BlockType type, byte[] body) { + var length = (body != null) ? HEAD_SIZE + body.Length : HEAD_SIZE; + var buffer = new byte[length]; + var index = 0; + buffer[index++] = Convert.ToByte(type); + buffer[index++] = Convert.ToByte(body.Length >> 16 & 0xFF); + buffer[index++] = Convert.ToByte(body.Length >> 8 & 0xFF); + buffer[index++] = Convert.ToByte(body.Length & 0xFF); + while (index < length) { + buffer[index] = body[index - HEAD_SIZE]; + index++; + } + return buffer; + } + + /// + /// Decode block data + /// + /// Buffer with data to decode + /// Result with type as BlockType and body as byte array + public static BlockData Decode(byte[] data) { + var type = (BlockType)data[0]; + var body = new byte[data.Length - HEAD_SIZE]; + for (var i = 0; i < body.Length; i++) { + body[i] = data[i + HEAD_SIZE]; + } + return new BlockData(type, body); + } + + /// + /// Check received block + /// + /// Byte index for BlockType + /// Is correct block or not + public static bool Check(BlockType type) { + return Enum.IsDefined(typeof(BlockType), type); + } + } +} \ No newline at end of file diff --git a/Runtime/Block.cs.meta b/Runtime/Block.cs.meta new file mode 100644 index 0000000..1eaf5ac --- /dev/null +++ b/Runtime/Block.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 318053597490d475381fdb076c14f474 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/BlockData.cs b/Runtime/BlockData.cs new file mode 100644 index 0000000..f4e05a1 --- /dev/null +++ b/Runtime/BlockData.cs @@ -0,0 +1,34 @@ +namespace Shardy { + + /// + /// Block result after decode + /// + public struct BlockData { + + /// + /// Type of block + /// + public BlockType Type; + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Block type + /// Data for block + public BlockData(BlockType type, byte[] body) { + Type = type; + Length = body.Length; + Body = body; + } + } +} \ No newline at end of file diff --git a/Runtime/BlockData.cs.meta b/Runtime/BlockData.cs.meta new file mode 100644 index 0000000..764e380 --- /dev/null +++ b/Runtime/BlockData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30ba0b5dd62634b909a632b6b71f065d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/BlockType.cs b/Runtime/BlockType.cs new file mode 100644 index 0000000..3bf1767 --- /dev/null +++ b/Runtime/BlockType.cs @@ -0,0 +1,33 @@ +namespace Shardy { + + /// + /// Block type to encode + /// + public enum BlockType { + + /// + /// Handshake process + /// + Handshake, + + /// + /// Acknowledgement for success verify + /// + HandshakeAcknowledgement, + + /// + /// Ping + /// + Heartbeat, + + /// + /// Data for command, request, response + /// + Data, + + /// + /// Kick from server, disconnect + /// + Kick + } +} \ No newline at end of file diff --git a/Runtime/BlockType.cs.meta b/Runtime/BlockType.cs.meta new file mode 100644 index 0000000..d5a8866 --- /dev/null +++ b/Runtime/BlockType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ff6e9e4777f9144a7b799717a87fb41b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Client.cs b/Runtime/Client.cs new file mode 100644 index 0000000..3c2945b --- /dev/null +++ b/Runtime/Client.cs @@ -0,0 +1,234 @@ +using System; + +namespace Shardy { + + /// + /// Client class connected to server + /// + public class Client { + + /// + /// Log tag + /// + const string TAG = "CLIENT"; + + /// + /// Event on connected + /// + public Action OnConnect = delegate { }; + + /// + /// Event on disconnected + /// + public Action OnDisconnect = delegate { }; + + /// + /// Event when ready to work + /// + public Action OnReady = delegate { }; + + /// + /// Commander instance + /// + readonly Commander _commander = null; + + /// + /// Client validator + /// + readonly IValidator _validator = null; + + /// + /// Client serializer + /// + readonly ISerializer _serializer = null; + + /// + /// Current connection + /// + readonly Connection _connection = null; + + /// + /// Current options + /// + readonly ClientOptions _options = null; + + /// + /// Snd handshake after connect + /// + readonly byte[] _handshake = null; + + /// + /// Is client connected + /// + public bool IsConnected { + get { + return _connection.IsConnected; + } + } + + /// + /// Client constructor + /// + /// Validator + /// Serializer + /// Client options (optional) + /// Handshake after connect (optional) + public Client(IValidator validator, ISerializer serializer, ClientOptions options = null, byte[] handshake = null) { +#if UNITY_WEBGL && !UNITY_EDITOR + WebSocketManager.Init(); +#if SHARDY_DEBUG_RAW + WebSocketManager.SetDebug(true); +#endif +#endif + _validator = validator; + _serializer = serializer; + _options = options ?? new ClientOptions(); + _handshake = handshake; +#if UNITY_WEBGL && !UNITY_EDITOR + if (_options.Type == TransportType.Tcp) { + Logger.Error($"Unable to use TCP transport for WebGL", TAG); + return; + } +#endif + _connection = new Connection(_options.Type, _options.BufferSize); + _commander = new Commander(_connection, _validator, _serializer, _options); + _commander.OnDisconnect = (reason) => OnDisconnect(reason); + _commander.OnReady = () => OnReady(); + } + + /// + /// Connect to server + /// + /// Host to connect + /// Port to connect + public async void Connect(string host, int port) { + var status = await _connection.Open(host, port); + if (status) { + _commander.Start(); + } + OnConnect(status); + if (_handshake != null && status) { + Handshake(_handshake); + } + } + + /// + /// Disconnect from server + /// + public void Disconnect() { + _commander.Disconnect(); + } + + /// + /// Send command (event) to server + /// + /// Command name + /// Payload data + public void Command(string command, byte[] data = null) { + _commander.Command(command, data); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Answer from server + /// Request id + public int Request(string request, Action callback) { + return Request(request, null, callback); + } + + /// + /// Send response on request from server + /// + /// Request data + /// Data + public void Response(PayloadData request, byte[] data = null) { + _commander.Response(request, data); + } + + /// + /// Send error on request from server + /// + /// Request data + /// Error message or code + /// Data + public void Error(PayloadData request, string error, byte[] data = null) { + _commander.Error(request, error, data); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Payload data + /// Answer from server + /// Request id + public int Request(string request, byte[] data, Action callback) { + return _commander.Request(request, data, callback); + } + + /// + /// Cancel request manually + /// + /// Request id + public void CancelRequest(int id) { + _commander.CancelRequest(id); + } + + /// + /// Handshake to verify connection + /// + /// Data for handshake + public void Handshake(byte[] body = null) { + _commander.Handshake(_validator.Handshake(body)); + } + + /// + /// Subscribe on command from server + /// + /// Command name + /// Callback to action + public void On(string command, Action callback) { + _commander.AddCommand(command, callback); + } + + /// + /// Unsubscribe from command + /// If callback is null -> clear all of them + /// + /// Command name + /// Callback to unsubscribe + public void Off(string command, Action callback = null) { + _commander.CancelCommand(command, callback); + } + + /// + /// Subscribe on request from server that wait response + /// + /// Request name + /// Callback to action + public void OnRequest(string request, Action callback) { + _commander.AddOnRequest(request, callback); + } + + /// + /// Unsubscribe from request from server that wait response + /// + /// Request name + /// Callback to unsubscribe + public void OffRequest(string request) { + _commander.CancelOnRequest(request); + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _commander.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Client.cs.meta b/Runtime/Client.cs.meta new file mode 100644 index 0000000..f5dd719 --- /dev/null +++ b/Runtime/Client.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fafaccae986214a3798477d5bafdcb8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ClientOptions.cs b/Runtime/ClientOptions.cs new file mode 100644 index 0000000..32d6b46 --- /dev/null +++ b/Runtime/ClientOptions.cs @@ -0,0 +1,50 @@ +namespace Shardy { + + /// + /// Client and connection options + /// + public class ClientOptions { + + /// + /// Transport type: TCP or WebSocket + /// + public TransportType Type = TransportType.Tcp; + + /// + /// Transport buffer size + /// + public int BufferSize = 1024; + + /// + /// Timeout for RPC request (ms) + /// + public float RequestTimeout = 10000f; + + /// + /// Interval for checking server (ms) + /// + public float PulseInterval = 1000f; + + /// + /// Options constructor + /// + /// Transport type + public ClientOptions(TransportType type = TransportType.Tcp) { + Type = type; + } + + /// + /// Options constructor + /// + /// Transport type + /// Transport buffer size, Kb + /// Timeout for RPC request, ms + /// Interval for checking server, ms + public ClientOptions(TransportType type, int buffer, float timeout, float pulse) { + Type = type; + BufferSize = buffer; + RequestTimeout = timeout; + PulseInterval = pulse; + } + } +} \ No newline at end of file diff --git a/Runtime/ClientOptions.cs.meta b/Runtime/ClientOptions.cs.meta new file mode 100644 index 0000000..8595c14 --- /dev/null +++ b/Runtime/ClientOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32ef8554eb36544889f30ee0f64ab8d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Commander.cs b/Runtime/Commander.cs new file mode 100644 index 0000000..78a8e92 --- /dev/null +++ b/Runtime/Commander.cs @@ -0,0 +1,595 @@ +๏ปฟusing System; +using System.Collections.Generic; +using System.Threading; + +#pragma warning disable 4014 + +namespace Shardy { + + /// + /// Client commander to send/receive commands and requests + /// + class Commander { + + /// + /// Log tag + /// + const string TAG = "COMMANDER"; + + /// + /// Timer timeout loop + /// + const float TIMEOUT_INTERVAL = 1000f; + + /// + /// Timeout error code + /// + const string TIMEOUT_ERROR = "timeout"; + + /// + /// Callback on disconnect + /// + public Action OnDisconnect = delegate { }; + + /// + /// Cached ready callback + /// + public Action OnReady = delegate { }; + + /// + /// Dictionary of request id and commands + /// + readonly Dictionary _names = null; + + /// + /// Dictionary of notify command and their callbacks + /// + readonly Dictionary>> _commands = null; + + /// + /// Dictionary of request id and callback + /// + readonly Dictionary> _callbacks = null; + + /// + /// Dictionary of request name and callback for requests from server + /// + readonly Dictionary> _requests = null; + + /// + /// Dictionary of request id and start using time + /// + readonly Dictionary _timeouts = null; + + /// + /// Protocol instance + /// + readonly Protocol _protocol = null; + + /// + /// Pulse instance + /// + Pulse _pulse = null; + + /// + /// Current request counter + /// + int _counter = 1; + + /// + /// Validator + /// + readonly IValidator _validator = null; + + /// + /// Serializer + /// + readonly ISerializer _serializer = null; + + /// + /// Current options + /// + readonly ClientOptions _options = null; + + /// + /// Cancellation token source + /// + readonly CancellationTokenSource _cancellation = new CancellationTokenSource(); + + /// + /// Cached disconnect reason + /// + DisconnectReason _disconnectReason = DisconnectReason.Normal; + + /// + /// Creates an instance of Commander + /// + /// Client connection + /// Current validator + /// Current serializer + /// Client options + public Commander(Connection connection, IValidator validator, ISerializer serializer, ClientOptions options) { + _validator = validator; + _serializer = serializer; + _options = options; + _names = new Dictionary(); + _commands = new Dictionary>>(); + _callbacks = new Dictionary>(); + _requests = new Dictionary>(); + _timeouts = new Dictionary(); + _protocol = new Protocol(connection); + _protocol.OnBlock = (block) => OnBlock(block); + _protocol.OnDisconnect = () => OnClose(); + } + + /// + /// Start use + /// + public void Start() { + Utils.SetTimer(TIMEOUT_INTERVAL, _cancellation, () => TimeoutCheck()); + _pulse = new Pulse(_options.PulseInterval); + _pulse.OnPulse = () => OnPulse(); + _protocol.Start(); + } + + /// + /// Timer check for timeout RPC call + /// + void TimeoutCheck() { + foreach (var id in _timeouts.Keys) { + var span = DateTime.Now - _timeouts[id]; + var timeout = (int)span.TotalMilliseconds; + if (timeout > _options.RequestTimeout) { + var payload = new PayloadData(); + payload.Type = PayloadType.Response; + payload.Id = id; + payload.Name = _names[id]; + payload.Error = TIMEOUT_ERROR; + OnPayload(payload); + } + } + } + + /// + /// Add callback for request + /// + /// Request id + /// Request command + /// Request's params + /// Callback for request + void AddRequest(int id, string command, byte[] param, Action callback) { + if (_callbacks.ContainsKey(id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"callback already exists: {id}, method: {_callbacks[id].Method}", TAG); +#endif + } else { + if (id <= 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"callback id can't be less 1: {id}", TAG); +#endif + return; + } + _names.Add(id, command); + _callbacks.Add(id, callback); + _timeouts.Add(id, DateTime.Now); + } + } + + /// + /// Remove request from list + /// + /// Request id + public void CancelRequest(int id) { + if (!_callbacks.ContainsKey(id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown callback to cancel: {id}", TAG); +#endif + return; + } + _names.Remove(id); + _callbacks.Remove(id); + _timeouts.Remove(id); + } + + /// + /// Exec callback + /// + /// Data for callback + void InvokeRequest(PayloadData payload) { + if (!_callbacks.ContainsKey(payload.Id)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown callback to execute: {payload.Id}", TAG); +#endif + return; + } + try { + _callbacks[payload.Id].Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"callback execute failed: {payload.Id}, error: {e}", TAG); +#endif + } + CancelRequest(payload.Id); + } + + /// + /// Subscribe callback on command + /// + /// Command name + /// Callback for command + public void AddCommand(string command, Action callback) { + if (_commands.TryGetValue(command, out var list)) { + list.Add(callback); + _commands[command] = list; + } else { + list = new List>(); + list.Add(callback); + _commands.Add(command, list); + } + } + + /// + /// Unsubscribe callback from command + /// If callback is null -> clear all of them + /// + /// Command name + /// Callback for command + public void CancelCommand(string command, Action callback) { + if (!_commands.ContainsKey(command)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown command to unsubscribe: {command}", TAG); +#endif + return; + } + if (callback == null) { + _commands[command].Clear(); + } else { + var list = _commands[command]; + for (var i = list.Count - 1; i >= 0; i--) { + if (list[i].Equals(callback)) { + list.RemoveAt(i); + break; + } + _commands[command] = list; + } + } + } + + /// + /// Exec callback on command + /// + /// Data for command + void InvokeCommand(PayloadData payload) { + if (!_commands.ContainsKey(payload.Name)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown command to execute: {payload.Name}", TAG); +#endif + return; + } + var list = _commands[payload.Name]; + foreach (var action in list) { + try { + action.Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"command execute failed: {payload.Name}, error: {e}", TAG); +#endif + } + } + } + + /// + /// Subscribe to request from server that wait response + /// + /// Request name + /// Callback on RPC + public void AddOnRequest(string request, Action callback) { + if (_requests.ContainsKey(request)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"request already exists: {request}, method: {_requests[request].Method}", TAG); +#endif + } else { + _requests.Add(request, callback); + } + } + + /// + /// Unsubscribe from request from server that wait response + /// + /// Request name + public void CancelOnRequest(string request) { + if (!_requests.ContainsKey(request)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown request to cancel: {request}", TAG); +#endif + return; + } + _requests.Remove(request); + } + + /// + /// Exec callback for RPC from server + /// + /// Request data + public void InvokeOnRequest(PayloadData payload) { + if (!_requests.ContainsKey(payload.Name)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"unknown request to execute: {payload.Name}", TAG); +#endif + return; + } + try { + _requests[payload.Name].Invoke(payload); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"request execute failed: {payload.Name}, error: {e}", TAG); +#endif + } + } + + /// + /// Send ping + /// + void Heartbeat() { +#if SHARDY_DEBUG + Logger.Info("-> heartbeat"); +#endif + _protocol.Heartbeat(); + } + + /// + /// Send handshake + /// + /// Data to handshake + public void Handshake(byte[] data) { +#if SHARDY_DEBUG + Logger.Info("-> handshake"); +#endif + _protocol.Handshake(data); + } + + /// + /// Send acknowledge + /// + /// Data to acknowledge + public void Acknowledge(byte[] data) { +#if SHARDY_DEBUG + Logger.Info("-> acknowledge"); +#endif + _protocol.Acknowledge(data); + } + + /// + /// Disconnect from server + /// + public void Disconnect() { +#if SHARDY_DEBUG + Logger.Info("-> disconnect"); +#endif + _protocol.Disconnect(); + } + + /// + /// Send command (event) to server with params + /// + /// Command name + /// Payload data + public void Command(string command, byte[] data) { +#if SHARDY_DEBUG + Logger.Info($"-> command: {command}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Command, command, 0, data, ""); + _protocol.Send(payload); + } + + /// + /// Send request to server and wait response + /// + /// Request name + /// Payload data + /// Answer from server + /// Request id + public int Request(string request, byte[] data, Action callback) { +#if SHARDY_DEBUG + Logger.Info($"-> request: {_counter}.{request}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Request, request, _counter, data, ""); + AddRequest(_counter, request, data, callback); + _protocol.Send(payload); + _counter++; + return _counter; + } + + /// + /// Send response on request from server + /// + /// Request data + /// Data + public void Response(PayloadData request, byte[] data = null) { +#if SHARDY_DEBUG + Logger.Info($"-> response: {request.Id}.{request.Name}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Response, request.Name, request.Id, data, ""); + _protocol.Send(payload); + } + + /// + /// Send error on request from server + /// + /// Request data + /// Error message or code + /// Data + public void Error(PayloadData request, string error, byte[] data = null) { +#if SHARDY_DEBUG + Logger.Info($"-> error: {request.Id}.{request.Name}, error: {error}"); +#endif + var payload = Payload.Encode(_serializer, PayloadType.Response, request.Name, request.Id, data, error); + _protocol.Send(payload); + } + + /// + /// Clear all events + /// + public void Clear() { + _cancellation.Cancel(); + _names.Clear(); + _callbacks.Clear(); + _timeouts.Clear(); + _commands.Clear(); + _requests.Clear(); + _pulse?.Clear(); + } + + /// + /// Process data from protocol + /// + /// Block type and possible data + void OnBlock(BlockData block) { +#if SHARDY_DEBUG_RAW + Logger.Info($"block: {block.Type}, data: {Utils.DataToDebug(block.Body)}", TAG); +#endif + switch (block.Type) { + case BlockType.Heartbeat: + OnHeartbeat(); + break; + case BlockType.Kick: + OnKick(block); + break; + case BlockType.HandshakeAcknowledgement: + OnAcknowledgement(block); + break; + case BlockType.Data: + var payload = Payload.Decode(_serializer, block.Body); + if (Payload.Check(payload)) { + OnPayload(payload); + } else { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid payload: {payload}", TAG); +#endif + } + break; + default: +#if SHARDY_DEBUG_RAW + Logger.Warning($"not implemented block type: {block.Type}", TAG); +#endif + break; + } + } + + /// + /// Process payload with commands/request/responses + /// When received data, send heartbeat for ok + /// + /// payload Decoded payload data + void OnPayload(PayloadData payload) { + _pulse.Reset(); + Heartbeat(); + switch (payload.Type) { + case PayloadType.Command: +#if SHARDY_DEBUG + Logger.Info($"<- command: {payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); +#endif + InvokeCommand(payload); + break; + case PayloadType.Request: +#if SHARDY_DEBUG + Logger.Info($"<- request: {payload.Id}.{payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); +#endif + InvokeOnRequest(payload); + break; + case PayloadType.Response: +#if SHARDY_DEBUG + if (string.IsNullOrEmpty(payload.Error)) { + Logger.Info($"<- response: {payload.Id}.{payload.Name}, data: {Utils.DataToDebug(payload.Data)}"); + } else { + Logger.Info($"<- error: {payload.Id}.{payload.Name}, error: {payload.Error}, data: {Utils.DataToDebug(payload.Data)}"); + } +#endif + InvokeRequest(payload); + break; + default: + break; + } + } + + /// + /// Event from protocol when connection closed + /// + void OnClose() { +#if SHARDY_DEBUG + Logger.Info("<- disconnect"); +#endif + Clear(); + OnDisconnect(_disconnectReason); + } + + /// + /// Process acknowledgement + /// + /// Acknowledgement data + void OnAcknowledgement(BlockData block) { +#if SHARDY_DEBUG + Logger.Info("<- acknowledge"); +#endif + _pulse.Reset(); + var state = _validator.VerifyAcknowledgement(block.Body); +#if SHARDY_DEBUG_RAW + Logger.Info($"acknowledgement data: {Utils.DataToDebug(block.Body)}, validation state: {state}", TAG); +#endif + if (state == ValidatorState.Success) { + Acknowledge(_validator.Acknowledgement(block.Body)); +#if SHARDY_DEBUG + Logger.Info("ready to work"); +#endif + OnReady(); + } else { + _disconnectReason = DisconnectReason.Handshake; + Disconnect(); + } + } + + /// + /// Process heartbeat from server + /// + void OnHeartbeat() { +#if SHARDY_DEBUG + Logger.Info("<- heartbeat"); +#endif + _pulse.Reset(); + } + + /// + /// Process kick + /// + /// Kick reason data + void OnKick(BlockData block) { + int.TryParse(Utils.DataToString(block.Body), out var index); + _disconnectReason = (DisconnectReason)index; +#if SHARDY_DEBUG + Logger.Info($"<- kick: {_disconnectReason}"); +#endif + _pulse.Reset(); + } + + /// + /// No answer from connection + /// + void OnPulse() { +#if SHARDY_DEBUG + Logger.Info("pulse timeout, send heartbeat"); +#endif + Heartbeat(); + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + Clear(); + _protocol.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Commander.cs.meta b/Runtime/Commander.cs.meta new file mode 100644 index 0000000..b33ee5b --- /dev/null +++ b/Runtime/Commander.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 195c752b89e9041c9afcebe7fe269a3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Connection.cs b/Runtime/Connection.cs new file mode 100644 index 0000000..6fece94 --- /dev/null +++ b/Runtime/Connection.cs @@ -0,0 +1,364 @@ +using System; +using System.Net.Sockets; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +#if UNITY_IOS +using System.Runtime.InteropServices; +#endif + +namespace Shardy { + + /// + /// Common connection class + /// + public class Connection { + + /// + /// Log tag + /// + const string TAG = "CONNECTION"; + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Cached websocket for WebGL + /// + WebSocket _webglsocket = null; +#else + /// + /// Cached websocket + /// + ClientWebSocket _websocket = null; +#endif + + /// + /// Cached socket + /// + Socket _tcpsocket = null; + + /// + /// Received buffer array + /// + readonly byte[] _received = null; + + /// + /// Connection transport type + /// + readonly TransportType _type = TransportType.Tcp; + + /// + /// Cached transport data + /// + ReceivedData _data = new ReceivedData(); + + /// + /// Cancellation token source + /// + CancellationTokenSource _cancellation = null; + + /// + /// Used flag + /// + bool _isUsed = false; + +#if UNITY_IOS + /// + /// Check and convert IP to IPv6 on iOS + /// + [DllImport("__Internal")] + static extern string CheckIPv6(string host); +#endif + + /// + /// Create new connection + /// + /// Transport type + /// Buffer size + public Connection(TransportType type, int size) { + _type = type; +#if SHARDY_DEBUG_RAW + Logger.Info($"new connection: {_type}", TAG); +#endif + _received = new byte[size]; + CreateSocket(); + } + + /// + /// Create socket instance + /// + void CreateSocket() { + _cancellation = new CancellationTokenSource(); + switch (_type) { + case TransportType.Tcp: + _tcpsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + _webglsocket = new WebSocket(); + _webglsocket.OnError += OnWebSocketError; + _webglsocket.OnClose += OnWebSocketClose; +#else + _websocket = new ClientWebSocket(); +#endif + break; + default: + break; + } + } + + /// + /// Check connection to host + /// + public bool IsConnected { + get { + return _type switch { + TransportType.Tcp => _tcpsocket.Connected, +#if UNITY_WEBGL && !UNITY_EDITOR + TransportType.WebSocket => _webglsocket.State == WebSocketStateCode.Open, +#else + TransportType.WebSocket => _websocket.State == WebSocketState.Open, +#endif + _ => false, + }; + } + } + + /// + /// Open connection + /// + /// Host to connect + /// Port to connect + public async Task Open(string host, int port) { + if (_isUsed) { + DeleteSocket(); + CreateSocket(); + } else { + _isUsed = true; + } + try { +#if UNITY_IOS && !UNITY_EDITOR + var ipv6 = CheckIPv6(host); + if (!string.IsNullOrEmpty(ipv6) && Socket.OSSupportsIPv6) { + host = ipv6; + } + _tcpsocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); +#endif + switch (_type) { + case TransportType.Tcp: +#if SHARDY_DEBUG + Logger.Info($"-> connect to {host}:{port}"); +#endif + await _tcpsocket.ConnectAsync(host, port).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: + var url = $"ws://{host}:{port}"; +#if SHARDY_DEBUG + Logger.Info($"-> connect to {url}"); +#endif +#if UNITY_WEBGL && !UNITY_EDITOR + await _webglsocket.Connect(url).WithCancellation(_cancellation.Token); +#else + await _websocket.ConnectAsync(new Uri(url), CancellationToken.None).WithCancellation(_cancellation.Token); ; +#endif + break; + default: + break; + } + return true; + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("open operation canceled", TAG); +#endif + return false; + } catch (SocketException e) { + if (e.SocketErrorCode == SocketError.ConnectionRefused) { +#if SHARDY_DEBUG_RAW + Logger.Info("open socket refused", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open socket failed: {e}", TAG); +#endif + } + return false; + } catch (WebSocketException e) { + if (e.GetBaseException() is SocketException exception) { + if (exception.SocketErrorCode == SocketError.ConnectionRefused) { +#if SHARDY_DEBUG_RAW + Logger.Info("open websocket refused", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open websocket as socket failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"open websocket failed: {e}", TAG); +#endif + } + return false; + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"open failed: {e}", TAG); +#endif + return false; + } + } + + /// + /// Close connection + /// + public void Close() { + switch (_type) { + case TransportType.Tcp: + if (_tcpsocket.Connected) { + _tcpsocket.Shutdown(SocketShutdown.Both); + _tcpsocket.Close(); + } + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + if (_webglsocket.State == WebSocketStateCode.Open) { + _webglsocket.Close(WebSocketCloseCode.Normal); + } +#else + switch (_websocket.State) { + case WebSocketState.Open: + case WebSocketState.CloseSent: + case WebSocketState.CloseReceived: + _websocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); + break; + default: + break; + } +#endif + break; + default: + break; + } + } + + /// + /// Send data to socket + /// + /// Data to send + public async Task Send(byte[] buffer) { + switch (_type) { + case TransportType.Tcp: + await _tcpsocket.SendAsync(buffer, SocketFlags.None).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + await _webglsocket.Send(buffer).WithCancellation(_cancellation.Token); +#else + await _websocket.SendAsync(buffer, WebSocketMessageType.Binary, true, CancellationToken.None).WithCancellation(_cancellation.Token); +#endif + break; + default: + break; + } + } + + /// + /// Receive data from socket + /// + public async Task Receive() { + switch (_type) { + case TransportType.Tcp: + _data.Length = await _tcpsocket.ReceiveAsync(_received, SocketFlags.None).WithCancellation(_cancellation.Token); + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + _data.Length = await _webglsocket.Receive(_received).WithCancellation(_cancellation.Token); +#else + var result = await _websocket.ReceiveAsync(_received, CancellationToken.None).WithCancellation(_cancellation.Token); + _data.Length = (result.MessageType == WebSocketMessageType.Close) ? 0 : result.Count; +#endif + break; + default: + break; + } + _data.Body = _received; + return _data; + } + + /// + /// Cancel operations + /// + public void Cancel() { + _cancellation.Cancel(); + } + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Callback on webglsocket error + /// + /// Websocket error code + void OnWebSocketError(WebSocketErrorCode code) { +#if SHARDY_DEBUG_RAW + Logger.Error($"webgl error: {code}", TAG); +#endif + } + + /// + /// Callback on webglsocket close + /// + /// Websocket close code + void OnWebSocketClose(WebSocketCloseCode code) { +#if SHARDY_DEBUG_RAW + Logger.Error($"webgl close: {code}", TAG); +#endif + Cancel(); + } +#endif + + /// + /// Delete socket instance + /// + void DeleteSocket() { + try { + _cancellation.Dispose(); + switch (_type) { + case TransportType.Tcp: + _tcpsocket.Dispose(); + _tcpsocket = null; + break; + case TransportType.WebSocket: +#if UNITY_WEBGL && !UNITY_EDITOR + WebSocketManager.Destroy(_webglsocket.Id); + _webglsocket = null; +#else + _websocket.Dispose(); + _websocket = null; +#endif + break; + default: + break; + } + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"delete failed: {e}", TAG); +#endif + } + } + + /// + /// Destroy connection + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + try { + Cancel(); + Close(); + DeleteSocket(); + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"destroy failed: {e}", TAG); +#endif + } + } + } +} \ No newline at end of file diff --git a/Runtime/Connection.cs.meta b/Runtime/Connection.cs.meta new file mode 100644 index 0000000..017bb81 --- /dev/null +++ b/Runtime/Connection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b5ad515ebacc047d8897007f03214fed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/DisconnectReason.cs b/Runtime/DisconnectReason.cs new file mode 100644 index 0000000..5210bf2 --- /dev/null +++ b/Runtime/DisconnectReason.cs @@ -0,0 +1,33 @@ +namespace Shardy { + + /// + /// Disconnect reasons + /// + public enum DisconnectReason { + + /// + /// Normal disconnect + /// + Normal, + + /// + /// Have no answer on ping command + /// + Timeout, + + /// + /// Handshake validation failed + /// + Handshake, + + /// + /// Server is closed` + /// + ServerDown, + + /// + /// Some error occurs + /// + Unknown + } +} \ No newline at end of file diff --git a/Runtime/DisconnectReason.cs.meta b/Runtime/DisconnectReason.cs.meta new file mode 100644 index 0000000..375e3a3 --- /dev/null +++ b/Runtime/DisconnectReason.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: aa4f5efaa9d4e45c69769a81b1856d68 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ISerializer.cs b/Runtime/ISerializer.cs new file mode 100644 index 0000000..8304ed4 --- /dev/null +++ b/Runtime/ISerializer.cs @@ -0,0 +1,23 @@ +namespace Shardy { + + /// + /// Serializer interface, uses in Payload + /// + public interface ISerializer { + + /// + /// Serialize data to byte array + /// + /// Target data + /// Encoded data + byte[] Encode(PayloadData body); + + /// + /// Deserialize data + /// + /// Encoded data + /// Data to use + PayloadData Decode(byte[] body); + + } +} \ No newline at end of file diff --git a/Runtime/ISerializer.cs.meta b/Runtime/ISerializer.cs.meta new file mode 100644 index 0000000..6cdfab8 --- /dev/null +++ b/Runtime/ISerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0c5ab361eab34fa3847f941f64280f0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/IValidator.cs b/Runtime/IValidator.cs new file mode 100644 index 0000000..1524687 --- /dev/null +++ b/Runtime/IValidator.cs @@ -0,0 +1,30 @@ +namespace Shardy { + + /// + /// Handshake interface for client-server validation + /// + public interface IValidator { + + /// + /// Validate acknowledgement data + /// + /// Data for validate + /// Validation result + ValidatorState VerifyAcknowledgement(byte[] body); + + /// + /// Get handshake data for send + /// + /// Data for handshake + /// Data for handshake + byte[] Handshake(byte[] body = null); + + /// + /// Get acknowledgement data for send + /// + /// Data from handshake + /// Data for acknowledge + byte[] Acknowledgement(byte[] body); + + } +} \ No newline at end of file diff --git a/Runtime/IValidator.cs.meta b/Runtime/IValidator.cs.meta new file mode 100644 index 0000000..22ec355 --- /dev/null +++ b/Runtime/IValidator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: af4b1517aeb964d3eae4f32f496dbb4f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Logger.cs b/Runtime/Logger.cs new file mode 100644 index 0000000..8d6bd02 --- /dev/null +++ b/Runtime/Logger.cs @@ -0,0 +1,119 @@ +using System; +#if !UNITY_WEBGL || UNITY_EDITOR +using UnityEngine; +#endif + +namespace Shardy { + + /// + /// Log colors + /// + public enum LogColor { + Default, + Red, + Orange, + Yellow, + Green, + Blue, + Purple + } + + /// + /// Custom logger + /// + public class Logger { + + /// + /// Date/time format for log + /// + const string DATE_FORMAT = "yyyy-MM-ddTHH:mm:ss.msZ"; + +#if UNITY_WEBGL && !UNITY_EDITOR + /// + /// Mask for log + /// + const string COMMON_MASK = "{0} {1}{2}"; + + /// + /// Mask for label + /// + const string LABEL_MASK = "{0} [{1}] {2}"; +#else + /// + /// Mask for log + /// + const string COMMON_MASK = "{0} {2}{3}"; + + /// + /// Mask for label + /// + const string LABEL_MASK = "{0} [{2}] {3}"; +#endif + + /// + /// Log info + /// + /// Data to log + /// Log label + /// Log color + public static void Info(object data, string label = "", LogColor color = LogColor.Default) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Log warning + /// + /// Data to log + /// Log label + /// Log color + public static void Warning(object data, string label = "", LogColor color = LogColor.Yellow) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogWarningFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Log error + /// + /// Data to log + /// Log label + /// Log color + public static void Error(object data, string label = "", LogColor color = LogColor.Red) { +#if UNITY_WEBGL && !UNITY_EDITOR + Console.WriteLine(string.Format(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), label, data)); +#else + Debug.LogErrorFormat(GetMask(label), DateTime.Now.ToString(DATE_FORMAT), GetColor(color), label, data); +#endif + } + + /// + /// Get mask for log + /// + /// Label for log + static string GetMask(string label) { + return string.IsNullOrEmpty(label) ? COMMON_MASK : LABEL_MASK; + } + + /// + /// Get HEX color for log + /// + /// Color index + static string GetColor(LogColor color) { + return color switch { + LogColor.Red => "#EE4B2B", + LogColor.Orange => "#FFAC1C", + LogColor.Yellow => "#FFFF8F", + LogColor.Green => "#50C878", + LogColor.Blue => "#89CFF0", + LogColor.Purple => "#BF40BF", + _ => "#CCCCCC", + }; + } + } +} \ No newline at end of file diff --git a/Runtime/Logger.cs.meta b/Runtime/Logger.cs.meta new file mode 100644 index 0000000..6a765b0 --- /dev/null +++ b/Runtime/Logger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a15d193bb62e44c18ae6ae1245499f3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Payload.cs b/Runtime/Payload.cs new file mode 100644 index 0000000..dfc1b12 --- /dev/null +++ b/Runtime/Payload.cs @@ -0,0 +1,42 @@ +using System; + +namespace Shardy { + + /// + /// Payload encode and decode block data to use in commander + /// + class Payload { + + /// + /// Encode data for transfer + /// + /// Service serializer + /// Type of data + /// Request name + /// Request id + /// Data + /// Data + /// Encoded data + public static byte[] Encode(ISerializer serializer, PayloadType type, string name, int id, byte[] data, string error) { + return serializer.Encode(new PayloadData(type, name, id, data, error)); + } + + /// + /// Decode received block + /// + /// Service serializer + /// Encoded data + /// Payload data to use in commander + public static PayloadData Decode(ISerializer serializer, byte[] data) { + return serializer.Decode(data); + } + + /// + /// Check payload for available type + /// + /// Payload data to check + public static bool Check(PayloadData payload) { + return Enum.IsDefined(typeof(PayloadType), payload.Type); + } + } +} diff --git a/Runtime/Payload.cs.meta b/Runtime/Payload.cs.meta new file mode 100644 index 0000000..869abcd --- /dev/null +++ b/Runtime/Payload.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1750fc2b77e0e4e8da84956166fd3237 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PayloadData.cs b/Runtime/PayloadData.cs new file mode 100644 index 0000000..93b2c38 --- /dev/null +++ b/Runtime/PayloadData.cs @@ -0,0 +1,52 @@ +using System; + +namespace Shardy { + + /// + /// Payload after decode + /// + [Serializable] + public struct PayloadData { + + /// + /// Type of data + /// + public PayloadType Type; + + /// + /// Command or request name + /// + public string Name; + + /// + /// Request id + /// + public int Id; + + /// + /// Data + /// + public byte[] Data; + + /// + /// Error message or code + /// + public string Error; + + /// + /// Constructor + /// + /// Payload type + /// Command or request name + /// Request id + /// Data + /// Error message or code + public PayloadData(PayloadType type, string name, int id, byte[] data, string error) { + Type = type; + Id = id; + Name = name; + Data = data; + Error = error; + } + } +} \ No newline at end of file diff --git a/Runtime/PayloadData.cs.meta b/Runtime/PayloadData.cs.meta new file mode 100644 index 0000000..a3312a7 --- /dev/null +++ b/Runtime/PayloadData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b59a7b0213a6494bb3f7f66cd76b204 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/PayloadType.cs b/Runtime/PayloadType.cs new file mode 100644 index 0000000..efe2efa --- /dev/null +++ b/Runtime/PayloadType.cs @@ -0,0 +1,23 @@ +namespace Shardy { + + /// + /// Payload type command + /// + public enum PayloadType { + + /// + /// Request and expect answer + /// + Request, + + /// + /// Command without answer, event + /// + Command, + + /// + /// Response on request + /// + Response + } +} \ No newline at end of file diff --git a/Runtime/PayloadType.cs.meta b/Runtime/PayloadType.cs.meta new file mode 100644 index 0000000..125feb2 --- /dev/null +++ b/Runtime/PayloadType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ab1f4c0c43865449ba79e044abfd0da9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins.meta b/Runtime/Plugins.meta new file mode 100644 index 0000000..cf18310 --- /dev/null +++ b/Runtime/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8dfe6a07bf5e745928b5fadf94d6eae4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/WebGL.meta b/Runtime/Plugins/WebGL.meta new file mode 100644 index 0000000..68aab10 --- /dev/null +++ b/Runtime/Plugins/WebGL.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c846a5a7495141a4851136fd38ffcf6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/WebGL/websocket.jslib b/Runtime/Plugins/WebGL/websocket.jslib new file mode 100644 index 0000000..1c2d805 --- /dev/null +++ b/Runtime/Plugins/WebGL/websocket.jslib @@ -0,0 +1,317 @@ +/** + * WebSocket library for WebGL + */ +var WebSocketLibrary = { + + /** + * Codes for websocket results + */ + $WebSocketResult: { + Default: 0, + NotFound: -1, + AlreadyConnected: -2, + NotConnected: -3, + AlreadyClosing: -4, + AlreadyClosed: -5, + NotOpened: -6, + CloseFail: -7, + SendFail: -8, + }, + + /** + * Codes for websocket states + */ + $WebSocketState: { + Connecting: 0, + Open: 1, + Closing: 2, + Closed: 3 + }, + + /** + * Manager + */ + $WebSockets: { + list: {}, + counter: 0, + onOpen: null, + onData: null, + onSend: null, + onError: null, + onClose: null, + isDebug: false + }, + + /** + * Get timestamp + * + * @returns Formatted date time + */ + $getTimestamp: function () { + var date = new Date(); + return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString(); + }, + + /** + * Callback on open connection + */ + wsSetOnOpen: function (callback) { + WebSockets.onOpen = callback; + }, + + /** + * Callback on receive data + */ + wsSetOnData: function (callback) { + WebSockets.onData = callback; + }, + + /** + * Callback on send data + */ + wsSetOnSend: function (callback) { + WebSockets.onSend = callback; + }, + + /** + * Callback on get error + */ + wsSetOnError: function (callback) { + WebSockets.onError = callback; + }, + + /** + * Callback on close + */ + wsSetOnClose: function (callback) { + WebSockets.onClose = callback; + }, + + /** + * Switch on/off debug mode + * + * @param state True or false + */ + wsSetDebug: function (state) { + WebSockets.isDebug = state; + }, + + /** + * Create new websocket connection + * + * @returns Instance id + */ + wsInit: function () { + var id = WebSockets.counter++; + WebSockets.list[id] = { + subprotocols: [], + ws: null + }; + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) init`); + } + return id; + }, + + /** + * Add subprotocol for connection + * + * @param id Instance id + * @param subprotocol Subprotocol + */ + wsAddSubProtocol: function (id, subprotocol) { + var data = UTF8ToString(subprotocol); + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) add subprotocol: ${data}`); + } + WebSockets.list[id].subprotocols.push(data); + }, + + /** + * Remove connection + * + * @param id Instance id + * @returns + */ + wsRemove: function (id) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) remove`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.Default; + }; + if (instance.ws && instance.ws.readyState < WebSocketState.Closing) { + instance.ws.close(); + } + delete WebSockets.list[id]; + return WebSocketResult.Default; + }, + + /** + * Open connection + * + * @param id Instance id + * @param url Url to connect + * @returns Result code + */ + wsConnect: function (id, url) { + var address = UTF8ToString(url); + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) connecting: ${address}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (instance.ws !== null) { + return WebSocketResult.AlreadyConnected; + } + instance.ws = new WebSocket(address, instance.subprotocols); + instance.ws.binaryType = 'arraybuffer'; + instance.ws.onopen = function () { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) connected`); + } + if (WebSockets.onOpen) { + Module.dynCall_vi(WebSockets.onOpen, id); + } + }; + instance.ws.onmessage = function (data) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) received data: ${new TextDecoder().decode(data.data)}`); + } + if (WebSockets.onData === null) { + return; + } + if (data.data instanceof ArrayBuffer) { + var dataBuffer = new Uint8Array(data.data); + var buffer = _malloc(dataBuffer.length); + HEAPU8.set(dataBuffer, buffer); + try { + Module.dynCall_viii(WebSockets.onData, id, buffer, dataBuffer.length); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) received failed: ${error.message}`); + } finally { + _free(buffer); + } + } else if (WebSockets.isDebug) { + console.warn(`${getTimestamp()} [WEBSOCKET] (${id}) received not buffer data: ${data.data}`); + } + }; + instance.ws.onerror = function (data) { + if (WebSockets.isDebug) { + var error = (data.code === undefined) ? 'unknown' : data.code; + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) error: ${error}`); + } + if (WebSockets.onError) { + Module.dynCall_vii(WebSockets.onError, id, data.code); + } + }; + instance.ws.onclose = function (data) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) closed: ${data.code}`); + } + if (WebSockets.onClose) { + Module.dynCall_vii(WebSockets.onClose, id, data.code); + } + delete instance.ws; + }; + return WebSocketResult.Default; + }, + + /** + * Close connection + * + * @param id Instance id + * @param code + * @param reason + * @returns Result code + */ + wsClose: function (id, code, reason) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) close: ${code}, reason: ${reason}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (!instance.ws) { + return WebSocketResult.NotConnected; + } + if (instance.ws.readyState === WebSocketState.Closing) { + return WebSocketResult.AlreadyClosing; + } + if (instance.ws.readyState === WebSocketState.Closed) { + return WebSocketResult.AlreadyClosed; + } + var result = (reason ? UTF8ToString(reason) : undefined); + try { + instance.ws.close(code, result); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) close error: ${error.message}`); + return WebSocketResult.CloseFail; + } + return WebSocketResult.Default; + }, + + /** + * Send buffer + * @param id Instance id + * @param buffer Data + * @param length Data length + * @returns Result code + */ + wsSend: function (id, data, length) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) send ${length} bytes: ${data}`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (!instance.ws) { + return WebSocketResult.NotConnected; + } + if (instance.ws.readyState !== WebSocketState.Open) { + return WebSocketResult.NotOpened; + } + try { + instance.ws.send(HEAPU8.buffer.slice(data, data + length)); + } catch (error) { + console.error(`${getTimestamp()} [WEBSOCKET] (${id}) send error: ${error.message}`); + return WebSocketResult.SendFail; + } + if (WebSockets.onSend) { + Module.dynCall_vi(WebSockets.onSend, id); + } + return WebSocketResult.Default; + }, + + /** + * Get connection state + * @param id Instance id + * @returns Result code + */ + wsGetState: function (id) { + if (WebSockets.isDebug) { + console.log(`${getTimestamp()} [WEBSOCKET] (${id}) get state`); + } + var instance = WebSockets.list[id]; + if (!instance) { + return WebSocketResult.NotFound; + } + if (instance.ws) { + return instance.ws.readyState; + } else { + return WebSocketState.Closed; + } + } + +}; + +autoAddDeps(WebSocketLibrary, '$WebSockets'); +autoAddDeps(WebSocketLibrary, '$WebSocketResult'); +autoAddDeps(WebSocketLibrary, '$WebSocketState'); +autoAddDeps(WebSocketLibrary, '$getTimestamp'); +mergeInto(LibraryManager.library, WebSocketLibrary); \ No newline at end of file diff --git a/Runtime/Plugins/WebGL/websocket.jslib.meta b/Runtime/Plugins/WebGL/websocket.jslib.meta new file mode 100644 index 0000000..81745ae --- /dev/null +++ b/Runtime/Plugins/WebGL/websocket.jslib.meta @@ -0,0 +1,32 @@ +fileFormatVersion: 2 +guid: d0af6ca4ab28342039b5d382e4887de7 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + WebGL: WebGL + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/iOS.meta b/Runtime/Plugins/iOS.meta new file mode 100644 index 0000000..bf488ef --- /dev/null +++ b/Runtime/Plugins/iOS.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e79797a38127f4967bb79f15ac6c123b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Plugins/iOS/IPv6.mm b/Runtime/Plugins/iOS/IPv6.mm new file mode 100644 index 0000000..5e592e2 --- /dev/null +++ b/Runtime/Plugins/iOS/IPv6.mm @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#define MakeStringCopy(x) (x != NULL && [x isKindOfClass:[NSString class]]) ? strdup([x UTF8String]) : NULL + +extern "C" { + +const char *CheckIPv6(const char *host) { + if (host == nil) { + return NULL; + } + const char *data = "No"; + int n; + struct addrinfo *res; + struct addrinfo *res0; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_DEFAULT; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if ((n = getaddrinfo(host, "http", &hints, &res0)) != 0) { + return NULL; + } + struct sockaddr_in6 *addr6; + NSString *ipv6 = NULL; + char ipbuf[32]; + for (res = res0; res; res = res->ai_next) { + if (res->ai_family == AF_INET6) { + addr6 = (struct sockaddr_in6 *) res->ai_addr; + data = inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, sizeof(ipbuf)); + NSString *temp = [[NSString alloc] initWithCString:(const char *) data encoding:NSASCIIStringEncoding]; + ipv6 = temp; + } else { + ipv6 = NULL; + } + break; + } + freeaddrinfo(res0); + NSString *result = ipv6; + return MakeStringCopy(result); +} + +} diff --git a/Runtime/Plugins/iOS/IPv6.mm.meta b/Runtime/Plugins/iOS/IPv6.mm.meta new file mode 100644 index 0000000..e89f1f6 --- /dev/null +++ b/Runtime/Plugins/iOS/IPv6.mm.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: b7a227195df3b4848a2c16f93a905468 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Protocol.cs b/Runtime/Protocol.cs new file mode 100644 index 0000000..195e490 --- /dev/null +++ b/Runtime/Protocol.cs @@ -0,0 +1,244 @@ +๏ปฟusing System; + +namespace Shardy { + + /// + /// Protocol state + /// + enum ProtocolState { + + /// + /// Init state, wait for handshake + /// + Start, + + /// + /// Handshake is in progress + /// + Handshake, + + /// + /// Work state after success handshake + /// + Work, + + /// + /// Protocol closed, any actions ignored + /// + Closed + } + + + /// + /// Protocol to manage all data from transport, and send to connection handlers + /// + class Protocol { + + /// + /// Log tag + /// + const string TAG = "PROTOCOL"; + + /// + /// Data callback + /// + public Action OnBlock = delegate { }; + + /// + /// Disconnect callback + /// + public Action OnDisconnect = delegate { }; + + /// + /// Current protocol state + /// + ProtocolState _state = ProtocolState.Closed; + + /// + /// Current transporter + /// + readonly Transport _transport = null; + + /// + /// Protocol constructor + /// + /// Current connection + public Protocol(Connection connection) { + _transport = new Transport(connection); + _transport.OnData = (data) => OnData(data); + _transport.OnDisconnect = () => OnClose(); + } + + /// + /// Start protocol and transport + /// + public void Start() { + _state = ProtocolState.Start; + _transport.Start(); + } + + /// + /// Send data to transport + /// + /// Type of block data + /// Data for transfer + internal void Dispatch(BlockType type, byte[] body = null) { + if (_state == ProtocolState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("send data to closed protocol", TAG); +#endif + return; + } + body ??= (new byte[0]); +#if SHARDY_DEBUG_RAW + Logger.Info($"dispatch type: {type}, body: {Utils.DataToDebug(body)}", TAG); +#endif + var data = Block.Encode(type, body); + _transport.Dispatch(data); + } + + /// + /// Send data to connection + /// + /// Serialized command data + public void Send(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info($"send data: {Utils.DataToDebug(body)}", TAG); +#endif + Dispatch(BlockType.Data, body); + } + + /// + /// Send heartbeat to connection + /// + public void Heartbeat() { +#if SHARDY_DEBUG_RAW + Logger.Info("send heartbeat", TAG); +#endif + Dispatch(BlockType.Heartbeat); + } + + /// + /// Send handshake to connection + /// + /// Handshake data + public void Handshake(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info("send handshake", TAG); +#endif + _state = ProtocolState.Handshake; + Dispatch(BlockType.Handshake, body); + } + + /// + /// Send acknowledgement + /// + /// Acknowledge data + public void Acknowledge(byte[] body) { +#if SHARDY_DEBUG_RAW + Logger.Info("send acknowledge", TAG); +#endif + _state = ProtocolState.Work; + Dispatch(BlockType.HandshakeAcknowledgement, body); + } + + /// + /// Disconnect from server + /// + public void Disconnect() { + _state = ProtocolState.Closed; +#if SHARDY_DEBUG_RAW + Logger.Info("disconnect", TAG); +#endif + _transport.Close(); + } + + /// + /// Callback from transport when disconnected + /// + internal void OnClose() { + _state = ProtocolState.Closed; + OnDisconnect(); + } + + /// + /// Decode data to package + /// Select behaviour by package type + /// + /// Buffer bytes array + internal void OnData(byte[] data) { + if (_state == ProtocolState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("received data to closed protocol", TAG); +#endif + return; + } + var block = Block.Decode(data); + if (!Block.Check(block.Type)) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid block type: {block.Type}, state: {_state}", TAG); +#endif + return; + } +#if SHARDY_DEBUG_RAW + Logger.Info($"received block: {block.Type}, data: {Utils.DataToDebug(block.Body)}, state: {_state}", TAG); +#endif + switch (_state) { + case ProtocolState.Start: + if (block.Type == BlockType.Heartbeat) { + OnBlock(block); + } else { + CatchBlockForState(block.Type); + } + break; + case ProtocolState.Work: + switch (block.Type) { + case BlockType.Heartbeat: + case BlockType.Kick: + case BlockType.Data: + OnBlock(block); + break; + default: + CatchBlockForState(block.Type); + break; + } + break; + case ProtocolState.Handshake: + switch (block.Type) { + case BlockType.HandshakeAcknowledgement: + case BlockType.Kick: + OnBlock(block); + break; + default: + CatchBlockForState(block.Type); + break; + } + break; + default: + CatchBlockForState(block.Type); + break; + } + } + + /// + /// Catch and log incorrect situation + /// + /// Block type + void CatchBlockForState(BlockType type) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid block type: {type}, state: {_state}", TAG); +#endif + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _state = ProtocolState.Closed; + _transport.Destroy(); + } + } +} \ No newline at end of file diff --git a/Runtime/Protocol.cs.meta b/Runtime/Protocol.cs.meta new file mode 100644 index 0000000..2bcd576 --- /dev/null +++ b/Runtime/Protocol.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 05073643c2eff400689ddc8f3679e867 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Pulse.cs b/Runtime/Pulse.cs new file mode 100644 index 0000000..6379c35 --- /dev/null +++ b/Runtime/Pulse.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading; + +#pragma warning disable 4014 + +namespace Shardy { + + /// + /// Pulse service for support connection + /// + class Pulse { + + /// + /// Callback + /// + public Action OnPulse = delegate { }; + + /// + /// Cancellation token source + /// + readonly CancellationTokenSource _cancellation = new CancellationTokenSource(); + + /// + /// Checks counter + /// + int _checks = 0; + + /// + /// Constructor + /// + /// Interval to check pulse + public Pulse(float interval) { + Utils.SetTimer(interval, _cancellation, () => CheckPulse()); + } + + /// + /// Pulse checker + /// + public void CheckPulse() { + _checks++; + if (_checks > 1) { + Reset(); + OnPulse(); + } + } + + /// + /// Reset timer when commands received + /// + public void Reset() { + _checks = 0; + } + + /// + /// Stop and switch off service + /// + public void Clear() { + Reset(); + _cancellation.Cancel(); + } + } +} \ No newline at end of file diff --git a/Runtime/Pulse.cs.meta b/Runtime/Pulse.cs.meta new file mode 100644 index 0000000..e2da804 --- /dev/null +++ b/Runtime/Pulse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0df7a1de43fa74a0082f87d7555abd11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ReceivedData.cs b/Runtime/ReceivedData.cs new file mode 100644 index 0000000..eed7a84 --- /dev/null +++ b/Runtime/ReceivedData.cs @@ -0,0 +1,28 @@ +namespace Shardy { + + /// + /// Data received from socket + /// + public struct ReceivedData { + + /// + /// Data length + /// + public int Length; + + /// + /// Data bytes array + /// + public byte[] Body; + + /// + /// Constructor + /// + /// Data for block + /// Data length + public ReceivedData(byte[] body, int length) { + Body = body; + Length = length; + } + } +} \ No newline at end of file diff --git a/Runtime/ReceivedData.cs.meta b/Runtime/ReceivedData.cs.meta new file mode 100644 index 0000000..48c8ce0 --- /dev/null +++ b/Runtime/ReceivedData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e038338fdd7174c1d9c61c93390d27b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Shardy.asmdef b/Runtime/Shardy.asmdef new file mode 100644 index 0000000..f3565fa --- /dev/null +++ b/Runtime/Shardy.asmdef @@ -0,0 +1,14 @@ +{ + "name": "Shardy", + "rootNamespace": "Shardy", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Runtime/Shardy.asmdef.meta b/Runtime/Shardy.asmdef.meta new file mode 100644 index 0000000..bc3bcaa --- /dev/null +++ b/Runtime/Shardy.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9b891ca15e43e41c6bac338ce42625c8 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Transport.cs b/Runtime/Transport.cs new file mode 100644 index 0000000..c0a4f9d --- /dev/null +++ b/Runtime/Transport.cs @@ -0,0 +1,360 @@ +using System; +using System.Net.WebSockets; + +namespace Shardy { + + /// + /// Transporter state + /// + enum TransportState { + + /// + /// Receive head data + /// + Head, + + /// + /// Receive body data + /// + Body, + + /// + /// Transport is closed, no more data received + /// + Closed + } + + /// + /// Transporter for protocol + /// Manage how data should send and receive to protocol + /// + class Transport { + + /// + /// Log tag + /// + const string TAG = "TRANSPORT"; + + /// + /// Callback to return data to handler + /// + public Action OnData = delegate { }; + + /// + /// Callback to return disconnect state + /// + public Action OnDisconnect = delegate { }; + + /// + /// Current transporter state + /// + TransportState _state = TransportState.Closed; + + /// + /// Common buffer array + /// + byte[] _buffer = null; + + /// + /// Offset to write buffer + /// + int _offset = 0; + + /// + /// Length of current package + /// + int _package = 0; + + /// + /// Current connection + /// + Connection _connection = null; + + /// + /// Constructor + /// + /// Connection instance + public Transport(Connection connection) { + _connection = connection; + } + + /// + /// Start receiving data + /// + public void Start() { + _state = TransportState.Head; + Receive(); + } + + /// + /// Send data to socket + /// + /// Bytes array + public async void Dispatch(byte[] buffer) { + if (!_connection.IsConnected) { +#if SHARDY_DEBUG_RAW + Logger.Warning("try send data with disconnected", TAG); +#endif + return; + } + if (_state != TransportState.Closed) { + try { + await _connection.Send(buffer); + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("send operation canceled", TAG); +#endif + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"send failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Warning($"send data when state closed: {Utils.DataToDebug(buffer)}", TAG); +#endif + } + } + + /// + /// Close this transport + /// + public void Close() { + try { + if (_connection != null) { + _connection.Cancel(); + _connection.Close(); + } + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"close failed: {e}", TAG); +#endif + } + } + + /// + /// Begin receive data from socket + /// + public async void Receive() { + if (_state == TransportState.Closed) { +#if SHARDY_DEBUG_RAW + Logger.Warning("received data on closed state", TAG); +#endif + return; + } + ReceivedData data = default; + try { + data = await _connection.Receive(); + } catch (OperationCanceledException) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive operation canceled", TAG); +#endif + ReceiveEnd(); + return; + } catch (WebSocketException e) { + if (e.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive websocket closed prematurely", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive websocket failed: {e}", TAG); +#endif + } + ReceiveEnd(); + return; + } catch (Exception e) { + if (e.GetBaseException() is WebSocketException exception) { + if (exception.WebSocketErrorCode == WebSocketError.ConnectionClosedPrematurely) { +#if SHARDY_DEBUG_RAW + Logger.Info("receive as websocket closed prematurely", TAG); +#endif + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive as websocket failed: {e}", TAG); +#endif + } + } else { +#if SHARDY_DEBUG_RAW + Logger.Error($"receive failed: {e}", TAG); +#endif + } + ReceiveEnd(); + return; + } + if (!_connection.IsConnected && data.Length > 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning("try receive data with disconnected", TAG); +#endif + return; + } +#if SHARDY_DEBUG_RAW + Logger.Info($"received size: {data.Length}, data: {Utils.DataToDebug(data.Body)}", TAG); +#endif + if (data.Length > 0) { + ProcessData(data.Body, 0, data.Length); + Receive(); + } else { + ReceiveEnd(); + } + } + + /// + /// Actions when receive finished + /// + void ReceiveEnd() { + _state = TransportState.Closed; + Close(); + OnDisconnect(); + } + + /// + /// Detect what to read and read it + /// + /// Data array + /// Offet to read + /// Length to read + internal void ProcessData(byte[] bytes, int offset, int limit) { + switch (_state) { + case TransportState.Head: + ReadHead(bytes, offset, limit); + break; + case TransportState.Body: + ReadBody(bytes, offset, limit); + break; + default: +#if SHARDY_DEBUG_RAW + Logger.Warning($"process bytes on incorrect state: {_state}", TAG); +#endif + break; + } + } + + /// + /// Get package size from head + /// + /// Head buffer + int GetPackageSize(byte[] buffer) { + var result = 0; + for (var i = 1; i < Block.HEAD_SIZE; i++) { + if (i > 1) { + result <<= 8; + } + result += buffer[i]; + } + return result; + } + + /// + /// Read header + /// + /// Data array + /// Offet to read + /// Length to read + /// Correct header or not + bool ReadHead(byte[] bytes, int offset, int limit) { + var length = limit - offset; + var head = new byte[Block.HEAD_SIZE]; + var size = Block.HEAD_SIZE - _offset; + if (length >= size) { + WriteBytes(bytes, offset, size, _offset, head); + _package = GetPackageSize(head); + if (_package < 0) { +#if SHARDY_DEBUG_RAW + Logger.Warning($"invalid package size: {_package}", TAG); +#endif + size = 0; + } + _buffer = new byte[Block.HEAD_SIZE + _package]; + WriteBytes(head, 0, Block.HEAD_SIZE, _buffer); + offset += size; + _offset = Block.HEAD_SIZE; + _state = TransportState.Body; + if (offset <= limit) { + ProcessData(bytes, offset, limit); + } + return true; + } else { + WriteBytes(bytes, offset, length, _offset, head); + _offset += length; + return false; + } + } + + /// + /// Read body + /// + /// Data array + /// Offet to read + /// Length to read + void ReadBody(byte[] bytes, int offset, int limit) { + var length = _package + Block.HEAD_SIZE - _offset; + if ((offset + length) <= limit) { + WriteBytes(bytes, offset, length, _offset, _buffer); + offset += length; + OnData(_buffer); + Reset(); + if (offset < limit) { + ProcessData(bytes, offset, limit); + } + } else { + WriteBytes(bytes, offset, limit - offset, _offset, _buffer); + _offset += limit - offset; + _state = TransportState.Body; + } + } + + /// + /// Reset all data after receive full package + /// + void Reset() { + _offset = 0; + _package = 0; + if (_state != TransportState.Closed) { + _state = TransportState.Head; + } + } + + /// + /// Write to buffer + /// + /// Source array + /// Start offset + /// Length to write + /// Target to write + void WriteBytes(byte[] source, int start, int length, byte[] target) { + WriteBytes(source, start, length, 0, target); + } + + /// Write to buffer + /// + /// Source array + /// Start offset + /// Length to write + /// Offset on target array + /// Target to write + void WriteBytes(byte[] source, int start, int length, int offset, byte[] target) { + for (var i = 0; i < length; i++) { + target[offset + i] = source[start + i]; + } + } + + /// + /// Destroy all + /// + public void Destroy() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + _state = TransportState.Closed; + try { + _connection.Destroy(); + _connection = null; + } catch (Exception e) { +#if SHARDY_DEBUG_RAW + Logger.Error($"destroy failed: {e}", TAG); +#endif + } + } + } +} \ No newline at end of file diff --git a/Runtime/Transport.cs.meta b/Runtime/Transport.cs.meta new file mode 100644 index 0000000..d58f5ad --- /dev/null +++ b/Runtime/Transport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f15005000f27e4050bf9c56e686b5856 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/TransportType.cs b/Runtime/TransportType.cs new file mode 100644 index 0000000..b5d2ad9 --- /dev/null +++ b/Runtime/TransportType.cs @@ -0,0 +1,18 @@ +namespace Shardy { + + /// + /// Type of transport + /// + public enum TransportType { + + /// + /// TCP sockets transport + /// + Tcp, + + /// + /// Websockets transport + /// + WebSocket + } +} \ No newline at end of file diff --git a/Runtime/TransportType.cs.meta b/Runtime/TransportType.cs.meta new file mode 100644 index 0000000..c98a403 --- /dev/null +++ b/Runtime/TransportType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a733b44d06d6f40bc949dc260fff979d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Utils.cs b/Runtime/Utils.cs new file mode 100644 index 0000000..2590cf9 --- /dev/null +++ b/Runtime/Utils.cs @@ -0,0 +1,134 @@ +using System; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Shardy { + + /// + /// Some usefull functions + /// + public static class Utils { + + /// + /// Custom timer for WebGL compatibility + /// + /// Interval for timer, ms + /// Cancellation source + /// Callback on tick + public static async Task SetTimer(float interval, CancellationTokenSource cancellation, Action callback) { + while (!cancellation.IsCancellationRequested) { + await SetDelay(interval); + callback(); + } + } + + /// + /// Make delay + /// Hack to prevent using Task.Delay in WebGL + /// + /// Delay in ms + public static async Task SetDelay(float delay) { + var target = DateTime.Now.AddMilliseconds(delay); + while (DateTime.Now < target) { + await Task.Yield(); + } + } + + /// + /// Extension to add cancellation for task + /// + public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { + var source = new TaskCompletionSource(); + using (cancellationToken.Register(state => ((TaskCompletionSource)state).TrySetResult(true), source)) { + if (task != await Task.WhenAny(task, source.Task)) { + throw new OperationCanceledException(cancellationToken); + } + } + return task.Result; + } + + /// + /// Extension to add cancellation for task + /// + public static async Task WithCancellation(this Task task, CancellationToken cancellationToken) { + var source = new TaskCompletionSource(); + using (cancellationToken.Register(state => ((TaskCompletionSource)state).TrySetResult(true), source)) { + if (task != await Task.WhenAny(task, source.Task).ConfigureAwait(false)) { + throw new OperationCanceledException(cancellationToken); + } + await task; + } + } + + /// + /// Convert data to string + /// + public static string DataToString(byte[] data) { + return (data == null) ? string.Empty : Encoding.UTF8.GetString(data); + } + +#if SHARDY_DEBUG || SHARDY_DEBUG_RAW + + /// + /// Convert data to log string + /// + public static string DataToDebug(byte[] data) { + return (data == null) ? string.Empty : ToLiteral(Encoding.UTF8.GetString(data)); + } + + /// + /// Escape string for log + /// + /// Input string + static string ToLiteral(string data) { + var literal = new StringBuilder(data.Length); + foreach (var c in data) { + switch (c) { + case '\"': + literal.Append("\\\""); + break; + case '\\': + literal.Append(@"\\"); + break; + case '\0': + literal.Append(@"\0"); + break; + case '\a': + literal.Append(@"\a"); + break; + case '\b': + literal.Append(@"\b"); + break; + case '\f': + literal.Append(@"\f"); + break; + case '\n': + literal.Append(@"\n"); + break; + case '\r': + literal.Append(@"\r"); + break; + case '\t': + literal.Append(@"\t"); + break; + case '\v': + literal.Append(@"\v"); + break; + default: + if (c >= 0x20 && c <= 0x7e) { + literal.Append(c); + } else { + literal.Append(@"\u"); + literal.Append(((int)c).ToString("x4")); + } + break; + } + } + return literal.ToString(); + } + +#endif + + } +} \ No newline at end of file diff --git a/Runtime/Utils.cs.meta b/Runtime/Utils.cs.meta new file mode 100644 index 0000000..12e7761 --- /dev/null +++ b/Runtime/Utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ffe31bde2d4c542dca0c306856360791 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ValidatorState.cs b/Runtime/ValidatorState.cs new file mode 100644 index 0000000..d037178 --- /dev/null +++ b/Runtime/ValidatorState.cs @@ -0,0 +1,18 @@ +namespace Shardy { + + /// + /// Validator state + /// + public enum ValidatorState { + + /// + /// Handshake passed + /// + Success, + + /// + /// Handshake failed + /// + Failed + } +} \ No newline at end of file diff --git a/Runtime/ValidatorState.cs.meta b/Runtime/ValidatorState.cs.meta new file mode 100644 index 0000000..623641a --- /dev/null +++ b/Runtime/ValidatorState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b17c053b8922c4d3fb3434dc532c4489 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/WebSocket.cs b/Runtime/WebSocket.cs new file mode 100644 index 0000000..e5b2900 --- /dev/null +++ b/Runtime/WebSocket.cs @@ -0,0 +1,291 @@ +#if UNITY_WEBGL + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace Shardy { + + /// + /// Condition key for wait callback + /// + enum WaitCondition { + Open, + Send, + Close + } + + /// + /// Websocket state codes + /// + enum WebSocketStateCode { + Connecting, + Open, + Closing, + Closed, + Error + } + + /// + /// Return error codes + /// + enum WebSocketErrorCode { + NotFound = -1, + AlreadyConnected = -2, + NotConnected = -3, + AlreadyClosing = -4, + AlreadyClosed = -5, + NotOpened = -6, + CloseFail = -7, + SendFail = -8, + Unknown = -999 + } + + /// + /// Websocket code for close + /// + enum WebSocketCloseCode { + NotSet = 0, + Normal = 1000, + Away = 1001, + ProtocolError = 1002, + UnsupportedData = 1003, + Undefined = 1004, + NoStatus = 1005, + Abnormal = 1006, + InvalidData = 1007, + PolicyViolation = 1008, + TooBig = 1009, + MandatoryExtension = 1010, + ServerError = 1011, + TlsHandshakeFailure = 1015 + } + + /// + /// WebSocket class for WebGL using + /// + class WebSocket { + + /// + /// Log tag + /// + const string TAG = "WEBSOCKET"; + + /// + /// Delay, ms + /// + const float DELAY = 10f; + + /// + /// Callback on socket open + /// + public Action OnOpen = delegate { }; + + /// + /// Callback on socket send + /// + public Action OnSend = delegate { }; + + /// + ///Callback on message receive + /// + public Action OnData = delegate { }; + + /// + /// Callback on error receive + /// + public Action OnError = delegate { }; + + /// + /// Callback on close socket + /// + public Action OnClose = delegate { }; + + /// + /// Connect to socket + /// + [DllImport("__Internal")] + public static extern int wsConnect(int id, string url); + + /// + /// Close socket + /// + [DllImport("__Internal")] + public static extern int wsClose(int id, int code, string reason); + + /// + /// Send buffer to socket + /// + [DllImport("__Internal")] + public static extern int wsSend(int id, byte[] data, int length); + + /// + /// Get current state + /// + [DllImport("__Internal")] + public static extern int wsGetState(int id); + + /// + /// Dict for check waitable vars + /// + readonly Dictionary _conditions = new Dictionary(3); + + /// + /// Received buffer + /// + List _buffer = new List(); + + /// + /// Current socket instance id + /// + protected int _id = -1; + + /// + /// Create websocket + /// + public WebSocket() { + _id = WebSocketManager.Add(this); + Subscribe(); + } + + /// + /// Create websocket + /// + /// Optional subprotocol + public WebSocket(string subprotocol) { + _id = WebSocketManager.Add(this); + WebSocketManager.wsAddSubProtocol(_id, subprotocol); + Subscribe(); + } + + /// + /// Create websocket + /// + /// Optional subprotocols list + public WebSocket(List subprotocols) { + _id = WebSocketManager.Add(this); + foreach (var subprotocol in subprotocols) { + WebSocketManager.wsAddSubProtocol(_id, subprotocol); + } + Subscribe(); + } + + /// + /// Subscribe for inner callbacks + /// + void Subscribe() { + _conditions[WaitCondition.Open] = false; + _conditions[WaitCondition.Send] = false; + _conditions[WaitCondition.Close] = false; + OnOpen += () => _conditions[WaitCondition.Open] = true; + OnSend += () => _conditions[WaitCondition.Send] = true; + OnClose += (WebSocketCloseCode code) => _conditions[WaitCondition.Close] = true; + OnData += (byte[] data, int length) => { + _buffer.Add(new ReceivedData(data, length)); + }; + } + + /// + /// Remove websocket + /// + ~WebSocket() { +#if SHARDY_DEBUG_RAW + Logger.Info("destroy", TAG); +#endif + WebSocketManager.wsRemove(_id); + } + + /// + /// Current socket id + /// + public int Id { + get { + return _id; + } + } + + /// + /// Current state + /// + public WebSocketStateCode State { + get { + var state = wsGetState(_id); + return state switch { + 0 => WebSocketStateCode.Connecting, + 1 => WebSocketStateCode.Open, + 2 => WebSocketStateCode.Closing, + 3 => WebSocketStateCode.Closed, + _ => WebSocketStateCode.Error, + }; + } + } + + /// + /// Check return code state on error + /// + /// Return state + /// Has error or not + bool CheckState(int state) { + if (state < 0) { +#if SHARDY_DEBUG + var error = Enum.IsDefined(typeof(WebSocketErrorCode), state) ? (WebSocketErrorCode)state : WebSocketErrorCode.Unknown; + Logger.Error($"state error: {error}", TAG); +#endif + return false; + } + return true; + } + + /// + /// Connect to server + /// + public async Task Connect(string url) { + var state = wsConnect(_id, url); + while (!_conditions[WaitCondition.Open]) { + await Utils.SetDelay(DELAY); + } + return CheckState(state); + } + + /// + /// Close connection + /// + /// Close code + /// Reason + public bool Close(WebSocketCloseCode code = WebSocketCloseCode.Normal, string reason = null) { + var state = wsClose(_id, (int)code, reason); + return CheckState(state); + } + + /// + /// Send data as buffer + /// + /// Array of bytes + public async Task Send(byte[] data) { + var state = wsSend(_id, data, data.Length); + while (!_conditions[WaitCondition.Send]) { + await Utils.SetDelay(DELAY); + } + _conditions[WaitCondition.Send] = false; + return CheckState(state); + } + + /// + /// Receive data from socket + /// + /// Buffer to write + /// Received length + public async Task Receive(byte[] buffer) { + while (_buffer.Count == 0) { + await Utils.SetDelay(DELAY); + } + var data = _buffer[0]; + _buffer.RemoveAt(0); + Array.Copy(data.Body, 0, buffer, 0, data.Length); + return data.Length; + } + } +} + +#endif \ No newline at end of file diff --git a/Runtime/WebSocket.cs.meta b/Runtime/WebSocket.cs.meta new file mode 100644 index 0000000..aacc090 --- /dev/null +++ b/Runtime/WebSocket.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4dbdc96924f6748ceba47023cd6b2600 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/WebSocketManager.cs b/Runtime/WebSocketManager.cs new file mode 100644 index 0000000..b10f5e8 --- /dev/null +++ b/Runtime/WebSocketManager.cs @@ -0,0 +1,219 @@ +#if UNITY_WEBGL + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using AOT; + +namespace Shardy { + + /// + /// Websocket manager for WebGL + /// + static class WebSocketManager { + + /// + /// List of websockets + /// + static readonly Dictionary _list = new Dictionary(); + + /// + /// On open socket delegate + /// + /// Instance id + public delegate void OnOpen(int id); + + /// + /// On send to socket delegate + /// + /// Instance id + public delegate void OnSend(int id); + + /// + /// On data receive delegate + /// + /// Instance id + /// Pointer to message + /// Data length + public delegate void OnData(int id, IntPtr message, int length); + + /// + /// On error receive delegate + /// + /// Instance id + /// Error code + public delegate void OnError(int id, int code); + + /// + /// On close socket delegate + /// + /// Instance id + /// Close code + public delegate void OnClose(int id, int code); + + /// + /// Set on/off debug mode + /// + [DllImport("__Internal")] + public static extern int wsSetDebug(bool value); + + /// + /// Create new websocket instance + /// + [DllImport("__Internal")] + public static extern int wsInit(); + + /// + /// Remove websocket + /// + [DllImport("__Internal")] + public static extern void wsRemove(int id); + + /// + /// Add subprotocol + /// + [DllImport("__Internal")] + public static extern int wsAddSubProtocol(int id, string subprotocol); + + /// + /// Set on open callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnOpen(OnOpen callback); + + /// + /// Set on send callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnSend(OnSend callback); + + /// + /// Set on data receive callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnData(OnData callback); + + /// + /// Set on error receive callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnError(OnError callback); + + /// + /// Set on close callback for instance + /// + [DllImport("__Internal")] + public static extern void wsSetOnClose(OnClose callback); + + /// + /// Flag to check initialized + /// + static bool _isInitialized = false; + + /// + /// Set debug mode + /// + public static void SetDebug(bool value) { + wsSetDebug(value); + } + + /// + /// Set callbacks + /// + public static void Init() { + if (!_isInitialized) { + wsSetOnOpen(OnOpenEvent); + wsSetOnSend(OnSendEvent); + wsSetOnData(OnDataEvent); + wsSetOnError(OnErrorEvent); + wsSetOnClose(OnCloseEvent); + _isInitialized = true; + } + } + + /// + /// Add new socket + /// + /// Websocket instance + /// Id + public static int Add(WebSocket socket) { + var id = wsInit(); + _list.Add(id, socket); + return id; + } + + /// + /// Remove websocket instance + /// + /// Instance id + public static void Destroy(int id) { + if (_list.ContainsKey(id)) { + _list.Remove(id); + wsRemove(id); + } + } + + /// + /// On open event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnOpen))] + public static void OnOpenEvent(int id) { + if (_list.ContainsKey(id)) { + _list[id].OnOpen(); + } + } + + /// + /// On send event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnSend))] + public static void OnSendEvent(int id) { + if (_list.ContainsKey(id)) { + _list[id].OnSend(); + } + } + + /// + /// On data receive event from jslib + /// + /// Instance id + [MonoPInvokeCallback(typeof(OnData))] + public static void OnDataEvent(int id, IntPtr message, int length) { + if (_list.ContainsKey(id)) { + var data = new byte[length]; + Marshal.Copy(message, data, 0, length); + _list[id].OnData(data, length); + } + } + + /// + /// On error receive event from jslib + /// + /// Instance id + /// Error code + [MonoPInvokeCallback(typeof(OnError))] + public static void OnErrorEvent(int id, int code) { + if (_list.ContainsKey(id)) { + var error = Enum.IsDefined(typeof(WebSocketErrorCode), code) ? (WebSocketErrorCode)code : WebSocketErrorCode.Unknown; + _list[id].OnError(error); + } + } + + /// + /// On close event from jslib + /// + /// Instance id + /// Close code + [MonoPInvokeCallback(typeof(OnClose))] + public static void OnCloseEvent(int id, int code) { + if (_list.ContainsKey(id)) { + var result = Enum.IsDefined(typeof(WebSocketCloseCode), code) ? (WebSocketCloseCode)code : WebSocketCloseCode.Undefined; + _list[id].OnClose(result); + } + } + } +} + +#endif \ No newline at end of file diff --git a/Runtime/WebSocketManager.cs.meta b/Runtime/WebSocketManager.cs.meta new file mode 100644 index 0000000..6fc5841 --- /dev/null +++ b/Runtime/WebSocketManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7ab03736437e4580866c7a13004ee9c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo.meta b/Samples~/Demo.meta new file mode 100644 index 0000000..1937e4b --- /dev/null +++ b/Samples~/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d70a34e1790ec4fb6ba0568b3faf4061 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scenes.meta b/Samples~/Demo/Scenes.meta new file mode 100644 index 0000000..9e9ab46 --- /dev/null +++ b/Samples~/Demo/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 49ae41e15900a4725956bbee5c3d4533 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scenes/Demo.unity b/Samples~/Demo/Scenes/Demo.unity new file mode 100644 index 0000000..b9badd5 --- /dev/null +++ b/Samples~/Demo/Scenes/Demo.unity @@ -0,0 +1,6314 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &86744315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 86744318} + - component: {fileID: 86744317} + - component: {fileID: 86744316} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &86744316 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &86744317 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &86744318 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 86744315} + 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 &87791714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 87791715} + - component: {fileID: 87791717} + - component: {fileID: 87791716} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &87791715 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + 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: 876135628} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &87791716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Subscribe + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &87791717 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87791714} + m_CullTransparentMesh: 1 +--- !u!1 &115949711 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 115949713} + - component: {fileID: 115949715} + - component: {fileID: 115949714} + - component: {fileID: 115949712} + m_Layer: 5 + m_Name: PortInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &115949712 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 115949714} + m_TextViewport: {fileID: 322493275} + m_TextComponent: {fileID: 2097740590} + m_Placeholder: {fileID: 2098744277} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 2 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 4 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 2 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 3000 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!224 &115949713 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 322493275} + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 144, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &115949714 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &115949715 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 115949711} + m_CullTransparentMesh: 1 +--- !u!1 &150526394 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 150526395} + - component: {fileID: 150526398} + - component: {fileID: 150526397} + - component: {fileID: 150526396} + m_Layer: 5 + m_Name: OffRequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &150526395 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 448535453} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &150526396 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 150526397} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: UnsubscribeRequest + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &150526397 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &150526398 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 150526394} + m_CullTransparentMesh: 1 +--- !u!1 &185570083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 185570084} + - component: {fileID: 185570087} + - component: {fileID: 185570086} + - component: {fileID: 185570085} + m_Layer: 5 + m_Name: LogScroll + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &185570084 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1461012000} + - {fileID: 396431563} + m_Father: {fileID: 1917894912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 32} + m_SizeDelta: {x: -64, y: 224} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &185570085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1561090812} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 1461012000} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 396431564} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &185570086 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &185570087 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 185570083} + m_CullTransparentMesh: 1 +--- !u!1 &207479224 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 207479225} + - component: {fileID: 207479226} + m_Layer: 5 + m_Name: HostPort + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &207479225 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207479224} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1926762628} + - {fileID: 798780212} + - {fileID: 1189404154} + - {fileID: 115949713} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &207479226 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207479224} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 3 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &322493274 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 322493275} + - component: {fileID: 322493276} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &322493275 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 322493274} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2098744280} + - {fileID: 2097740592} + m_Father: {fileID: 115949713} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &322493276 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 322493274} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &396431562 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 396431563} + - component: {fileID: 396431566} + - component: {fileID: 396431565} + - component: {fileID: 396431564} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &396431563 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 444005365} + m_Father: {fileID: 185570084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 48, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &396431564 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1809996613} + m_HandleRect: {fileID: 1809996612} + m_Direction: 2 + m_Value: 0.52008855 + m_Size: 0.074666664 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &396431565 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &396431566 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 396431562} + m_CullTransparentMesh: 1 +--- !u!1 &444005364 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 444005365} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &444005365 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 444005364} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1809996612} + m_Father: {fileID: 396431563} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &448535452 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 448535453} + - component: {fileID: 448535455} + - component: {fileID: 448535454} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &448535453 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + 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: 150526395} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &448535454 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Off request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &448535455 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 448535452} + m_CullTransparentMesh: 1 +--- !u!1 &454989673 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 454989674} + - component: {fileID: 454989675} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &454989674 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 454989673} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 569754090} + - {fileID: 504131352} + m_Father: {fileID: 1041758959} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &454989675 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 454989673} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &504131351 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 504131352} + - component: {fileID: 504131354} + - component: {fileID: 504131353} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &504131352 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + 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: 454989674} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &504131353 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &504131354 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 504131351} + m_CullTransparentMesh: 1 +--- !u!1 &519420028 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 519420032} + - component: {fileID: 519420031} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!20 &519420031 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &519420032 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 519420028} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + 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 &539258973 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 539258974} + - component: {fileID: 539258975} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &539258974 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 539258973} + 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!114 &539258975 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 539258973} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08db36445d04347ef86917819b072b76, type: 3} + m_Name: + m_EditorClassIdentifier: + LogText: {fileID: 1321034296} + StatusText: {fileID: 562753628} + HostInput: {fileID: 798780213} + PortInput: {fileID: 115949712} + DataInput: {fileID: 1041758960} + LogScroll: {fileID: 185570085} + ConnectButton: {fileID: 1481597995} + Buttons: + - {fileID: 1309338645} + - {fileID: 1602564545} + - {fileID: 1950926904} + - {fileID: 876135629} + - {fileID: 1287462913} + - {fileID: 1052900978} + - {fileID: 1485904924} + - {fileID: 150526396} +--- !u!1 &562753626 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 562753627} + - component: {fileID: 562753629} + - component: {fileID: 562753628} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &562753627 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + 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: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &562753628 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnected + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &562753629 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 562753626} + m_CullTransparentMesh: 1 +--- !u!1 &569754089 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 569754090} + - component: {fileID: 569754093} + - component: {fileID: 569754092} + - component: {fileID: 569754091} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &569754090 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + 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: 454989674} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &569754091 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &569754092 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "Enter some data to test transfer \nor stay empty" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 2150773298 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &569754093 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 569754089} + m_CullTransparentMesh: 1 +--- !u!1 &579574895 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 579574896} + - component: {fileID: 579574897} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &579574896 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 579574895} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1309338644} + - {fileID: 1602564544} + - {fileID: 1950926903} + - {fileID: 876135628} + - {fileID: 1287462912} + - {fileID: 1485904923} + - {fileID: 150526395} + - {fileID: 1041758959} + m_Father: {fileID: 1819325582} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.000031207783} + m_SizeDelta: {x: 0, y: 3000} + m_Pivot: {x: 0, y: 1} +--- !u!114 &579574897 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 579574895} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 16 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &598734667 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 598734668} + - component: {fileID: 598734671} + - component: {fileID: 598734670} + - component: {fileID: 598734669} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &598734668 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + 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: 1341619234} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &598734669 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &598734670 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &598734671 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 598734667} + m_CullTransparentMesh: 1 +--- !u!1 &770291285 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 770291286} + - component: {fileID: 770291288} + - component: {fileID: 770291287} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &770291286 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + 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: 1602564544} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &770291287 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Command + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &770291288 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 770291285} + m_CullTransparentMesh: 1 +--- !u!1 &775008409 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 775008410} + - component: {fileID: 775008412} + - component: {fileID: 775008411} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &775008410 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + 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: 1481597994} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &775008411 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Connect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &775008412 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 775008409} + m_CullTransparentMesh: 1 +--- !u!1 &798780211 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 798780212} + - component: {fileID: 798780215} + - component: {fileID: 798780214} + - component: {fileID: 798780213} + m_Layer: 5 + m_Name: HostInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &798780212 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1341619234} + m_Father: {fileID: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &798780213 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 798780214} + m_TextViewport: {fileID: 1341619234} + m_TextComponent: {fileID: 2074396582} + m_Placeholder: {fileID: 598734670} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 192.168.0.51 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &798780214 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &798780215 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 798780211} + m_CullTransparentMesh: 1 +--- !u!1 &860852142 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 860852143} + - component: {fileID: 860852146} + - component: {fileID: 860852145} + - component: {fileID: 860852144} + m_Layer: 5 + m_Name: Scroll View + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &860852143 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1819325582} + - {fileID: 1042330545} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 1024} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &860852144 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 579574896} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 1 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 1819325582} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 1042330546} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &860852145 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &860852146 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 860852142} + m_CullTransparentMesh: 1 +--- !u!1 &876135627 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 876135628} + - component: {fileID: 876135631} + - component: {fileID: 876135630} + - component: {fileID: 876135629} + m_Layer: 5 + m_Name: SubscribeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &876135628 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 87791715} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &876135629 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 876135630} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Subscribe + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &876135630 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &876135631 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 876135627} + m_CullTransparentMesh: 1 +--- !u!1 &999822692 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 999822693} + - component: {fileID: 999822695} + - component: {fileID: 999822694} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &999822693 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + 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: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &999822694 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &999822695 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 999822692} + m_CullTransparentMesh: 1 +--- !u!1 &1041758958 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1041758959} + - component: {fileID: 1041758962} + - component: {fileID: 1041758961} + - component: {fileID: 1041758960} + m_Layer: 5 + m_Name: DataInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1041758959 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 454989674} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1041758960 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1041758961} + m_TextViewport: {fileID: 454989674} + m_TextComponent: {fileID: 504131353} + m_Placeholder: {fileID: 569754092} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 2 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1041758961 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1041758962 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1041758958} + m_CullTransparentMesh: 1 +--- !u!1 &1042330544 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1042330545} + - component: {fileID: 1042330548} + - component: {fileID: 1042330547} + - component: {fileID: 1042330546} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1042330545 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1251226125} + m_Father: {fileID: 860852143} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 48, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1042330546 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2137896824} + m_HandleRect: {fileID: 2137896823} + m_Direction: 2 + m_Value: 1 + m_Size: 0.34133333 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1042330547 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1042330548 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1042330544} + m_CullTransparentMesh: 1 +--- !u!1 &1045124896 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1045124897} + - component: {fileID: 1045124899} + - component: {fileID: 1045124898} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1045124897 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + 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: 1287462912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1045124898 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Unsubscribe + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1045124899 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1045124896} + m_CullTransparentMesh: 1 +--- !u!1 &1052900976 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1052900977} + - component: {fileID: 1052900980} + - component: {fileID: 1052900979} + - component: {fileID: 1052900978} + m_Layer: 5 + m_Name: DisconnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1052900977 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1166121420} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1052900978 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1052900979} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Disconnect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1052900979 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1052900980 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1052900976} + m_CullTransparentMesh: 1 +--- !u!1 &1074074093 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1074074094} + - component: {fileID: 1074074096} + - component: {fileID: 1074074095} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1074074094 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + 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: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1074074095 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1074074096 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1074074093} + m_CullTransparentMesh: 1 +--- !u!1 &1166121419 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1166121420} + - component: {fileID: 1166121422} + - component: {fileID: 1166121421} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1166121420 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + 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: 1052900977} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1166121421 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1166121422 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1166121419} + m_CullTransparentMesh: 1 +--- !u!1 &1189404153 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1189404154} + - component: {fileID: 1189404156} + - component: {fileID: 1189404155} + m_Layer: 5 + m_Name: PortText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1189404154 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + 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: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1189404155 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Port:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1189404156 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1189404153} + m_CullTransparentMesh: 1 +--- !u!1 &1251226124 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1251226125} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1251226125 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1251226124} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2137896823} + m_Father: {fileID: 1042330545} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1287462911 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1287462912} + - component: {fileID: 1287462915} + - component: {fileID: 1287462914} + - component: {fileID: 1287462913} + m_Layer: 5 + m_Name: UnsubscribeButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1287462912 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1045124897} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1287462913 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1287462914} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Unsubscribe + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1287462914 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1287462915 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1287462911} + m_CullTransparentMesh: 1 +--- !u!1 &1309338643 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1309338644} + - component: {fileID: 1309338647} + - component: {fileID: 1309338646} + - component: {fileID: 1309338645} + m_Layer: 5 + m_Name: RequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1309338644 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2083619548} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1309338645 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1309338646} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Request + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1309338646 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1309338647 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309338643} + m_CullTransparentMesh: 1 +--- !u!1 &1321034294 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1321034295} + - component: {fileID: 1321034297} + - component: {fileID: 1321034296} + m_Layer: 5 + m_Name: LogText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1321034295 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + 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: 1561090812} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1321034296 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1321034297 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321034294} + m_CullTransparentMesh: 1 +--- !u!1 &1341619233 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1341619234} + - component: {fileID: 1341619235} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1341619234 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1341619233} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 598734668} + - {fileID: 2074396581} + m_Father: {fileID: 798780212} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1341619235 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1341619233} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &1353611067 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1353611068} + - component: {fileID: 1353611070} + - component: {fileID: 1353611069} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1353611068 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + 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: 1950926903} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1353611069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Error + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1353611070 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1353611067} + m_CullTransparentMesh: 1 +--- !u!1 &1436611974 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1436611975} + - component: {fileID: 1436611977} + - component: {fileID: 1436611976} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1436611975 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + 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: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1436611976 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Shardy demo +--- !u!222 &1436611977 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1436611974} + m_CullTransparentMesh: 1 +--- !u!1 &1461011999 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1461012000} + - component: {fileID: 1461012003} + - component: {fileID: 1461012002} + - component: {fileID: 1461012001} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1461012000 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1561090812} + m_Father: {fileID: 185570084} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1461012001 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1461012002 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1461012003 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461011999} + m_CullTransparentMesh: 1 +--- !u!1 &1481597993 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1481597994} + - component: {fileID: 1481597997} + - component: {fileID: 1481597996} + - component: {fileID: 1481597995} + m_Layer: 5 + m_Name: ConnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1481597994 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 775008410} + m_Father: {fileID: 1497364878} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1481597995 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1481597996} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Connect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1481597996 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1481597997 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1481597993} + m_CullTransparentMesh: 1 +--- !u!1 &1485904922 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1485904923} + - component: {fileID: 1485904926} + - component: {fileID: 1485904925} + - component: {fileID: 1485904924} + m_Layer: 5 + m_Name: OnRequestButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1485904923 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1662488316} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1485904924 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1485904925} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: SubscribeRequest + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1485904925 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1485904926 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1485904922} + m_CullTransparentMesh: 1 +--- !u!1 &1497364877 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1497364878} + - component: {fileID: 1497364880} + - component: {fileID: 1497364879} + - component: {fileID: 1497364881} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1497364878 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1436611975} + - {fileID: 207479225} + - {fileID: 1481597994} + - {fileID: 1052900977} + - {fileID: 999822693} + - {fileID: 860852143} + - {fileID: 1074074094} + - {fileID: 562753627} + m_Father: {fileID: 1917894912} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 132.00002} + m_SizeDelta: {x: -64, y: -328.00003} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1497364879 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1497364880 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_CullTransparentMesh: 1 +--- !u!114 &1497364881 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1497364877} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &1561090811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1561090812} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1561090812 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1561090811} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1321034295} + m_Father: {fileID: 1461012000} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 1332.2343} + m_SizeDelta: {x: 0, y: 3000} + m_Pivot: {x: 0, y: 1} +--- !u!1 &1602564543 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1602564544} + - component: {fileID: 1602564547} + - component: {fileID: 1602564546} + - component: {fileID: 1602564545} + m_Layer: 5 + m_Name: CommandButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1602564544 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 770291286} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1602564545 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1602564546} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Command + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1602564546 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1602564547 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1602564543} + m_CullTransparentMesh: 1 +--- !u!1 &1662488315 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1662488316} + - component: {fileID: 1662488318} + - component: {fileID: 1662488317} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1662488316 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + 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: 1485904923} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1662488317 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: On request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1662488318 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1662488315} + m_CullTransparentMesh: 1 +--- !u!1 &1809996611 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1809996612} + - component: {fileID: 1809996614} + - component: {fileID: 1809996613} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1809996612 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + 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: 444005365} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1809996613 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1809996614 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1809996611} + m_CullTransparentMesh: 1 +--- !u!1 &1819325581 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1819325582} + - component: {fileID: 1819325585} + - component: {fileID: 1819325584} + - component: {fileID: 1819325583} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1819325582 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 579574896} + m_Father: {fileID: 860852143} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1819325583 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1819325584 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1819325585 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819325581} + m_CullTransparentMesh: 1 +--- !u!1 &1917894908 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1917894912} + - component: {fileID: 1917894911} + - component: {fileID: 1917894910} + - component: {fileID: 1917894909} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1917894909 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1917894910 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1080, y: 1920} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1917894911 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1917894912 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1917894908} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1497364878} + - {fileID: 185570084} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1926762627 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1926762628} + - component: {fileID: 1926762630} + - component: {fileID: 1926762629} + m_Layer: 5 + m_Name: HostText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1926762628 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + 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: 207479225} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1926762629 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Host:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1926762630 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1926762627} + m_CullTransparentMesh: 1 +--- !u!1 &1950926902 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1950926903} + - component: {fileID: 1950926906} + - component: {fileID: 1950926905} + - component: {fileID: 1950926904} + m_Layer: 5 + m_Name: ErrorButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1950926903 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1353611068} + m_Father: {fileID: 579574896} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1950926904 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1950926905} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 539258975} + m_TargetAssemblyTypeName: Demo, Assembly-CSharp + m_MethodName: Error + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1950926905 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1950926906 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1950926902} + m_CullTransparentMesh: 1 +--- !u!1 &2074396580 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2074396581} + - component: {fileID: 2074396583} + - component: {fileID: 2074396582} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2074396581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + 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: 1341619234} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2074396582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "192.168.0.51\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2074396583 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2074396580} + m_CullTransparentMesh: 1 +--- !u!1 &2083619547 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2083619548} + - component: {fileID: 2083619550} + - component: {fileID: 2083619549} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2083619548 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + 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: 1309338644} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2083619549 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Request + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2083619550 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2083619547} + m_CullTransparentMesh: 1 +--- !u!1 &2097740589 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2097740592} + - component: {fileID: 2097740591} + - component: {fileID: 2097740590} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2097740590 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "3000\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2097740591 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + m_CullTransparentMesh: 1 +--- !u!224 &2097740592 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2097740589} + 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: 322493275} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &2098744276 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2098744280} + - component: {fileID: 2098744279} + - component: {fileID: 2098744277} + - component: {fileID: 2098744278} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2098744277 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!114 &2098744278 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!222 &2098744279 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + m_CullTransparentMesh: 1 +--- !u!224 &2098744280 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2098744276} + 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: 322493275} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &2137896822 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2137896823} + - component: {fileID: 2137896825} + - component: {fileID: 2137896824} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2137896823 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + 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: 1251226125} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2137896824 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2137896825 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2137896822} + m_CullTransparentMesh: 1 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 519420032} + - {fileID: 1917894912} + - {fileID: 86744318} + - {fileID: 539258974} diff --git a/Samples~/Demo/Scenes/Demo.unity.meta b/Samples~/Demo/Scenes/Demo.unity.meta new file mode 100644 index 0000000..9d4e2bb --- /dev/null +++ b/Samples~/Demo/Scenes/Demo.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 04958b545c3e04b579450370a955cefe +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts.meta b/Samples~/Demo/Scripts.meta new file mode 100644 index 0000000..f8aa446 --- /dev/null +++ b/Samples~/Demo/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 44d6ca945a6bd42b8843c8dc70d17554 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/Demo.cs b/Samples~/Demo/Scripts/Demo.cs new file mode 100644 index 0000000..8ce6283 --- /dev/null +++ b/Samples~/Demo/Scripts/Demo.cs @@ -0,0 +1,263 @@ +using UnityEngine; +using Shardy; +using System.Text; +using TMPro; +using UnityEngine.UI; + +public class Demo : MonoBehaviour { + + /// + /// Link to log text + /// + [SerializeField] + TextMeshProUGUI LogText = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Input field for host + /// + [SerializeField] + TMP_InputField HostInput = null; + + /// + /// Input field for port + /// + [SerializeField] + TMP_InputField PortInput = null; + + /// + /// Input field for data + /// + [SerializeField] + TMP_InputField DataInput = null; + + /// + /// Scroll for logs + /// + [SerializeField] + ScrollRect LogScroll = null; + + /// + /// Link to connect button + /// + [SerializeField] + Button ConnectButton = null; + + /// + /// Array with buttons + /// + [SerializeField] + Button[] Buttons = null; + + /// + /// Client instance + /// + Client _client = null; + + /// + /// Cached data + /// + byte[] _data = null; + + /// + /// Init + /// + /// This demo uses TCP transport for connecting to test service + /// If you want to test client on your own backend with Websockets, change it in ClientOptions + /// + void Awake() { + LogScroll.verticalNormalizedPosition = 1f; + SwitchControls(false); + _client = new Client(new MyHandshake(), new MyJSON(), new ClientOptions()); + _client.OnConnect += OnConnect; + _client.OnDisconnect += OnDisconnect; + _client.OnReady += OnReady; + } + + /// + /// Destroy client + /// + void OnDestroy() { + _client.Destroy(); + } + + /// + /// Callback on ready to work + /// + void OnReady() { + StatusText.text = "Ready"; + LogText.text += $"< ready\n"; + } + + /// + /// Callback on disconnect with reason + /// + void OnDisconnect(DisconnectReason reason) { + LogText.text += $"< disconnected\n"; + StatusText.text = $"Disconnected: {reason}"; + Scroll(); + SwitchControls(false); + } + + /// + /// Callback on connect with status + /// + void OnConnect(bool status) { + LogText.text += status ? $"< connected\n" : $"< failed\n"; + StatusText.text = status ? "Connected" : "Disconnected"; + SwitchControls(status); + if (status) { + _client.Handshake(); + } + } + + /// + /// On/off controls + /// + void SwitchControls(bool value) { + ConnectButton.interactable = !value; + foreach (var item in Buttons) { + item.interactable = value; + } + DataInput.interactable = value; + } + + /// + /// Connect to server + /// + public void Connect() { + var host = HostInput.text.Trim(); + var port = int.Parse(PortInput.text.Trim()); + LogText.text += $"> connect to: {host}:{port}\n"; + _client.Connect(host, port); + } + + /// + /// Disconnect + /// + public void Disconnect() { + LogText.text += $"> disconnect\n"; + _client.Disconnect(); + Scroll(); + } + + /// + /// Test request + /// + public void Request() { + PrepareData(); + var request = "status"; + LogText.text += $"> test request: {request}\n"; + _client.Request(request, _data, (response) => { + LogText.text += $"< request data: {Utils.DataToString(response.Data)}\n\n"; + Scroll(); + }); + Scroll(); + } + + /// + /// Test command + /// + public void Command() { + PrepareData(); + var command = "notify"; + LogText.text += $"> test command: {command}\n"; + _client.Command(command, _data); + Scroll(); + } + + /// + /// Test request with error response + /// + public void Error() { + PrepareData(); + var request = "fail"; + LogText.text += $"> test error: {request}\n"; + _client.Request(request, _data, (response) => { + LogText.text += $"< error data: {Utils.DataToString(response.Data)}\n\n"; + Scroll(); + }); + Scroll(); + } + + /// + /// Subscribe on command + /// + public void Subscribe() { + PrepareData(); + var command = "timer"; + LogText.text += $"> subscribe on command: {command}\n"; + _client.Command(command, Encoding.UTF8.GetBytes("yes")); + _client.On(command, OnCommand); + Scroll(); + } + + /// + /// Unsubscribe from command + /// + public void Unsubscribe() { + PrepareData(); + var command = "timer"; + LogText.text += $"> unsubscribe from command: {command}\n"; + _client.Command(command, Encoding.UTF8.GetBytes("no")); + _client.Off(command, OnCommand); + Scroll(); + } + + /// + /// Add callback for request from server + /// Need respond or will be timeout + /// + /// Send command to initiate this example + /// + public void SubscribeRequest() { + var request = "request"; + LogText.text += $"> subscribe on request: {request}\n"; + _client.OnRequest(request, (payload) => { + // make response on this request id + // + // if comment this, you will give timeout on your backend + _client.Response(payload, Encoding.UTF8.GetBytes("some_data_from_client")); + }); + _client.Command(request); + } + + /// + /// Unsubscribe from server request + /// + /// Send command to initiate example and check that callback above doesn't invoke + /// + public void UnsubscribeRequest() { + var request = "request"; + LogText.text += $"> unsubscribe from request: {request}\n"; + _client.OffRequest(request); + _client.Command(request); + } + + /// + /// Callback on subscribed command + /// + void OnCommand(PayloadData payload) { + LogText.text += $"< subscribe data: {Utils.DataToString(payload.Data)}\n\n"; + Scroll(); + } + + /// + /// Prepare data to transport + /// + void PrepareData() { + _data = !string.IsNullOrEmpty(DataInput.text) ? Encoding.UTF8.GetBytes(DataInput.text) : null; + } + + /// + /// Scroll to bottom with some step + /// + void Scroll() { + LogScroll.verticalNormalizedPosition -= 0.035f; + } +} diff --git a/Samples~/Demo/Scripts/Demo.cs.meta b/Samples~/Demo/Scripts/Demo.cs.meta new file mode 100644 index 0000000..3675751 --- /dev/null +++ b/Samples~/Demo/Scripts/Demo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08db36445d04347ef86917819b072b76 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/MyHandshake.cs b/Samples~/Demo/Scripts/MyHandshake.cs new file mode 100644 index 0000000..e1ec016 --- /dev/null +++ b/Samples~/Demo/Scripts/MyHandshake.cs @@ -0,0 +1,38 @@ +using System.Text; +using Shardy; + +/// +/// Handshake stub +/// +class MyHandshake : IValidator { + + /// + /// Data for acknowledgement + /// + public byte[] Acknowledgement(byte[] body) { + // + // generate as you wish here + // + return body; + } + + /// + /// Data for initial handshake + /// + public byte[] Handshake(byte[] body = null) { + // + // generate as you wish here + // + return Encoding.UTF8.GetBytes("handshake_data"); + } + + /// + /// Verify acknowledgement + /// + public ValidatorState VerifyAcknowledgement(byte[] body) { + // + // validate as you wish here + // + return ValidatorState.Success; + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/MyHandshake.cs.meta b/Samples~/Demo/Scripts/MyHandshake.cs.meta new file mode 100644 index 0000000..53a7b9d --- /dev/null +++ b/Samples~/Demo/Scripts/MyHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 153935054a6164c40924eb2d7a2d611f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/MyJSON.cs b/Samples~/Demo/Scripts/MyJSON.cs new file mode 100644 index 0000000..2cb85b0 --- /dev/null +++ b/Samples~/Demo/Scripts/MyJSON.cs @@ -0,0 +1,30 @@ +using System.Text; +using NiceJson; +using Shardy; + +/// +/// Simple example serializer via NiceJson +/// +class MyJSON : ISerializer { + + /// + /// Decode received data to PayloadData + /// + public PayloadData Decode(byte[] body) { + var data = (JsonObject)JsonNode.ParseJsonString(Encoding.UTF8.GetString(body)); + return new PayloadData((PayloadType)(int)data["type"], data["name"], data["id"], Encoding.UTF8.GetBytes(data["data"]), data["error"]); + } + + /// + /// Encode to byte array for transporting + /// + public byte[] Encode(PayloadData payload) { + var data = new JsonObject(); + data["type"] = (int)payload.Type; + data["name"] = payload.Name; + data["id"] = payload.Id; + data["data"] = (payload.Data != null) ? Encoding.UTF8.GetString(payload.Data) : string.Empty; + data["error"] = payload.Error; + return Encoding.UTF8.GetBytes(data.ToJsonString()); + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/MyJSON.cs.meta b/Samples~/Demo/Scripts/MyJSON.cs.meta new file mode 100644 index 0000000..44a65ae --- /dev/null +++ b/Samples~/Demo/Scripts/MyJSON.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d4584e4fdf6f4b98bccc655cb42aa00 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Demo/Scripts/NiceJson.cs b/Samples~/Demo/Scripts/NiceJson.cs new file mode 100644 index 0000000..f797331 --- /dev/null +++ b/Samples~/Demo/Scripts/NiceJson.cs @@ -0,0 +1,769 @@ +๏ปฟ/* + NiceJson 1.3.3 (2020-05-11) + + MIT License + =========== + + Copyright (C) 2015 รngel Quiroga Mendoza + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + Appreciation Contributions: + Rayco Sรกnchez Garcรญa +*/ + +using System; +using System.Collections.Generic; +using System.Collections; +using System.Globalization; +using System.Text; + +namespace NiceJson { + [Serializable] + public abstract class JsonNode { + protected const char PP_IDENT_CHAR = '\t'; //Modify this to spaces or whatever char you want to be the ident one + protected const int PP_IDENT_COUNT = 1; //Modify this to be the numbers of IDENT_CHAR x identation + protected const bool ESCAPE_SOLIDUS = false; //If you are going to to embed this json in html, you can turn this on ref: http://andowebsit.es/blog/noteslog.com/post/the-solidus-issue/ + + protected const char CHAR_CURLY_OPEN = '{'; + protected const char CHAR_CURLY_CLOSED = '}'; + protected const char CHAR_SQUARED_OPEN = '['; + protected const char CHAR_SQUARED_CLOSED = ']'; + + protected const char CHAR_COLON = ':'; + protected const char CHAR_COMMA = ','; + protected const char CHAR_QUOTE = '"'; + + protected const char CHAR_NULL_LITERAL = 'n'; + protected const char CHAR_TRUE_LITERAL = 't'; + protected const char CHAR_FALSE_LITERAL = 'f'; + + protected const char CHAR_SPACE = ' '; + + protected const char CHAR_BS = '\b'; + protected const char CHAR_FF = '\f'; + protected const char CHAR_RF = '\r'; + protected const char CHAR_NL = '\n'; + protected const char CHAR_HT = '\t'; + protected const char CHAR_ESCAPE = '\\'; + protected const char CHAR_SOLIDUS = '/'; + protected const char CHAR_ESCAPED_QUOTE = '\"'; + + protected const char CHAR_N = 'n'; + protected const char CHAR_R = 'r'; + protected const char CHAR_B = 'b'; + protected const char CHAR_T = 't'; + protected const char CHAR_F = 'f'; + protected const char CHAR_U = 'u'; + + protected const string STRING_ESCAPED_BS = "\\b"; + protected const string STRING_ESCAPED_FF = "\\f"; + protected const string STRING_ESCAPED_RF = "\\r"; + protected const string STRING_ESCAPED_NL = "\\n"; + protected const string STRING_ESCAPED_TAB = "\\t"; + protected const string STRING_ESCAPED_ESCAPE = "\\\\"; + protected const string STRING_ESCAPED_SOLIDUS = "\\/"; + protected const string STRING_ESCAPED_ESCAPED_QUOTE = "\\\""; + + protected const string STRING_SPACE = " "; + protected const string STRING_LITERAL_NULL = "null"; + protected const string STRING_LITERAL_TRUE = "true"; + protected const string STRING_LITERAL_FALSE = "false"; + + protected const string STRING_ESCAPED_UNICODE_INIT = "\\u00"; + + //Indexers and accesors + public JsonNode this[string key] { + get { + if (this is JsonObject) { + return ((JsonObject)this)[key]; + } else { + return null; + } + } + + set { + if (this is JsonObject) { + ((JsonObject)this)[key] = value; + } + } + } + + public JsonNode this[int index] { + get { + if (this is JsonArray) { + return ((JsonArray)this)[index]; + } else { + return null; + } + } + + set { + if (this is JsonArray) { + ((JsonArray)this)[index] = value; + } + } + } + + public bool ContainsKey(string key) { + if (this is JsonObject) { + return ((JsonObject)this).ContainsKey(key); + } else { + return false; + } + } + + //escaping logic + + //Escaping/Unescaping logic + protected static string EscapeString(string s) { + var result = new StringBuilder(); + + foreach (var c in s) { + switch (c) { + case CHAR_ESCAPE: { + result.Append(STRING_ESCAPED_ESCAPE); + } + break; + case CHAR_SOLIDUS: { +#pragma warning disable + if (ESCAPE_SOLIDUS) { + result.Append(STRING_ESCAPED_SOLIDUS); + } else { + result.Append(c); + } +#pragma warning restore + } + break; + case CHAR_ESCAPED_QUOTE: { + _ = result.Append(STRING_ESCAPED_ESCAPED_QUOTE); + } + break; + case CHAR_NL: { + _ = result.Append(STRING_ESCAPED_NL); + } + break; + case CHAR_RF: { + _ = result.Append(STRING_ESCAPED_RF); + } + break; + case CHAR_HT: { + _ = result.Append(STRING_ESCAPED_TAB); + } + break; + case CHAR_BS: { + _ = result.Append(STRING_ESCAPED_BS); + } + break; + case CHAR_FF: { + _ = result.Append(STRING_ESCAPED_FF); + } + break; + default: + if (c < CHAR_SPACE) { + _ = result.Append(STRING_ESCAPED_UNICODE_INIT + Convert.ToByte(c).ToString("x2").ToUpper()); + } else { + _ = result.Append(c); + } + break; + } + } + + return result.ToString(); + } + + protected static string UnescapeString(string s) { + var result = new StringBuilder(s.Length); + + for (var i = 0; i < s.Length; i++) { + if (s[i] == CHAR_ESCAPE) { + i++; + + switch (s[i]) { + case CHAR_ESCAPE: { + _ = result.Append(s[i]); + } + break; + case CHAR_SOLIDUS: { + _ = result.Append(s[i]); + } + break; + case CHAR_ESCAPED_QUOTE: { + _ = result.Append(s[i]); + } + break; + case CHAR_N: { + _ = result.Append(CHAR_NL); + } + break; + case CHAR_R: { + _ = result.Append(CHAR_RF); + } + break; + case CHAR_T: { + _ = result.Append(CHAR_HT); + } + break; + case CHAR_B: { + _ = result.Append(CHAR_BS); + } + break; + case CHAR_F: { + _ = result.Append(CHAR_FF); + } + break; + case CHAR_U: { + _ = result.Append((char)int.Parse(s.Substring(i + 1, 4), NumberStyles.AllowHexSpecifier)); + i = i + 4; + } + break; + default: { + _ = result.Append(s[i]); + } + break; + } + } else { + _ = result.Append(s[i]); + } + } + + return result.ToString(); + } + + //setter implicit casting + + public static implicit operator JsonNode(string value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(int value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(long value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(float value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(double value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(decimal value) { + return new JsonBasic(value); + } + + public static implicit operator JsonNode(bool value) { + return new JsonBasic(value); + } + + //getter implicit casting + + public static implicit operator string(JsonNode value) { + if (value != null) { + return value.ToString(); + } else { + return null; + } + } + + public static implicit operator int(JsonNode value) { + return (int)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(int)); + } + + public static implicit operator long(JsonNode value) { + return (long)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(long)); + } + + public static implicit operator float(JsonNode value) { + return (float)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(float)); + } + + public static implicit operator double(JsonNode value) { + return (double)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(double)); + } + + public static implicit operator decimal(JsonNode value) { + return (decimal)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(decimal)); + } + + public static implicit operator bool(JsonNode value) { + return (bool)Convert.ChangeType(((JsonBasic)value).ValueObject, typeof(bool)); + } + + //Parsing logic + public static JsonNode ParseJsonString(string jsonString) { + return ParseJsonPart(RemoveNonTokenChars(jsonString)); + } + + private static JsonNode ParseJsonPart(string jsonPart) { + JsonNode jsonPartValue = null; + + if (jsonPart.Length == 0) { + return jsonPartValue; + } + + switch (jsonPart[0]) { + case CHAR_CURLY_OPEN: { + var jsonObject = new JsonObject(); + var splittedParts = SplitJsonParts(jsonPart.Substring(1, jsonPart.Length - 2)); + _ = new string[2]; + foreach (var keyValuePart in splittedParts) { + var keyValueParts = SplitKeyValuePart(keyValuePart); + if (keyValueParts[0] != null) { + jsonObject[UnescapeString(keyValueParts[0])] = ParseJsonPart(keyValueParts[1]); + } + } + jsonPartValue = jsonObject; + } + break; + case CHAR_SQUARED_OPEN: { + var jsonArray = new JsonArray(); + var splittedParts = SplitJsonParts(jsonPart.Substring(1, jsonPart.Length - 2)); + + foreach (var part in splittedParts) { + if (part.Length > 0) { + jsonArray.Add(ParseJsonPart(part)); + } + } + jsonPartValue = jsonArray; + } + break; + case CHAR_QUOTE: { + jsonPartValue = new JsonBasic(UnescapeString(jsonPart.Substring(1, jsonPart.Length - 2))); + } + break; + case CHAR_FALSE_LITERAL://false + { + jsonPartValue = new JsonBasic(false); + } + break; + case CHAR_TRUE_LITERAL://true + { + jsonPartValue = new JsonBasic(true); + } + break; + case CHAR_NULL_LITERAL://null + { + jsonPartValue = null; + } + break; + default://it must be a number or it will fail + { + long longValue; + if (long.TryParse(jsonPart, NumberStyles.Any, CultureInfo.InvariantCulture, out longValue)) { + if (longValue > int.MaxValue || longValue < int.MinValue) { + jsonPartValue = new JsonBasic(longValue); + } else { + jsonPartValue = new JsonBasic((int)longValue); + } + } else { + decimal decimalValue; + if (decimal.TryParse(jsonPart, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalValue)) { + jsonPartValue = new JsonBasic(decimalValue); + } + } + } + break; + } + + return jsonPartValue; + } + + private static List SplitJsonParts(string json) { + var jsonParts = new List(); + var identLevel = 0; + var lastPartChar = 0; + var inString = false; + + for (var i = 0; i < json.Length; i++) { + switch (json[i]) { + case CHAR_COMMA: { + if (!inString && identLevel == 0) { + jsonParts.Add(json.Substring(lastPartChar, i - lastPartChar)); + lastPartChar = i + 1; + } + } + break; + case CHAR_QUOTE: { + if (i == 0 || (json[i - 1] != CHAR_ESCAPE)) { + inString = !inString; + } + } + break; + case CHAR_CURLY_OPEN: + case CHAR_SQUARED_OPEN: { + if (!inString) { + identLevel++; + } + } + break; + case CHAR_CURLY_CLOSED: + case CHAR_SQUARED_CLOSED: { + if (!inString) { + identLevel--; + } + } + break; + } + } + + jsonParts.Add(json.Substring(lastPartChar)); + + return jsonParts; + } + + private static string[] SplitKeyValuePart(string json) { + var parts = new string[2]; + var inString = false; + + var found = false; + var index = 0; + + while (index < json.Length && !found) { + if (json[index] == CHAR_QUOTE && (index == 0 || (json[index - 1] != CHAR_ESCAPE))) { + if (!inString) { + inString = true; + index++; + } else { + parts[0] = json.Substring(1, index - 1); + parts[1] = json.Substring(index + 2);//+2 because of the : + found = true; + } + } else { + index++; + } + } + + return parts; + } + + private static string RemoveNonTokenChars(string s) { + var len = s.Length; + var s2 = new char[len]; + var currentPos = 0; + var outString = true; + for (var i = 0; i < len; i++) { + var c = s[i]; + if (c == CHAR_QUOTE) { + if (i == 0 || (s[i - 1] != CHAR_ESCAPE)) { + outString = !outString; + } + } + + if (!outString || ( + (c != CHAR_SPACE) && + (c != CHAR_RF) && + (c != CHAR_NL) && + (c != CHAR_HT) && + (c != CHAR_BS) && + (c != CHAR_FF) + )) { + s2[currentPos++] = c; + } + } + return new String(s2, 0, currentPos); + } + + //Object logic + + public abstract string ToJsonString(); + + public string ToJsonPrettyPrintString() { + var jsonString = this.ToJsonString(); + + var identStep = string.Empty; + for (var i = 0; i < PP_IDENT_COUNT; i++) { + identStep += PP_IDENT_CHAR; + } + + var inString = false; + + var currentIdent = string.Empty; + for (var i = 0; i < jsonString.Length; i++) { + switch (jsonString[i]) { + case CHAR_COLON: { + if (!inString) { + jsonString = jsonString.Insert(i + 1, STRING_SPACE); + } + } + break; + case CHAR_QUOTE: { + if (i == 0 || (jsonString[i - 1] != CHAR_ESCAPE)) { + inString = !inString; + } + } + break; + case CHAR_COMMA: { + if (!inString) { + jsonString = jsonString.Insert(i + 1, CHAR_NL + currentIdent); + } + } + break; + case CHAR_CURLY_OPEN: + case CHAR_SQUARED_OPEN: { + if (!inString) { + currentIdent += identStep; + jsonString = jsonString.Insert(i + 1, CHAR_NL + currentIdent); + } + } + break; + case CHAR_CURLY_CLOSED: + case CHAR_SQUARED_CLOSED: { + if (!inString) { + currentIdent = currentIdent.Substring(0, currentIdent.Length - identStep.Length); + jsonString = jsonString.Insert(i, CHAR_NL + currentIdent); + i += currentIdent.Length + 1; + } + } + break; + } + } + + return jsonString; + } + } + + [Serializable] + public class JsonBasic : JsonNode { + public object ValueObject { + get { + return m_value; + } + } + + private object m_value; + + public JsonBasic(object value) { + m_value = value; + } + + public override string ToString() { + return m_value.ToString(); + } + + public override string ToJsonString() { + if (m_value == null) { + return STRING_LITERAL_NULL; + } else if (m_value is string) { + return CHAR_QUOTE + EscapeString(m_value.ToString()) + CHAR_QUOTE; + } else if (m_value is bool) { + if ((bool)m_value) { + return STRING_LITERAL_TRUE; + } else { + return STRING_LITERAL_FALSE; + } + } else //number + { + if (m_value is decimal) { + return ((decimal)m_value).ToString(CultureInfo.InvariantCulture); + } else { + return m_value.ToString(); + } + } + } + } + + [Serializable] + public class JsonObject : JsonNode, IEnumerable { + private Dictionary m_dictionary = new Dictionary(); + + public Dictionary.KeyCollection Keys { + get { + return m_dictionary.Keys; + } + } + + public Dictionary.ValueCollection Values { + get { + return m_dictionary.Values; + } + } + + public new JsonNode this[string key] { + get { + return m_dictionary[key]; + } + + set { + m_dictionary[key] = value; + } + } + + public void Add(string key, JsonNode value) { + m_dictionary.Add(key, value); + } + + public bool Remove(string key) { + return m_dictionary.Remove(key); + } + + public JsonNode GetValue(string key, JsonNode defaultValue = default(JsonNode)) { + JsonNode value; + return m_dictionary.TryGetValue(key, out value) ? value : defaultValue; + } + + public new bool ContainsKey(string key) { + return m_dictionary.ContainsKey(key); + } + + public bool ContainsValue(JsonNode value) { + return m_dictionary.ContainsValue(value); + } + + public void Clear() { + m_dictionary.Clear(); + } + + public int Count { + get { + return m_dictionary.Count; + } + } + + public IEnumerator GetEnumerator() { + foreach (var jsonKeyValue in m_dictionary) { + yield return jsonKeyValue; + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public override string ToJsonString() { + if (m_dictionary == null) { + return STRING_LITERAL_NULL; + } else { + var jsonString = new StringBuilder(); + _ = jsonString.Append(CHAR_CURLY_OPEN); + foreach (var key in m_dictionary.Keys) { + _ = jsonString.Append(CHAR_QUOTE); + _ = jsonString.Append(EscapeString(key)); + _ = jsonString.Append(CHAR_QUOTE); + _ = jsonString.Append(CHAR_COLON); + + if (m_dictionary[key] != null) { + _ = jsonString.Append(m_dictionary[key].ToJsonString()); + } else { + _ = jsonString.Append(STRING_LITERAL_NULL); + } + _ = jsonString.Append(CHAR_COMMA); + } + if (jsonString[jsonString.Length - 1] == CHAR_COMMA) { + _ = jsonString.Remove(jsonString.Length - 1, 1); + } + _ = jsonString.Append(CHAR_CURLY_CLOSED); + + return jsonString.ToString(); + } + } + } + + [Serializable] + public class JsonArray : JsonNode, IEnumerable { + private List m_list = new List(); + + public int Count { + get { + return m_list.Count; + } + } + + public new JsonNode this[int index] { + get { + return m_list[index]; + } + + set { + m_list[index] = value; + } + } + + public IEnumerator GetEnumerator() { + foreach (var value in m_list) { + yield return value; + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + //expose some methods of list extends with needs + + public void Add(JsonNode item) { + m_list.Add(item); + } + + public void AddRange(IEnumerable collection) { + m_list.AddRange(collection); + } + + public void Insert(int index, JsonNode item) { + m_list.Insert(index, item); + } + + public void InsertRange(int index, IEnumerable collection) { + m_list.InsertRange(index, collection); + } + + public void RemoveAt(int index) { + m_list.RemoveAt(index); + } + + public bool Remove(JsonNode item) { + return m_list.Remove(item); + } + + public void Clear() { + m_list.Clear(); + } + + //end exposed methods + + + public override string ToJsonString() { + if (m_list == null) { + return STRING_LITERAL_NULL; + } else { + var jsonString = new StringBuilder(); + _ = jsonString.Append(CHAR_SQUARED_OPEN); + foreach (var value in m_list) { + if (value != null) { + _ = jsonString.Append(value.ToJsonString()); + } else { + _ = jsonString.Append(STRING_LITERAL_NULL); + } + + _ = jsonString.Append(CHAR_COMMA); + } + if (jsonString[jsonString.Length - 1] == CHAR_COMMA) { + _ = jsonString.Remove(jsonString.Length - 1, 1); + } + _ = jsonString.Append(CHAR_SQUARED_CLOSED); + + return jsonString.ToString(); + } + } + } +} \ No newline at end of file diff --git a/Samples~/Demo/Scripts/NiceJson.cs.meta b/Samples~/Demo/Scripts/NiceJson.cs.meta new file mode 100644 index 0000000..973f72f --- /dev/null +++ b/Samples~/Demo/Scripts/NiceJson.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 582b2ee812a0e45af84cc1fdffd10a61 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe.meta b/Samples~/TicTacToe.meta new file mode 100644 index 0000000..91e55af --- /dev/null +++ b/Samples~/TicTacToe.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 12f27a11ec10041d583430efb13c736d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images.meta b/Samples~/TicTacToe/Images.meta new file mode 100644 index 0000000..a95ab5c --- /dev/null +++ b/Samples~/TicTacToe/Images.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a254545fc86ae4b68ba6ac3fb21cf951 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images/circle-icon.png b/Samples~/TicTacToe/Images/circle-icon.png new file mode 100644 index 0000000..b30185c Binary files /dev/null and b/Samples~/TicTacToe/Images/circle-icon.png differ diff --git a/Samples~/TicTacToe/Images/circle-icon.png.meta b/Samples~/TicTacToe/Images/circle-icon.png.meta new file mode 100644 index 0000000..72362a0 --- /dev/null +++ b/Samples~/TicTacToe/Images/circle-icon.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 39f8dc9a87dfb4a2c9020e4d96806394 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 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: iPhone + 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: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Images/cross-icon.png b/Samples~/TicTacToe/Images/cross-icon.png new file mode 100644 index 0000000..c0c1cc3 Binary files /dev/null and b/Samples~/TicTacToe/Images/cross-icon.png differ diff --git a/Samples~/TicTacToe/Images/cross-icon.png.meta b/Samples~/TicTacToe/Images/cross-icon.png.meta new file mode 100644 index 0000000..b956ba7 --- /dev/null +++ b/Samples~/TicTacToe/Images/cross-icon.png.meta @@ -0,0 +1,140 @@ +fileFormatVersion: 2 +guid: 2441ef3d25cc740b5b3783c7c86413eb +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 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: iPhone + 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: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes.meta b/Samples~/TicTacToe/Scenes.meta new file mode 100644 index 0000000..b18a4c7 --- /dev/null +++ b/Samples~/TicTacToe/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fdebd3cff83c043aeb5d0e4b0f4e72cd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes/Game.unity b/Samples~/TicTacToe/Scenes/Game.unity new file mode 100644 index 0000000..dd08529 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Game.unity @@ -0,0 +1,2589 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &97341221 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 97341222} + - component: {fileID: 97341223} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &97341222 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 97341221} + 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!114 &97341223 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 97341221} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8ad76e2a6f3bc4bb5a80c3869758dc7e, type: 3} + m_Name: + m_EditorClassIdentifier: + PlayField: {fileID: 2120814422} + CrossIcon: {fileID: 21300000, guid: 2441ef3d25cc740b5b3783c7c86413eb, type: 3} + CircleIcon: {fileID: 21300000, guid: 39f8dc9a87dfb4a2c9020e4d96806394, type: 3} + CrossColor: {r: 1, g: 0, b: 0, a: 1} + CircleColor: {r: 0, g: 1, b: 0, a: 1} + ScoreText: {fileID: 1386850861} + StatusText: {fileID: 1197697554} +--- !u!1 &125874181 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 125874182} + - component: {fileID: 125874185} + - component: {fileID: 125874184} + - component: {fileID: 125874183} + m_Layer: 5 + m_Name: ExitButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &125874182 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1759215197} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0} + m_AnchorMax: {x: 0.5, y: 0} + m_AnchoredPosition: {x: 0, y: 32} + m_SizeDelta: {x: 320, y: 96} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &125874183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 125874184} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 97341223} + m_TargetAssemblyTypeName: GameController, Assembly-CSharp + m_MethodName: Exit + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &125874184 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &125874185 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 125874181} + m_CullTransparentMesh: 1 +--- !u!1 &167076085 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 167076086} + - component: {fileID: 167076088} + - component: {fileID: 167076087} + - component: {fileID: 167076089} + m_Layer: 5 + m_Name: 12Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &167076086 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &167076087 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &167076088 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_CullTransparentMesh: 1 +--- !u!114 &167076089 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 167076085} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &207043278 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 207043282} + - component: {fileID: 207043281} + - component: {fileID: 207043280} + - component: {fileID: 207043279} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &207043279 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &207043280 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &207043281 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &207043282 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 207043278} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1386850860} + - {fileID: 1860323809} + - {fileID: 2120814422} + - {fileID: 1197697553} + - {fileID: 125874182} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &431767752 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 431767753} + - component: {fileID: 431767755} + - component: {fileID: 431767754} + - component: {fileID: 431767756} + m_Layer: 5 + m_Name: 01Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &431767753 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &431767754 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &431767755 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_CullTransparentMesh: 1 +--- !u!114 &431767756 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 431767752} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &479522083 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 479522084} + - component: {fileID: 479522086} + - component: {fileID: 479522085} + - component: {fileID: 479522087} + m_Layer: 5 + m_Name: 00Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &479522084 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &479522085 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &479522086 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_CullTransparentMesh: 1 +--- !u!114 &479522087 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 479522083} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &509870036 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 509870037} + - component: {fileID: 509870039} + - component: {fileID: 509870038} + - component: {fileID: 509870040} + m_Layer: 5 + m_Name: 21Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &509870037 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &509870038 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &509870039 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_CullTransparentMesh: 1 +--- !u!114 &509870040 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 509870036} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &623150005 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 623150006} + - component: {fileID: 623150008} + - component: {fileID: 623150007} + m_Layer: 5 + m_Name: 11Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &623150006 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &623150007 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &623150008 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 623150005} + m_CullTransparentMesh: 1 +--- !u!1 &674806828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 674806831} + - component: {fileID: 674806830} + - component: {fileID: 674806829} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &674806829 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 +--- !u!20 &674806830 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &674806831 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + 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 &980937551 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 980937552} + - component: {fileID: 980937554} + - component: {fileID: 980937553} + - component: {fileID: 980937555} + m_Layer: 5 + m_Name: 11Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &980937552 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &980937553 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &980937554 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_CullTransparentMesh: 1 +--- !u!114 &980937555 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 980937551} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &996884106 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 996884107} + - component: {fileID: 996884109} + - component: {fileID: 996884108} + - component: {fileID: 996884110} + m_Layer: 5 + m_Name: 10Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &996884107 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &996884108 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &996884109 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_CullTransparentMesh: 1 +--- !u!114 &996884110 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996884106} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &996961688 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 996961689} + - component: {fileID: 996961691} + - component: {fileID: 996961690} + - component: {fileID: 996961692} + m_Layer: 5 + m_Name: 02Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &996961689 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &996961690 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &996961691 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_CullTransparentMesh: 1 +--- !u!114 &996961692 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 996961688} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1128266014 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1128266015} + - component: {fileID: 1128266017} + - component: {fileID: 1128266016} + m_Layer: 5 + m_Name: 02Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1128266015 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1128266016 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1128266017 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1128266014} + m_CullTransparentMesh: 1 +--- !u!1 &1197697552 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1197697553} + - component: {fileID: 1197697555} + - component: {fileID: 1197697554} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1197697553 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + 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: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 192} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0} +--- !u!114 &1197697554 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Wait + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 64 + m_fontSizeBase: 64 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1197697555 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1197697552} + m_CullTransparentMesh: 1 +--- !u!1 &1361859503 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1361859504} + - component: {fileID: 1361859506} + - component: {fileID: 1361859505} + - component: {fileID: 1361859507} + m_Layer: 5 + m_Name: 22Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1361859504 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1361859505 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1361859506 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_CullTransparentMesh: 1 +--- !u!114 &1361859507 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1361859503} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1386850859 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1386850860} + - component: {fileID: 1386850862} + - component: {fileID: 1386850861} + m_Layer: 5 + m_Name: ScoreText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1386850860 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + 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: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -32} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1386850861 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 0:0 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 64 + m_fontSizeBase: 64 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1386850862 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1386850859} + m_CullTransparentMesh: 1 +--- !u!1 &1427813292 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1427813293} + - component: {fileID: 1427813295} + - component: {fileID: 1427813294} + - component: {fileID: 1427813296} + m_Layer: 5 + m_Name: 20Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1427813293 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + 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: 2120814422} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1427813294 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1427813295 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_CullTransparentMesh: 1 +--- !u!114 &1427813296 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1427813292} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59dcb2c69516748f0a455ea71d5c1c3d, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1495330464 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1495330465} + - component: {fileID: 1495330467} + - component: {fileID: 1495330466} + m_Layer: 5 + m_Name: 21Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1495330465 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1495330466 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1495330467 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1495330464} + m_CullTransparentMesh: 1 +--- !u!1 &1748551580 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1748551581} + - component: {fileID: 1748551583} + - component: {fileID: 1748551582} + m_Layer: 5 + m_Name: 12Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1748551581 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1748551582 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1748551583 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1748551580} + m_CullTransparentMesh: 1 +--- !u!1 &1759215196 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1759215197} + - component: {fileID: 1759215199} + - component: {fileID: 1759215198} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1759215197 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + 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: 125874182} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1759215198 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Exit + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 48 + m_fontSizeBase: 48 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1759215199 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1759215196} + m_CullTransparentMesh: 1 +--- !u!1 &1782207046 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1782207047} + - component: {fileID: 1782207049} + - component: {fileID: 1782207048} + m_Layer: 5 + m_Name: 20Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1782207047 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1782207048 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1782207049 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1782207046} + m_CullTransparentMesh: 1 +--- !u!1 &1814945262 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1814945263} + - component: {fileID: 1814945265} + - component: {fileID: 1814945264} + m_Layer: 5 + m_Name: 00Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1814945263 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1814945264 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1814945265 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1814945262} + m_CullTransparentMesh: 1 +--- !u!1 &1821649078 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1821649079} + - component: {fileID: 1821649081} + - component: {fileID: 1821649080} + m_Layer: 5 + m_Name: 22Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1821649079 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1821649080 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1821649081 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1821649078} + m_CullTransparentMesh: 1 +--- !u!1 &1838535362 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1838535363} + - component: {fileID: 1838535365} + - component: {fileID: 1838535364} + m_Layer: 5 + m_Name: 01Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1838535363 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1838535364 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1838535365 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1838535362} + m_CullTransparentMesh: 1 +--- !u!1 &1860323808 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1860323809} + - component: {fileID: 1860323810} + m_Layer: 5 + m_Name: Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1860323809 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1860323808} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1814945263} + - {fileID: 1838535363} + - {fileID: 1128266015} + - {fileID: 2066689120} + - {fileID: 623150006} + - {fileID: 1748551581} + - {fileID: 1782207047} + - {fileID: 1495330465} + - {fileID: 1821649079} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 800, y: 800} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1860323810 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1860323808} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 256, y: 256} + m_Spacing: {x: 16, y: 16} + m_Constraint: 1 + m_ConstraintCount: 3 +--- !u!1 &2066689119 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2066689120} + - component: {fileID: 2066689122} + - component: {fileID: 2066689121} + m_Layer: 5 + m_Name: 10Image + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2066689120 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + 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: 1860323809} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2066689121 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2066689122 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2066689119} + m_CullTransparentMesh: 1 +--- !u!1 &2101528484 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2101528487} + - component: {fileID: 2101528486} + - component: {fileID: 2101528485} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2101528485 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &2101528486 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &2101528487 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2101528484} + 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 &2120814421 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2120814422} + - component: {fileID: 2120814423} + m_Layer: 5 + m_Name: PlayField + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2120814422 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2120814421} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 479522084} + - {fileID: 431767753} + - {fileID: 996961689} + - {fileID: 996884107} + - {fileID: 980937552} + - {fileID: 167076086} + - {fileID: 1427813293} + - {fileID: 509870037} + - {fileID: 1361859504} + m_Father: {fileID: 207043282} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 800, y: 800} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2120814423 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2120814421} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 4 + m_StartCorner: 0 + m_StartAxis: 0 + m_CellSize: {x: 256, y: 256} + m_Spacing: {x: 16, y: 16} + m_Constraint: 1 + m_ConstraintCount: 3 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 674806831} + - {fileID: 207043282} + - {fileID: 2101528487} + - {fileID: 97341222} diff --git a/Samples~/TicTacToe/Scenes/Game.unity.meta b/Samples~/TicTacToe/Scenes/Game.unity.meta new file mode 100644 index 0000000..4bfc8c6 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Game.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 992f68042d5314a3fbbd641573b310e3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scenes/Menu.unity b/Samples~/TicTacToe/Scenes/Menu.unity new file mode 100644 index 0000000..7bf61b1 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Menu.unity @@ -0,0 +1,3722 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &87452109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 87452110} + - component: {fileID: 87452112} + - component: {fileID: 87452111} + m_Layer: 5 + m_Name: HostText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &87452110 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + 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: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &87452111 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Host:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &87452112 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 87452109} + m_CullTransparentMesh: 1 +--- !u!1 &138338658 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 138338659} + - component: {fileID: 138338661} + - component: {fileID: 138338660} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &138338659 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + 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: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: 0} + m_SizeDelta: {x: 952, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &138338660 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Wait for opponent... +--- !u!222 &138338661 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138338658} + m_CullTransparentMesh: 1 +--- !u!1 &149192842 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 149192843} + - component: {fileID: 149192846} + - component: {fileID: 149192845} + - component: {fileID: 149192844} + m_Layer: 5 + m_Name: SearchPanel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &149192843 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 138338659} + - {fileID: 1460273542} + - {fileID: 1461035827} + - {fileID: 1655159176} + m_Father: {fileID: 1634755900} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -64, y: -64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &149192844 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &149192845 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.5896226, g: 0.7976472, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &149192846 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149192842} + m_CullTransparentMesh: 1 +--- !u!1 &240390030 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 240390031} + - component: {fileID: 240390033} + - component: {fileID: 240390032} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &240390031 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + 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: 2122295233} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &240390032 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "3000\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &240390033 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 240390030} + m_CullTransparentMesh: 1 +--- !u!1 &372681422 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 372681423} + - component: {fileID: 372681426} + - component: {fileID: 372681425} + - component: {fileID: 372681424} + m_Layer: 5 + m_Name: ConnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &372681423 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 982673899} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &372681424 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 372681425} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Connect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &372681425 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &372681426 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 372681422} + m_CullTransparentMesh: 1 +--- !u!1 &447614748 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 447614749} + - component: {fileID: 447614752} + - component: {fileID: 447614751} + - component: {fileID: 447614750} + m_Layer: 5 + m_Name: PlayButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &447614749 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 741069091} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 256} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &447614750 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 0 + m_TargetGraphic: {fileID: 447614751} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Play + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &447614751 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &447614752 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 447614748} + m_CullTransparentMesh: 1 +--- !u!1 &459724183 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 459724184} + - component: {fileID: 459724187} + - component: {fileID: 459724186} + - component: {fileID: 459724185} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &459724184 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 869956712} + - {fileID: 1976736168} + - {fileID: 372681423} + - {fileID: 919464296} + - {fileID: 1156390075} + - {fileID: 447614749} + - {fileID: 1016756350} + - {fileID: 1879525922} + m_Father: {fileID: 1634755900} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -64, y: -64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &459724185 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 32 + m_Right: 32 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 1 + m_Spacing: 16 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &459724186 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &459724187 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 459724183} + m_CullTransparentMesh: 1 +--- !u!1 &498426051 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 498426052} + - component: {fileID: 498426053} + m_Layer: 0 + m_Name: Scripts + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &498426052 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 498426051} + 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!114 &498426053 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 498426051} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8189a9473e61645ebb6c7b49be2df4dc, type: 3} + m_Name: + m_EditorClassIdentifier: + HostInput: {fileID: 1640573858} + PortInput: {fileID: 1564217885} + StatusText: {fileID: 1879525923} + SearchPanel: {fileID: 149192842} + PlayButton: {fileID: 447614750} +--- !u!1 &674806828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 674806831} + - component: {fileID: 674806830} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!20 &674806830 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &674806831 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 674806828} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + 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 &741069090 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 741069091} + - component: {fileID: 741069093} + - component: {fileID: 741069092} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &741069091 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + 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: 447614749} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &741069092 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Play + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 96 + m_fontSizeBase: 96 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &741069093 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 741069090} + m_CullTransparentMesh: 1 +--- !u!1 &869956711 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 869956712} + - component: {fileID: 869956714} + - component: {fileID: 869956713} + m_Layer: 5 + m_Name: TitleText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &869956712 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + 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: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &869956713 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 64 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 6 + m_MaxSize: 64 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Tic-Tac-Toe +--- !u!222 &869956714 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 869956711} + m_CullTransparentMesh: 1 +--- !u!1 &919464295 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 919464296} + - component: {fileID: 919464299} + - component: {fileID: 919464298} + - component: {fileID: 919464297} + m_Layer: 5 + m_Name: DisconnectButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &919464296 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 945034700} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 144} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &919464297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 919464298} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Disconnect + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &919464298 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &919464299 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 919464295} + m_CullTransparentMesh: 1 +--- !u!1 &945034699 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 945034700} + - component: {fileID: 945034702} + - component: {fileID: 945034701} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &945034700 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + 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: 919464296} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &945034701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &945034702 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945034699} + m_CullTransparentMesh: 1 +--- !u!1 &982673898 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 982673899} + - component: {fileID: 982673901} + - component: {fileID: 982673900} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &982673899 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + 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: 372681423} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &982673900 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Connect + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &982673901 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 982673898} + m_CullTransparentMesh: 1 +--- !u!1 &1016756349 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1016756350} + - component: {fileID: 1016756352} + - component: {fileID: 1016756351} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1016756350 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + 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: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1016756351 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1016756352 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1016756349} + m_CullTransparentMesh: 1 +--- !u!1 &1051212462 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1051212465} + - component: {fileID: 1051212464} + - component: {fileID: 1051212463} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1051212463 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_SendPointerHoverToParent: 1 + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &1051212464 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &1051212465 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1051212462} + 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 &1075891663 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1075891664} + - component: {fileID: 1075891665} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1075891664 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1075891663} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2100409529} + - {fileID: 2129878274} + m_Father: {fileID: 1640573857} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1075891665 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1075891663} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &1078465109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1078465110} + - component: {fileID: 1078465112} + - component: {fileID: 1078465111} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1078465110 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + 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: 1461035827} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1078465111 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Cancel + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 96 + m_fontSizeBase: 96 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1078465112 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1078465109} + m_CullTransparentMesh: 1 +--- !u!1 &1156390074 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1156390075} + - component: {fileID: 1156390077} + - component: {fileID: 1156390076} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1156390075 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + 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: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1156390076 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1156390077 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1156390074} + m_CullTransparentMesh: 1 +--- !u!1 &1309975583 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1309975585} + - component: {fileID: 1309975586} + m_Layer: 0 + m_Name: Connector + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1309975585 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309975583} + 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!114 &1309975586 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1309975583} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 08c073176e63443479820504ed5e74f9, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!1 &1460273541 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1460273542} + - component: {fileID: 1460273544} + - component: {fileID: 1460273543} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1460273542 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + 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: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -160} + m_SizeDelta: {x: 952, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1460273543 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1460273544 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460273541} + m_CullTransparentMesh: 1 +--- !u!1 &1460361714 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1460361715} + - component: {fileID: 1460361718} + - component: {fileID: 1460361717} + - component: {fileID: 1460361716} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1460361715 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + 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: 2122295233} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1460361716 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &1460361717 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1460361718 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1460361714} + m_CullTransparentMesh: 1 +--- !u!1 &1461035826 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1461035827} + - component: {fileID: 1461035830} + - component: {fileID: 1461035829} + - component: {fileID: 1461035828} + m_Layer: 5 + m_Name: CancelButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1461035827 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1078465110} + m_Father: {fileID: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -320} + m_SizeDelta: {x: 952, y: 256} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1461035828 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1461035829} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 498426053} + m_TargetAssemblyTypeName: MenuController, Assembly-CSharp + m_MethodName: Stop + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1461035829 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1461035830 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1461035826} + m_CullTransparentMesh: 1 +--- !u!1 &1564217883 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1564217884} + - component: {fileID: 1564217887} + - component: {fileID: 1564217886} + - component: {fileID: 1564217885} + m_Layer: 5 + m_Name: PortInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1564217884 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 2122295233} + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 144, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1564217885 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1564217886} + m_TextViewport: {fileID: 2122295233} + m_TextComponent: {fileID: 240390032} + m_Placeholder: {fileID: 1460361717} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 2 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 4 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 2 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 3000 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1564217886 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1564217887 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1564217883} + m_CullTransparentMesh: 1 +--- !u!1 &1634755896 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1634755900} + - component: {fileID: 1634755899} + - component: {fileID: 1634755898} + - component: {fileID: 1634755897} + m_Layer: 5 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1634755897 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1634755898 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 0.5 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1634755899 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_VertexColorAlwaysGammaSpace: 0 + m_AdditionalShaderChannelsFlag: 25 + m_UpdateRectTransformForStandalone: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1634755900 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1634755896} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 459724184} + - {fileID: 149192843} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!1 &1640573856 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1640573857} + - component: {fileID: 1640573860} + - component: {fileID: 1640573859} + - component: {fileID: 1640573858} + m_Layer: 5 + m_Name: HostInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1640573857 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1075891664} + m_Father: {fileID: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 320, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1640573858 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2da0c512f12947e489f739169773d7ca, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1640573859} + m_TextViewport: {fileID: 1075891664} + m_TextComponent: {fileID: 2129878275} + m_Placeholder: {fileID: 2100409531} + m_VerticalScrollbar: {fileID: 0} + m_VerticalScrollbarEventHandler: {fileID: 0} + m_LayoutGroup: {fileID: 0} + m_ScrollSensitivity: 1 + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_HideSoftKeyboard: 0 + m_CharacterValidation: 0 + m_RegexValue: + m_GlobalPointSize: 44 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnSubmit: + m_PersistentCalls: + m_Calls: [] + m_OnSelect: + m_PersistentCalls: + m_Calls: [] + m_OnDeselect: + m_PersistentCalls: + m_Calls: [] + m_OnTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnEndTextSelection: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_OnTouchScreenKeyboardStatusChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: 192.168.0.51 + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_RichText: 1 + m_GlobalFontAsset: {fileID: 0} + m_OnFocusSelectAll: 1 + m_ResetOnDeActivation: 1 + m_RestoreOriginalTextOnEscape: 1 + m_isRichTextEditingAllowed: 0 + m_LineLimit: 0 + m_InputValidator: {fileID: 0} +--- !u!114 &1640573859 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1640573860 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1640573856} + m_CullTransparentMesh: 1 +--- !u!1 &1655159175 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1655159176} + - component: {fileID: 1655159178} + - component: {fileID: 1655159177} + m_Layer: 5 + m_Name: 'Panel ' + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1655159176 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + 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: 149192843} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 508, y: -480} + m_SizeDelta: {x: 952, y: 32} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1655159177 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1655159178 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1655159175} + m_CullTransparentMesh: 1 +--- !u!1 &1879525921 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1879525922} + - component: {fileID: 1879525924} + - component: {fileID: 1879525923} + m_Layer: 5 + m_Name: StatusText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1879525922 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + 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: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 96} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1879525923 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Disconnected + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1879525924 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1879525921} + m_CullTransparentMesh: 1 +--- !u!1 &1941589581 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1941589582} + - component: {fileID: 1941589584} + - component: {fileID: 1941589583} + m_Layer: 5 + m_Name: PortText + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1941589582 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + 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: 1976736168} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 128, y: 64} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1941589583 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 'Port:' + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &1941589584 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1941589581} + m_CullTransparentMesh: 1 +--- !u!1 &1976736167 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1976736168} + - component: {fileID: 1976736169} + m_Layer: 5 + m_Name: HostPort + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1976736168 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1976736167} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 87452110} + - {fileID: 1640573857} + - {fileID: 1941589582} + - {fileID: 1564217884} + m_Father: {fileID: 459724184} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 128} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &1976736169 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1976736167} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 30649d3a9faa99c48a7b1166b86bf2a0, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 3 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!1 &2100409528 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2100409529} + - component: {fileID: 2100409532} + - component: {fileID: 2100409531} + - component: {fileID: 2100409530} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2100409529 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + 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: 1075891664} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2100409530 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreLayout: 1 + m_MinWidth: -1 + m_MinHeight: -1 + m_PreferredWidth: -1 + m_PreferredHeight: -1 + m_FlexibleWidth: -1 + m_FlexibleHeight: -1 + m_LayoutPriority: 1 +--- !u!114 &2100409531 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Enter text... + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: 0 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 2 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2100409532 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2100409528} + m_CullTransparentMesh: 1 +--- !u!1 &2122295232 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2122295233} + - component: {fileID: 2122295234} + m_Layer: 5 + m_Name: Text Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2122295233 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2122295232} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 1460361715} + - {fileID: 240390031} + m_Father: {fileID: 1564217884} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2122295234 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2122295232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3312d7739989d2b4e91e6319e9a96d76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: {x: -8, y: -5, z: -8, w: -5} + m_Softness: {x: 0, y: 0} +--- !u!1 &2129878273 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2129878274} + - component: {fileID: 2129878276} + - component: {fileID: 2129878275} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2129878274 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + 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: 1075891664} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2129878275 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: "192.168.0.51\u200B" + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 44 + m_fontSizeBase: 44 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 0 + m_fontSizeMax: 0 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 0 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_enableExtraPadding: 1 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &2129878276 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2129878273} + m_CullTransparentMesh: 1 +--- !u!1660057539 &9223372036854775807 +SceneRoots: + m_ObjectHideFlags: 0 + m_Roots: + - {fileID: 674806831} + - {fileID: 1634755900} + - {fileID: 1051212465} + - {fileID: 1309975585} + - {fileID: 498426052} diff --git a/Samples~/TicTacToe/Scenes/Menu.unity.meta b/Samples~/TicTacToe/Scenes/Menu.unity.meta new file mode 100644 index 0000000..9560e20 --- /dev/null +++ b/Samples~/TicTacToe/Scenes/Menu.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0a23420e63fbd4762b6af6e6609d8179 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts.meta b/Samples~/TicTacToe/Scripts.meta new file mode 100644 index 0000000..d34bbe4 --- /dev/null +++ b/Samples~/TicTacToe/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c64238bd0f8524ce7b799ebc28e587f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/Connector.cs b/Samples~/TicTacToe/Scripts/Connector.cs new file mode 100644 index 0000000..f728e27 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Connector.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using Shardy; + +[DefaultExecutionOrder(-1)] +public class Connector : MonoBehaviour { + + /// + /// Client instance + /// + static Client _client = null; + + /// + /// Init + /// + /// This demo uses TCP transport for connecting to test game server + /// + void Awake() { + if (_client == null) { + _client = new Client(new TestHandshake(), new TestSerializer(), new ClientOptions()); + DontDestroyOnLoad(gameObject); + } + } + + /// + /// Get client instance for external use + /// + public static Client Use() { + return _client; + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/Connector.cs.meta b/Samples~/TicTacToe/Scripts/Connector.cs.meta new file mode 100644 index 0000000..695c61c --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Connector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08c073176e63443479820504ed5e74f9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/Consts.cs b/Samples~/TicTacToe/Scripts/Consts.cs new file mode 100644 index 0000000..22d4cfc --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Consts.cs @@ -0,0 +1,42 @@ +public class Consts { + + /// + /// Menu scene name + /// + public const string MENU_SCENE = "Menu"; + + /// + /// Game scene name + /// + public const string GAME_SCENE = "Game"; + + /// + /// Start search command + /// + public const string SEARCH_START = "start"; + + /// + /// Stop search command + /// + public const string SEARCH_STOP = "stop"; + + /// + /// Exit game command + /// + public const string EXIT_GAME = "exit"; + + /// + /// Turn command + /// + public const string TURN = "turn"; + + /// + /// Game round command + /// + public const string ROUND = "round"; + + /// + /// Game created command, ready for play + /// + public const string PLAY = "play"; +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/Consts.cs.meta b/Samples~/TicTacToe/Scripts/Consts.cs.meta new file mode 100644 index 0000000..aff0569 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/Consts.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e6bd755974cd14a519727dd7cd6e87d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/GameController.cs b/Samples~/TicTacToe/Scripts/GameController.cs new file mode 100644 index 0000000..d5ea5ba --- /dev/null +++ b/Samples~/TicTacToe/Scripts/GameController.cs @@ -0,0 +1,246 @@ +using System; +using System.Text; +using NiceJson; +using TMPro; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +/// +/// Type of player' game item +/// +public enum ItemType { + Cross, + Circle, + None +} + +/// +/// Game info structure +/// +public struct GameInfo { + + /// + /// Current game id + /// + public string GameId; + + /// + /// Current player id + /// + public int PlayerId; + + /// + /// Current turn player id + /// + public int TurnPlayerId; + + /// + /// Score data + /// + public int[] Score; +} + +public class GameController : MonoBehaviour { + + /// + /// Sprites count in row + /// + const int ROW_MAX_COUNT = 3; + + /// + /// Container with game sprites + /// + [SerializeField] + Transform PlayField = null; + + /// + /// Link to cross sprite + /// + [SerializeField] + Sprite CrossIcon = null; + + /// + /// Link to circle sprite + /// + [SerializeField] + Sprite CircleIcon = null; + + /// + /// Link to cross color picker + /// + [SerializeField] + Color CrossColor = Color.red; + + /// + /// Link to circle color picker + /// + [SerializeField] + Color CircleColor = Color.green; + + /// + /// Link to score text + /// + [SerializeField] + TextMeshProUGUI ScoreText = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Sprites in grid + /// + readonly Image[,] _field = new Image[ROW_MAX_COUNT, ROW_MAX_COUNT]; + + /// + /// Current game info + /// + GameInfo _info = new GameInfo(); + + /// + /// Init + /// + void Awake() { + var images = PlayField.GetComponentsInChildren(); + var i = 0; + for (var x = 0; x < ROW_MAX_COUNT; x++) { + for (var y = 0; y < ROW_MAX_COUNT; y++) { + _field[x, y] = images[i]; + var button = images[i].GetComponent(); + button.Init(this, x, y); + i++; + } + } + Clear(); + SetStatus("Wait, please..."); + Connector.Use().On(Consts.ROUND, (response) => { + var json = Encoding.UTF8.GetString(response.Data); + try { + var data = (JsonObject)JsonNode.ParseJsonString(json); + _info.GameId = data["g"]; + _info.PlayerId = data["p"]; + _info.TurnPlayerId = data["t"]; + _info.Score = new int[] { data["s"][0], data["s"][1] }; + } catch (Exception e) { + Debug.LogException(e); + } + Clear(); + SetScore(); + var status = _info.PlayerId != _info.TurnPlayerId ? "Wait for the opponent's step" : "Make your step"; + SetStatus(status); + }); + Connector.Use().On(Consts.TURN, (response) => { + var json = Encoding.UTF8.GetString(response.Data); + try { + var data = (JsonObject)JsonNode.ParseJsonString(json); + SetItem(data["x"], data["y"], (ItemType)(int)data["t"]); + _info.TurnPlayerId = data["t"] == 0 ? 1 : 0; + } catch (Exception e) { + Debug.LogException(e); + } + var status = _info.PlayerId != _info.TurnPlayerId ? "Wait for the opponent's step" : "Make your step"; + SetStatus(status); + }); + Connector.Use().On(Consts.EXIT_GAME, (response) => { + SetStatus("Opponent has left the game"); + }); + } + + /// + /// Unsubscrive + /// + void OnDisable() { + Connector.Use().Off(Consts.ROUND); + Connector.Use().Off(Consts.TURN); + Connector.Use().Off(Consts.EXIT_GAME); + } + + /// + /// Clear play field + /// + void Clear() { + for (var x = 0; x < ROW_MAX_COUNT; x++) { + for (var y = 0; y < ROW_MAX_COUNT; y++) { + SetItem(x, y, ItemType.None); + } + } + } + + /// + /// Set score + /// + void SetScore() { + ScoreText.text = $"{_info.Score[0]}:{_info.Score[1]}"; + } + + /// + /// Set status message + /// + /// Message text + void SetStatus(string message) { + StatusText.text = message; + } + + /// + /// Exit from game + /// + public void Exit() { + var json = new JsonObject(); + json["g"] = _info.GameId; + json["p"] = _info.PlayerId; + var data = Encoding.UTF8.GetBytes(json.ToJsonString()); + Connector.Use().Request(Consts.EXIT_GAME, data, (data) => { + SceneManager.LoadScene(Consts.MENU_SCENE); + }); + } + + /// + /// Set play item + /// + /// X coordinate + /// Y coordinate + /// Type of item + public void SetItem(int x, int y, ItemType type) { + switch (type) { + case ItemType.Cross: + _field[x, y].color = CrossColor; + _field[x, y].sprite = CrossIcon; + break; + case ItemType.Circle: + _field[x, y].color = CircleColor; + _field[x, y].sprite = CircleIcon; + break; + case ItemType.None: + _field[x, y].color = Color.white; + _field[x, y].sprite = null; + break; + default: + break; + } + } + + /// + /// Make game step + /// + /// X coordinate + /// Y coordinate + public void MakeTurn(int x, int y) { + if (_info.PlayerId != _info.TurnPlayerId) { + return; + } + var json = new JsonObject(); + json["g"] = _info.GameId; + json["p"] = _info.PlayerId; + json["x"] = x; + json["y"] = y; + var data = Encoding.UTF8.GetBytes(json.ToJsonString()); + Connector.Use().Request(Consts.TURN, data, (response) => { + if (!string.IsNullOrEmpty(response.Error)) { + SetStatus(response.Error); + } + }); + } +} diff --git a/Samples~/TicTacToe/Scripts/GameController.cs.meta b/Samples~/TicTacToe/Scripts/GameController.cs.meta new file mode 100644 index 0000000..1a84652 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/GameController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8ad76e2a6f3bc4bb5a80c3869758dc7e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/ItemButton.cs b/Samples~/TicTacToe/Scripts/ItemButton.cs new file mode 100644 index 0000000..3e79db7 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/ItemButton.cs @@ -0,0 +1,39 @@ +using UnityEngine; +using UnityEngine.EventSystems; + +public class ItemButton : MonoBehaviour, IPointerClickHandler { + + /// + /// Cache controller + /// + GameController _controller = null; + + /// + /// Cached X coordinate + /// + int _x = -1; + + /// + /// Cached Y coordinate + /// + int _y = -1; + + /// + /// Init item button + /// + /// Parent controller + /// X coord + /// Y coord + public void Init(GameController controller, int x, int y) { + _controller = controller; + _x = x; + _y = y; + } + + /// + /// Action on click + /// + public void OnPointerClick(PointerEventData data) { + _controller.MakeTurn(_x, _y); + } +} diff --git a/Samples~/TicTacToe/Scripts/ItemButton.cs.meta b/Samples~/TicTacToe/Scripts/ItemButton.cs.meta new file mode 100644 index 0000000..7549a98 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/ItemButton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 59dcb2c69516748f0a455ea71d5c1c3d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/MenuController.cs b/Samples~/TicTacToe/Scripts/MenuController.cs new file mode 100644 index 0000000..ee0df2e --- /dev/null +++ b/Samples~/TicTacToe/Scripts/MenuController.cs @@ -0,0 +1,136 @@ +// +// This is simple game client for Tic-Tac-Toe game +// You can get game server source code here: https://github.com/mopsicus/shardy-tictactoe +// + +using UnityEngine; +using Shardy; +using TMPro; +using UnityEngine.UI; +using UnityEngine.SceneManagement; + +public class MenuController : MonoBehaviour { + + /// + /// Input field for host + /// + [SerializeField] + TMP_InputField HostInput = null; + + /// + /// Input field for port + /// + [SerializeField] + TMP_InputField PortInput = null; + + /// + /// Link to status text + /// + [SerializeField] + TextMeshProUGUI StatusText = null; + + /// + /// Search panel + /// + [SerializeField] + GameObject SearchPanel = null; + + /// + /// Play button + /// + [SerializeField] + Button PlayButton = null; + + /// + /// Init + /// + void Awake() { + Connector.Use().OnConnect += OnConnect; + Connector.Use().OnDisconnect += OnDisconnect; + Connector.Use().OnReady += OnReady; + Connector.Use().On(Consts.PLAY, (data) => { + SceneManager.LoadScene(Consts.GAME_SCENE); + }); + if (Connector.Use().IsConnected) { + PlayButton.interactable = true; + StatusText.text = "Ready for play"; + } + } + + /// + /// Unsubscribe on exit + /// + void OnDisable() { + Connector.Use().OnConnect -= OnConnect; + Connector.Use().OnDisconnect -= OnDisconnect; + Connector.Use().OnReady -= OnReady; + Connector.Use().Off(Consts.PLAY); + } + + /// + /// Callback on ready to work + /// + void OnReady() { + StatusText.text = "Ready for play"; + } + + /// + /// Callback on disconnect with reason + /// + void OnDisconnect(DisconnectReason reason) { + PlayButton.interactable = false; + StatusText.text = $"Disconnected: {reason}"; + } + + /// + /// Callback on connect with status + /// + void OnConnect(bool status) { + PlayButton.interactable = status; + StatusText.text = status ? "Connected" : "Disconnected"; + if (status) { + Connector.Use().Handshake(); + } + } + + /// + /// Connect to server + /// + public void Connect() { + var host = HostInput.text.Trim(); + var port = int.Parse(PortInput.text.Trim()); + Connector.Use().Connect(host, port); + } + + /// + /// Disconnect + /// + public void Disconnect() { + Connector.Use().Disconnect(); + } + + /// + /// Start play + /// + public void Play() { + SearchPanel.SetActive(true); + Connector.Use().Request(Consts.SEARCH_START, (data) => { + if (!string.IsNullOrEmpty(data.Error)) { + SearchPanel.SetActive(false); + StatusText.text = data.Error; + } + }); + } + + /// + /// Stop opponent search + /// + public void Stop() { + Connector.Use().Request(Consts.SEARCH_STOP, (data) => { + if (!string.IsNullOrEmpty(data.Error)) { + StatusText.text = data.Error; + } + SearchPanel.SetActive(false); + }); + } +} diff --git a/Samples~/TicTacToe/Scripts/MenuController.cs.meta b/Samples~/TicTacToe/Scripts/MenuController.cs.meta new file mode 100644 index 0000000..b2f6706 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/MenuController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8189a9473e61645ebb6c7b49be2df4dc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/TestHandshake.cs b/Samples~/TicTacToe/Scripts/TestHandshake.cs new file mode 100644 index 0000000..3a2e4ec --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestHandshake.cs @@ -0,0 +1,38 @@ +using System.Text; +using Shardy; + +/// +/// Handshake stub +/// +class TestHandshake : IValidator { + + /// + /// Data for acknowledgement + /// + public byte[] Acknowledgement(byte[] body) { + // + // generate as you wish here + // + return body; + } + + /// + /// Data for initial handshake + /// + public byte[] Handshake(byte[] body = null) { + // + // generate as you wish here + // + return Encoding.UTF8.GetBytes("handshake_data"); + } + + /// + /// Verify acknowledgement + /// + public ValidatorState VerifyAcknowledgement(byte[] body) { + // + // validate as you wish here + // + return ValidatorState.Success; + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta b/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta new file mode 100644 index 0000000..ac63c1c --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestHandshake.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 00986864a3f414c5fb448a110b260636 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/TicTacToe/Scripts/TestSerializer.cs b/Samples~/TicTacToe/Scripts/TestSerializer.cs new file mode 100644 index 0000000..503cb7f --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestSerializer.cs @@ -0,0 +1,30 @@ +using System.Text; +using NiceJson; +using Shardy; + +/// +/// Simple example serializer via NiceJson +/// +class TestSerializer : ISerializer { + + /// + /// Decode received data to PayloadData + /// + public PayloadData Decode(byte[] body) { + var data = (JsonObject)JsonNode.ParseJsonString(Encoding.UTF8.GetString(body)); + return new PayloadData((PayloadType)(int)data["type"], data["name"], data["id"], Encoding.UTF8.GetBytes(data["data"]), data["error"]); + } + + /// + /// Encode to byte array for transporting + /// + public byte[] Encode(PayloadData payload) { + var data = new JsonObject(); + data["type"] = (int)payload.Type; + data["name"] = payload.Name; + data["id"] = payload.Id; + data["data"] = (payload.Data != null) ? Encoding.UTF8.GetString(payload.Data) : string.Empty; + data["error"] = payload.Error; + return Encoding.UTF8.GetBytes(data.ToJsonString()); + } +} \ No newline at end of file diff --git a/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta b/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta new file mode 100644 index 0000000..281df04 --- /dev/null +++ b/Samples~/TicTacToe/Scripts/TestSerializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 46dd4829a45134c1cad76cafce5a775d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json new file mode 100644 index 0000000..e4e6cbf --- /dev/null +++ b/package.json @@ -0,0 +1,43 @@ +{ + "name": "com.mopsicus.shardy", + "version": "1.0.0", + "displayName": "Shardy", + "description": "Client for Shardy โ€“ framework for online games and applications for Node.js. Supports sockets, websockets, WebGL.", + "license": "MIT", + "author": "Mopsicus ", + "homepage": "https://github.com/mopsicus/shardy-unity", + "changelogUrl": "https://github.com/mopsicus/shardy-unity/blob/main/CHANGELOG.md", + "documentationUrl": "https://github.com/mopsicus/shardy-unity/blob/main/Documentation~/index.md", + "unity": "2022.3", + "keywords": [ + "shardy", + "framework", + "rpc", + "web", + "netcode", + "games", + "engine", + "multiplayer", + "websocket", + "networking", + "webgl", + "socket" + ], + "dependencies": {}, + "repository": { + "type": "git", + "url": "https://github.com/mopsicus/shardy-unity.git" + }, + "samples": [ + { + "displayName": "Demo", + "description": "A demo scene to show Shardy API usage", + "path": "Samples~/Demo" + }, + { + "displayName": "TicTacToe", + "description": "Tic-Tac-Toe client for test game server ", + "path": "Samples~/TicTacToe" + } + ] + } \ No newline at end of file diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..65411ff --- /dev/null +++ b/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cbdfae54d471141ab8c6fbe89f744f05 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: