FieldWalker

Diarkis Unity SDK Sample Application

This is a sample application based on Unity Engine provided by the network middleware, Diarkis. It includes various features such as MatchMake, DirectMessage, and player-to-player data synchronization using different protocols (UDP, TCP, P2P). For more details about Diarkis products, please refer to the Diarkis Website.

Folder Description

  • Core Install the Diarkis C# SDK

    • Client Diarkis Module (C# classes and helpers for using the Diarkis Core Library)

      • Data Data structure related classes

      • Events Event related classes

      • Logging Classes related to the logging system

      • Modules Module-base classes (code interacting with Diarkis Core Library)

      • System System related classes (like memory management)

      • Utils Various helpers for using Diarkis types

    • Interop Auto-generated C# files to call Diarkis Native Code (modifying these files is not recommended)

    • CustomCommands Developers can define custom commands using the files here

      • json_definitions JSON files defining structures for custom commands

      • custom JSON files defining structures for custom commands

    • Libraries Diarkis Native Code made in C++ (Diarkis Core API)

  • Documentation This document

  • Plugin Diarkis plugin scripts

    • Callbacks Scripts to register callbacks to Diarkis events

    • Common Scripts common to each scene (including the singleton class DiarkisNetworkManager interfacing with Diarkis SDK)

      • MainGame Scripts for the MainGame scene (synchronization of players in a 3D environment)

  • Sample Diarkis sample scripts

    • Misc Miscellaneous files (lighting, input system, etc.)

    • Models 3D model files

      • Animations Animation files for characters

      • Materials Material files

    • Prefabs Prefab files (e.g., DiarkisPlayer, Grid, etc.)

    • Scenes Scene files for Unity.

    • Scripts Unity related scripts

      • MainGame Scripts for the MainGame scene (synchronization of players in a 3D environment)

      • SceneManagers Scene-specific classes

      • UI User interface scripts (buttons, toggles, etc.)

  • Textures Image files

Loading the Project

In the Unity project, open the package manager with Window>Package Manager, click +, then Add Package From Disk, and select the package.json file found at the root of the Diarkis sample folder.

It is recommended to use the LTS version of Unity (as of the latest update, 2022.3.20f1). You can now open the project in Unity Editor.

Select the title scene file (Assets/Scenes/DiarkisSample_1_Title.unity). You can run the sample by clicking the play button from the toolbar.

Library Security Error on MacOS

Users loading the project on MacOS might see a pop-up notification stating that the library cannot be trusted. In this case, open System Preferences>Privacy & Security without closing the window and press Allow Anyway. You may need to apply this to each library (only once for each). Failing to do so will prevent the Diarkis library from running, and the sample will display runtime errors.

Disabling Recompile on Play Mode

Scene Explanation

Title

This scene is the initial sample scene and can provide various inputs to set up the connection with the Diarkis server.

Item
Description
Example

Host

The EndPoint URL of the Diarkis Http server

asia-northeast1.diarkis.io (http:// is not required) / 192.168.XXX.XXX:7000

ClientKey

Client Key (specify if needed)

XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

UID

Unique User ID

Diarkis203

RandomUID

Randomly auto-generate a unique User ID (unique GUID)

0f0b66aa-8d45-4505-9208-c41d975a0c65

ServerType

Specify the communication protocol of the Diarkis server to use

UDP or TCP

SelectFeature

From this screen, you can choose features related to each Diarkis module.

Room

This screen uses the Diarkis Room Module. You can enter a room using Create, Join, or RandomJoin from this screen.

Item
Description
Example

MaxMember

Maximum number of members in the Room

4

AllowEmpty

Allow the existence of a room when no user is present in it.

true

TTL

Room's survival time after it's left with no members.

60

Interval

Sending interval on the server for Broadcast and MessageTo messages; messages are buffered for this interval.

200

Join Existing Room

Specify RoomID to join. (Do not use the above setting)

Join Random Room

Join a random room using the settings above, or create a new room if no existing room is found.

Create Room

Create and join a room using the settings above.

MainGame - Room

This screen appears upon successfully joining a Room. Message exchange through the Diarkis Room Module synchronizes the position of players and objects.

Item
Description
Example

My UID

UserID for the local character

Diarkis-Test

Room ID

ID of the Room in which you are entering

17b39a74e5fff52c7f0000011fa4

Owner UID

User ID of the Room Owner

Diarkis-Test

Members

Members currently entering the Room

Diarkis-Test, ...

Broadcast/Send

Send a message to everyone in the Room. Specifying a User ID sends the message only to that user

Leave

Leave the Room and return to the previous screen

Start P2P

Initializes the P2P communication with other Room members. After setting up, messaging is done using the Diarkis P2P Module, improving communication speed.

Create Sphere/Cube

Creates a new object near the player and synchronizes its position

Clear All Objects

Deletes all created Objects within the Room

Clear My Objects

Deletes all Objects created by you within the Room

MainGame - Field

This screen displays a 3D representation of the Diarkis Field Module. Field communication does not require pre-commands like Join or Create. Only one Field exists per server type, and a user can only exist at one position within it at a time.

Item
Description
Example

My UID

UserID for the local character

Diarkis-Test

Server Count

Number of Diarkis servers in the mesh network affects the number of Grids dividing the ground.

4

Field Size

Size of the Field; changes the overall Field size and the Grid size dividing it.

4500

Grid Size

Size of one Grid, calculated from Field Size and Server Count.

2250

Leave

Leave the Field and return to the previous scene.

MatchMaker

This screen allows you to issue a IssueTicket using the Diarkis MatchMaker Module and wait for matching with other users from the server. Upon completing the match, you can broadcast messages to other Ticket members.

Item
Description
Example

TicketType

Specify the type of ticket to issue. In the basic version of the Diarkis Template Server, only Ticket Type 0 is implemented. Some server-side development is required to handle other ticket types.

0

Issue Ticket

Issue a MatchMaking IssueTicket to the server.

Cancel

Cancel an IssueTicket.

Status

Matching status.

Not Started / Waiting For Match / Complete / Failed

Ticket Owner ID

UserID of the owner of the completed ticket.

Members

Members of the completed ticket.

Message

Broadcast a message to other Members of the Ticket.

Group

The Diarkis Group Module allows you to create or join a random Group from this screen, and broadcast messages to other Group members.

Item
Description

Group ID

The Group ID you are participating in

Message Button

Broadcast a message to other Group members

Direct Message

The Diarkis DM Module can be used on this screen to send Unicast messages directly to other members.

Item
Description

My UID

Your UserID

Recipient ID

UserID of the user to whom the message will be sent

Message Button

Send a Direct Message to the user specified by the Recipient ID

Class Description

This class is a MonoBehaviour singleton class and must remain active as long as the user wishes to use Diarkis features in the Unity Project. It can be called statically to expose Diarkis module objects.

Usage Example:

if (!DiarkisNetworkManager.IsConnected()) // check if the client is not yet connected to Diarkis
{
    DiarkisNetworkManager.Instance.ServerType = Diarkis.ServerType.UDP; // set the protocol to UDP
    DiarkisNetworkManager.Instance.HttpHost = "127.0.0.1:7000"; // set the server address
    DiarkisNetworkManager.Instance.ClientKey = _clientKeyInputField.text; // set the client Key
    DiarkisNetworkManager.Instance.UID = "John Doe"; //set the user ID
    DiarkisNetworkManager.Connect(); // initiate Connection to Diarkis
}

The inspector UI includes various options to set up Diarkis options from the editor:

Events

Diarkis API uses its own event system. When specific actions within the Diarkis module are completed, events are triggered by the related module, and all registered callbacks are invoked in the EventHandler. Each event and its parameter signatures are located in this class.

Example of Event Registration:

protected override void Start()
{
  DiarkisEventHandler handler = DiarkisNetworkManager.GetEventHandler();
  handler.RegisterCallback(DiarkisEventType.UDPConnect, (System.Action<DiarkisConnectionEventArgs>)((args) => { OnConnect(args); }), this);
}

public void OnConnect(DiarkisConnectionEventArgs args)
{
    if (args.GetStatus() == DiarkisConnectStatus.DCS_Success)
    {
        Logger.Debug("Connection Success");
    }
    else
    {
        Logger.Error("Connection Failed");
    }
}

The DiarkisCallbackDispatcher MonoBehaviour class allows you to register events from the Editor user interface without writing a single line of code. It is also useful for remembering the event’s type signature.

For example, the following setting behaves similarly to the above code.

Logging

The Diarkis logging system is based on two classes: DiarkisLogger and DiarkisLoggingFactory.

DiarkisLogger instances are created by DiarkisLoggerFactory and are used to log information at different log levels. These loggers provide methods for logging messages, warnings, errors, and other pertinent information regarding the execution of the application.

DiarkisLoggerFactory is responsible for creating loggers within the native code, providing Logger instances to different modules within the Diarkis framework. The log function provided in LoggerFactory's constructor can be configured to control the output destination, log level filtering, and formatting options, allowing developers to tailor the logging behavior to their specific needs.

Usage Example:

    class Program
    {
        static void Main(string[] args)
        {
            var logSeverity = DiarkisLoggerSeverity.Debug;
            var logFileStream = DiarkisUtils.GetFileStreamWriter("./", "diarkis-cs-sample-logs.txt");
            var logAction = new Action<string>((str) =>
            {
                if (str.Contains("\n"))
                {
                    Console.Write(str);
                    logFileStream.Write(str);
                }
                else
                {
                    Console.WriteLine(str);
                    logFileStream.WriteLine(str);
                }
            });
            var loggerFactory = new Diarkis.DiarkisLoggerFactory(logSeverity, logAction);
            DiarkisLogger = loggerFactory.CreateLogger();
            var logger1 = (DiarkisLogger)loggerFactory.CreateLogger("ExampleLogger1");
            var logger2 = (DiarkisLogger)loggerFactory.CreateLogger("ExampleLogger2");
            logger1.Error("this is an error");
            logger2.Debug("this is a Debug log");
            logger2.Verbose("the Debug Log is not displayed because severity level is too high");
            var eventHandler = new DiarkisEventHandler();
            Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
        }
    }

Output Example:

2024-02-01 15:39:32[FAIL][ExampleLogger1]this is an error
2024-02-01 15:39:32[DEBUG][ExampleLogger2]this is a Debug log

Note: The code above also creates a file at ./diarkis-cs-sample-logs.txt and registers the output.

Log Level Hierarchy:

public enum DiarkisLoggerSeverity {
  Trace = 0,
  Verbose,
  Debug,
  Info,
  Warning,
  Error,
  Fatal,
  None
}

Logger Manager Inspector

The NetworkManager inspector also includes various fields for easily configuring the logger. For example, you can set different log severities based on the logger's category or display logs on the game screen.

Diarkis Core Library

The Diarkis Core Library is a DLL made in C++. Automatically generated .cs wrapper files Core-wrapped allow the use of C++ native code in C#.

Diarkis Module

Diarkis Module is part of the Diarkis C# SDK and is independent of Unity, allowing it to be used in pure C# console applications.

This is not strictly a module but a class that functions as an interface containing all Diarkis Modules at once. It is a member of the DiarkisNetworkManager Unity class but can also be used in a plain C# context. You need one DiarkisInterface per connection to a Diarkis server. If you need a server for MatchMaking and one for TURN, you should have two instances of DiarkisInterface.

Usage Example:

  class Program
  {
      static void Main(string[] args)
      {
          var eventHandler = new DiarkisEventHandler(); // Event Handler object (cf: Events)
          var logSeverity = DiarkisLoggerSeverity.Error;
          var logAction = new Action<string>((str) => {Console.WriteLine(str); });
          var loggerFactory = new Diarkis.DiarkisLoggerFactory(logSeverity, logAction); // Logger Factory Object (cf: Logging)

          // DiarkisInterface object is created here (The ServerType is passed as parameter of the constructor UDP/TCP)
          Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
          diarkis.HttpHost = "192.168.100.12:7000";

          // StartRuntimeThread will initiate the update loop using multiThreading,
          // Since Unity is not a thread safe Engine, it is not recommended to use this function in Unity
          // The recommended behavior is to call diarkis.UpdateComponents(); inside the FixedUpdate function of the
          // DiarkisNetworkManager object
          diarkis.StartRuntimeThread();
          Console.WriteLine("Connecting to " + diarkis.HttpHost);

          // Send the Http Authentication get request to the Http Diarkis server, if the authentication is sucessful
          // the server will reply
          diarkis.sendHttpAuth();

          // note: DiarkisUtils.WaitFor() is using threads will block the main thread until the condition is met.
          // It is not recommended to use it in a Unity Project since it will make the game freeze.
          // Instead it is recommended to use the DiarkisAsync.WaitFor() function which is using the Unity Coroutine mechanism
          if (!DiarkisUtils.WaitFor(() => { return diarkis.IsConnected(); }))
          {
              Console.WriteLine("Connection Timeout");
              return;
          }
          Console.WriteLine("UDP Connection success");

          // listen to the Room Join event (just an example)
          eventHandler.RegisterCallback(Diarkis.DiarkisEventType.RoomJoin,
          (DiarkisRoomJoinEventArgs eventArgs) => { Console.WriteLine("Room Joined!"); });

          // Join a random room
          diarkis.Room.SendJoinRandomRoom(4, 60, 100, true);

          // do any required more actions ...
          return;
      }
  }

This module is used to create and manage a UDP connection with a Diarkis server; several other modules, such as Room and P2P, rely on it.

This module manages and creates a TCP connection with a Diarkis server. Other modules like Room and P2P can be configured to use either UDP or TCP, though some modules are dependent only on UDP.

This module allows multiple clients to join a Room and exchange data, messages, or object information. A P2P connection can be initiated with group members under the condition that the Room is using a UDP connection. You can only join one Room at a time, and to enter the same Room, it must be connected to the same server.

This module is used to create and manage a direct peer-to-peer connection between two clients. It is used as an optional feature within the Room module. Clients can initiate P2P synchronization and transmit data without using an intermediate server after having joined a Room.

The Group module allows multiple clients to join a group and exchange messages. The number of Groups one can join at the same time is unlimited, and it doesn't require being connected to the same server to join the same Group.

This module looks similar to the Room but varies in many ways. Only one Field exists within a server network. With Diarkis server logic, multiple UDP servers can be configured as part of the same mesh network. A Field is divided into several Grids, each assigned to a server. Each server is responsible for conveying client information within its Grid. This module is well-suited for large environments where a high number of players might connect simultaneously.

This Direct Message (DM) module can be used to send unicast messages directly to members on separate servers. Unlike Room or Group, DM does not require joining the same room, and you can send directly if you know the UserID.

The MatchMaker module contains functions and events for issuing matchmaking tickets. Ideally, matchmaking conditions are defined server-side. Clients simply set TicketType and issue a ticket using IssueTicket(). Once ticket issuance is completed (all players fulfilling matching conditions are found), a TicketComplete event is triggered, and players can communicate with other matched members using the TicketBroadcast command.

Session is similar to the Field module in that it allows the same session to exist on different Diarkis servers within the same mesh network. However, it is not meant to share coordinate data but to exchange standard data for a limited group of players.

Custom Commands

Most commands transmitted through the Diarkis module are built-in commands, meaning their content is known to the core library and parsed into specific types such as DiarkisRoomJoinEventArgs.

However, developers wishing to develop their own commands must add the command to both the server-side and client-side. To facilitate the creation and parsing of such commands, Diarkis provides a standalone binary called Puffer, available as linux or mac binaries in the Diarkis Server Template (a separate repository).

The json definition file containing some of the payloads and commands used in the sample is found at CustomCommands.json.

Depending on how custom commands are defined server-side, parsing them is mostly done in OnResponse or OnPush events (in the cases of UDP or TCP). Here's an example of using a Zoo command defined as above:

        public void OnResponse(DiarkisResponseEventArgs args)
        {
            if (args.GetVersion() == Zoo.VER && args.GetCommand() == Zoo.CMD)
            {
                Zoo zooCommand = new Zoo();
                if (!Zoo.Unpack(args.GetPayload().ToArray()))
                {
                    DiarkisNetworkManager.Instance.Logger.Error("Failed to parse Zoo command");
                    return;
                }
                long lion = zooCommand.Lion;
                byte[] penguins = zooCommand.Penguins;
            }
        }

Using Multiple DiarkisInterface Instances

Although the DiarkisNetworkManager is designed to use a single connection to one Diarkis server, it's also possible to handle multiple connections simultaneously. For that reason, you can create multiple alternative DiarkisInterface objects via the DiarkisNetworkManager object, as shown in this example:

        var diarkisLobby = DiarkisNetworkManager.GetDiarkisInterface("Lobby");
        var diarkisGame = DiarkisNetworkManager.GetDiarkisInterface("Game");
        diarkisLobby.EventHandler.RegisterCallback(DiarkisEventType.UDPConnect, new Action<DiarkisConnectionEventArgs>((args) => { Debug.Log("CONNECTED TO LOBBY SERVER."); }));
        diarkisLobby.EventHandler.RegisterCallback(DiarkisEventType.UDPConnect, new Action<DiarkisConnectionEventArgs>((args) => { Debug.Log("CONNECTED TO GAME SERVER."); }));

        DiarkisNetworkManager.Connect("Lobby", DiarkisTransportType.UDP, "LBY");
        DiarkisNetworkManager.Connect("Game", DiarkisTransportType.UDP, "GAME");

Asynchronous Code

While events are the way to perform actions synchronously, developers may want certain scenarios to execute in a predefined order asynchronously. For that, there is a WaitFor() function defined in the DiarkisUtils interface.

Usage Example:

class Program
  {
      static void Main(string[] args)
      {
          Diarkis.DiarkisInterface diarkis = new Diarkis.DiarkisInterface(loggerFactory, ServerType.UDP, eventHandler);
          diarkis.HttpHost = "192.168.100.12:7000";
          diarkis.StartRuntimeThread();
          Console.WriteLine("Connecting to " + diarkis.HttpHost);
          diarkis.sendHttpAuth();
          if (!DiarkisUtils.WaitFor(() => { return diarkis.IsConnected(); }))
          {
              Console.WriteLine("Connection Timeout");
              return;
          }
          Console.WriteLine("UDP Connection success");
          Console.WriteLine("Joining a Room...");
          diarkis.Room.SendJoinRandomRoom(4, 60, 100, true);
          if (!DiarkisUtils.WaitFor(() => { return diarkis.Room.ID != ""; }))
          {
              Console.WriteLine("Room Join Timeout");
              return;
          }
          Console.WriteLine("Room Joined!");
          return;
      }
  }

Note: DiarkisUtils.WaitFor() uses the Threading.Sleep() function. It means that the main thread is blocking until the condition is met. Instead, it is recommended to use the DiarkisAsync.WaitFor() version available in the DiarkisAsync interface, which uses Unity's Coroutine mechanism instead of Threads.

Unity Asynchronous Code Example:

void Start()
{
    StartCoroutine(ConnectAndJoinRoomAsync())
}

public IEnumerator ConnectAndJoinRoomAsync()
{
    DiarkisNetworkManager.Connect();
    DiarkisAsyncResult res = new DiarkisAsyncResult();
    yield return DiarkisAsync.WaitFor(() =>
    {
        return IsConnected();
    }, res);
    if (!res.completed)
    {
        if (Logger != null)
        {
            Logger.Error("Connection Time Out");
        }
        yield break;
    }

    Logger.Debug("Connection Success");
    Logger.Debug("Joining Random Room...");
    DiarkisNetworkManager.GetRoom().SendJoinRandomRoom(4, 60, 100, true);
    yield return DiarkisAsync.WaitFor(() =>
    {
        return DiarkisNetworkManager.GetRoom().ID != "";
    }, res);
    if (!res.completed)
    {
        if (Logger != null)
        {
            Logger.Error("Room Join Time Out");
        }
        yield break;
    }
    Logger.Debug("Room succesfully joined");
    yield return null;
}

Catching Diarkis Events Asynchornously

Although Diarkis library is designed to call events through callback functions synchronously (as described in the Events Section, it’s worth mentioning that combining the above function with event callbacks will allow catching event callbacks within an asynchronous context.

Here is an example of a function waiting asynchronously for a member to join using event callbacks:

        void Start()
        {
            StartCoroutine(WaitForRoomMemberJoin())
        }

        IEnumerator WaitForRoomMemberJoin()
        {
            DiarkisAsyncResult res = new DiarkisAsyncResult();
            DiarkisPayloadEventArgs eventArgs = null;
            var callback = (Action<DiarkisPayloadEventArgs>)((args) => { eventArgs = args; });
            DiarkisNetworkManager.GetEventHandler()?.RegisterCallback(Diarkis.DiarkisEventType.RoomMemberJoin, callback, this);
            yield return DiarkisAsync.WaitFor(() =>
            {
                return eventArgs != null;
            }, res);

            DiarkisNetworkManager.GetEventHandler()?.UnregisterCallback(callback);
            if (res.completed)
            {
                // callback triggered
            }
            else
            {
                //callback trigger timeout
            }
            yield return null;
        }

Custom Allocators

It's possible to arbitrarily set the allocator size to be used throughout the Diarkis Native Library code. For that, static functions SetCustomAllocatorSize and SetCustomAllocator are provided.

When feasible, this size should not exceed the available memory size, and an exception will be thrown if it does.

The following example sets the allocator size to 16MB. Diarkis libraries typically use no more than 500Kb, but it's recommended to use at least 4Mb.

Usage Example:

  class Program
  {
      static void Main(string[] args)
      {
          //Parameters are the Size of the Buffer, and the alignment.
          ICustomAllocator _originalAllocator = DiarkisLib.SetCustomAllocatorSize(1024 * 1024 * 16, 16);

          // code using Diarkis ...

          // When Diarkis resources are done to be used and have been disposed, the Allocator can be safely reset
          DiarkisLib.SetCustomAllocator(_originalAllocator);
          return;
      }
  }

Notes on Memory Safety

Diarkis C# SDK is based on the core Diarkis Library initially created in C++ and compiled into native libraries. Automatically generated wrapper files in .cs allow C++ native code usage in C#. However, C++ and C# are not the same language, and the most significant difference is how they manage memory. C# relies on garbage collection (GC) for heap management, making it "memory-safe." C++ has no GC, requiring developers to manage data allocation/deallocation.

Therefore, every wrapped class from the Native Diarkis Library is derived from the IDisposable type in C#. These objects have the function to instruct the Garbage Collector not to care about the data, allowing developers to release unmanaged resources using the Dispose() function as desired.

It's essential to understand that once the Dispose() function is called, any code dependent on the unmanaged resources allocated to this object may cause a Memory Exception, Unity Editor crashes, or Memory Leaks. If such issues arise, releasing a resource too early or using one too late might have been an issue.

Building on iOS

When building for iOS, it's important to set some specific values in the Player Settings. Set Managed Stripping Level to minimal in the Optimization section.

When building for iOS, it may be necessary to perform some minor adjustments so that Diarkis Libraries can run correctly. After pressing the Build Button in Unity Editor, Unity will generate the xcode project folder. Open the xcode project, select the Unity-iPhone target, and open the General tab. Next, you need to add two of the runtime Diarkis library files to the project in the left panel, available in the Libraries\Diarkis\Libraries\iOS folder. Then, add these files to the Frameworks, Libraries, and Embedded Content list. This is necessary to ensure that the libraries will be copied to your iOS device when installing the app.

Building on visionOS and visionOS-Simulator

Building for visionOS is similar to iOS, but there are some additional steps required in xcode. The first thing to note is that you can switch between visionOS and visionOS-Simulator as the platform in Unity's Build Window.

Moreover, depending on whether you are building for the simulator or an actual visionOS device, you'll need to change library parameters within the editor. For instance, if you want to build for VisionOS-Simulator-arm64, you need to select two libraries in the Packages>Diarkis Plugin Sample>Core>Libraries>visionOS-Simulator-arm64 folder and set the platform to visionOS, disabling conflicting libraries.

Once the build is complete, open the xcode project file in xcode (version 15.2 or higher is required to support visionOS). Then, similarly to iOS builds, add the corresponding library for the target platform to your project in the left panel of xcode.

Be sure to check Add to target: Unity-visionOS`

Next, in Unity-VisionOS > General > Frameworks, Libraries, and Embedded Content, set the two Diarkis libraries to Embed & Sign.

(This step is specific to simulators). In Unity-VisionsOS > Build Settings > Linking - General, add the value -ld64 to Other Linker Flags.

With this linker correctly set, your app is ready to build for visionOS.

Obfuscation

Obfuscation tools can be used safely with Diarkis. For example, Beebyte Obfuscator from the Unity Asset Store has been used to build the obfuscated version of the Diarkis sample. The binary file contains assemblies to hide the application's logic, making it difficult for hackers to reverse-engineer the source code.

To use Beebyte Obfuscator, you must first purchase a license, download it from the Window > Package Manager window, and import it into the project.

When the package is imported, a settings prefab is created in Assets/Editor/Beebyte/Obfuscator/ObfuscsatorOptions. By altering these settings, you can opt for stronger or lighter obfuscation, though the default settings should work well.

You can then build the project from the File > Build Settings window, ensuring to use the Clean Build option to ensure obfuscation settings are applied between builds.

Last updated

Was this helpful?