Skip to content

Commit

Permalink
Upgrade to v1.10. Supporting visionOS.
Browse files Browse the repository at this point in the history
  • Loading branch information
botaohu committed Sep 2, 2024
1 parent 5934945 commit 23e44ef
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 62 deletions.
5 changes: 3 additions & 2 deletions Editor/MultipeerConnectivityTransportBuildProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2023 Reality Design Lab <[email protected]>
// SPDX-FileCopyrightText: Copyright 2024 Reality Design Lab <[email protected]>
// SPDX-FileContributor: Yuchen Zhang <[email protected]>
// SPDX-FileContributor: Botao Amber Hu <[email protected]>
// SPDX-License-Identifier: MIT

using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;

#if UNITY_IOS && UNITY_EDITOR
#if (UNITY_IOS || UNITY_VISIONOS) && UNITY_EDITOR
using UnityEditor.iOS.Xcode;

namespace Netcode.Transports.MultipeerConnectivity.Editor
Expand Down
4 changes: 1 addition & 3 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
MIT License

Copyright (c) 2023 Holo Interactive

Copyright (c) 2021 Unity Technologies
Copyright (c) 2024 Reality Design Lab

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:

Expand Down
43 changes: 33 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@

## Overview

This package implemented the transport layer of Netcode for GameObjects with Apple Multipeer Connectivity, which can enable peer-to-peer communication between nearby devices. By using Multipeer Connectivity, nearby devices can connect to each other when there is no WiFi or cellular network. Multipeer Connectivity is the technology behind AirDrop, which means it can transfer large file between devices very fast. Please reference Apple's official document for detailed information: https://developer.apple.com/documentation/multipeerconnectivity.
This package implements the Transport layer of Netcode for GameObjects using Apple Multipeer Connectivity, enabling peer-to-peer communication between nearby Apple devices (macOS, visionOS, iOS). Multipeer Connectivity facilitates real-time communication and data exchange, supporting activities like multiplayer gaming, collaborative work, and data sharing, even without WiFi or cellular networks. It powers technologies like AirDrop, allowing fast large file transfers. For more details, refer to Apple's official documentation of [Multipeer Connectivity](https://developer.apple.com/documentation/multipeerconnectivity).

We created a [sample project](https://github.com/holoi/netcode-transport-multipeer-connectivity-sample) demonstrating how to properly setup the network connection.
The Multipeer Connectivity Transport for Netcode for GameObjects extends this capability to Unity-based projects, enabling developers to integrate cross-platform networking features into their games and applications. This allows peer-to-peer local network communication between iOS, visionOS, macOS devices, and within the Unity Editor on Mac. For a demonstration on how to use this transport, please check out our [sample project](https://github.com/realitydeslab/netcode-transport-multipeer-connectivity-sample).

We contribute this package to Unity Multiplayer Community repo. See https://github.com/Unity-Technologies/multiplayer-community-contributions/tree/main/Transports/com.community.netcode.transport.multipeer-connectivity
We also contribute this early version of this package to Unity Multiplayer Community repo.
See https://github.com/Unity-Technologies/multiplayer-community-contributions/tree/main/Transports/com.community.netcode.transport.multipeer-connectivity

## System Requirements

This package has been tested and verified for peer-to-peer communication using MultipeerConnectivity across the following platforms:
- iOS 17.0+
- visionOS 1.0+
- macOS 14.0+
- Unity Editor 2022.3 LTS (macOS)

Note: The later versions may work but are not tested.

## How To Install

This package uses the scoped registry feature to resolve package dependencies. Open the Package Manager page in the Project Settings window and add the following entry to the Scoped Registries list:

* Name: `Reality Design Lab`
Expand All @@ -19,7 +31,7 @@ Now you can Install a package from a registry by name:

```org.realitydeslab.netcode.transport.multipeer-connectivity```

## Some Good to Know Concepts Before Using The Transport
## Concepts Before Using The Transport

### Host-Client Architecture vs Peer-To-Peer Architecture

Expand Down Expand Up @@ -118,14 +130,25 @@ When you build the project onto your iOS devices for the first time, both host a

## Debug Your Project in Unity Editor

Please notice that Multipeer Connectivity Transport can only run on an iOS device. It cannot run on your Mac. Therefore, when you want to debug your project in Unity Editor, we recommand you temporarily switch to use Unity Transport.
Please notice that Multipeer Connectivity Transport can run on an iOS, visionOS, macOS device. It cannot run on your Mac. Therefore, when you want to debug your project in Unity Editor, we recommand you temporarily switch to use Unity Transport.


## How to compile native plugins

Run
```
cd Source~
./build.sh
```
To build the native plugins for this transport from source code, follow these steps:

1. Ensure you have Xcode and the necessary iOS development tools installed on your Mac.
1. Open a terminal and navigate to the root directory of this project.
1. Run the following commands:
```
cd Source~
./build.sh
```
This script will compile the native iOS, macOS, visionOS plugin and place the resulting `.a` files in the appropriate directories within the Unity project structure.
1. After running the build script, the updated plugin files should be ready for use in your Unity project.
Note: You'll need to rebuild the plugin if you make any changes to the native code or want to target a different iOS architecture.
## Author and License
This project is authored by [Reality Design Lab](https://reality.design) and is licensed under the [MIT License](https://opensource.org/license/mit).
66 changes: 30 additions & 36 deletions Runtime/MultipeerConnectivityTransport.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 Reality Design Lab <[email protected]>
// SPDX-FileCopyrightText: Copyright 2024 Reality Design Lab <[email protected]>
// SPDX-FileContributor: Yuchen Zhang <[email protected]>
// SPDX-FileContributor: Botao Amber Hu <[email protected]>
// SPDX-License-Identifier: MIT

using System;
Expand All @@ -12,6 +13,12 @@ namespace Netcode.Transports.MultipeerConnectivity
{
public class MultipeerConnectivityTransport : NetworkTransport
{
#if (UNITY_IOS || UNITY_VISIONOS) && !UNITY_EDITOR
public const string IMPORT_LIBRARY = "__Internal";
#else
public const string IMPORT_LIBRARY = "MultipeerConnectivityTransportForNetcodeForGameObjectsNativePlugin";
#endif

/// <summary>
/// This class is a singleton so it's easy to be referenced anywhere.
/// </summary>
Expand Down Expand Up @@ -79,11 +86,6 @@ public class MultipeerConnectivityTransport : NetworkTransport
/// </summary>
private readonly Dictionary<int, string> _pendingConnectionRequestDict = new();

/// <summary>
/// Check if we are currently running on an iOS device.
/// </summary>
public static bool IsRuntime => Application.platform == RuntimePlatform.IPhonePlayer;

/// <summary>
/// Initialize the MPCSession and register native callbacks.
/// </summary>
Expand All @@ -96,7 +98,7 @@ public class MultipeerConnectivityTransport : NetworkTransport
/// <param name="onConnectedWithPeer">Invoked when connected with a peer</param>
/// <param name="onDisconnectedWithPeer">Invoked when disconnected with a peer</param>
/// <param name="onReceivedData">Invoked when receives data message from a peer</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_Initialize(string nickname,
Action<int, string> onBrowserFoundPeer,
Action<int, string> onBrowserLostPeer,
Expand All @@ -112,33 +114,33 @@ private static extern void MPC_Initialize(string nickname,
/// </summary>
/// <param name="sessionId">The unique id of the network session</param>
/// <param name="autoApproveConnectionRequest">Setting to true to approve all incoming connection requests</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_StartAdvertising(string sessionId, bool autoApproveConnectionRequest);

/// <summary>
/// Start browsing for nearny advertising peers.
/// </summary>
/// <param name="sessionId">The unique id of the network session</param>
/// <param name="autoSendConnectionRequest">Setting to true to automatically send connection request to the first browsed peer</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_StartBrowsing(string sessionId, bool autoSendConnectionRequest);

/// <summary>
/// Stop advertising.
/// </summary>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_StopAdvertising();

/// <summary>
/// Stop browsing.
/// </summary>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_StopBrowsing();

/// <summary>
/// Shutdown and deinitialize the MPCSession.
/// </summary>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_Shutdown();

/// <summary>
Expand All @@ -148,21 +150,21 @@ private static extern void MPC_Initialize(string nickname,
/// <param name="data">The raw data</param>
/// <param name="length">The length of the data</param>
/// <param name="reliable">Whether to use realiable way to send the data</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_SendData(int transportID, byte[] data, int length, bool reliable);

/// <summary>
/// Send connection request to a specific browsed host.
/// </summary>
/// <param name="nearbyHostKey">The key of the host in the dict</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_SendConnectionRequest(int nearbyHostKey);

/// <summary>
/// Approve the connection request sent by a specific client.
/// </summary>
/// <param name="connectionRequestKey">The key of the connection request in the dict</param>
[DllImport("__Internal")]
[DllImport(IMPORT_LIBRARY)]
private static extern void MPC_ApproveConnectionRequest(int connectionRequestKey);

/// <summary>
Expand Down Expand Up @@ -409,25 +411,23 @@ public override void DisconnectRemoteClient(ulong transportId)

public override void Shutdown()
{
if (IsRuntime)
{
MPC_Shutdown();
// Reset variables
_pendingConnectionRequestDict.Clear();
_nearbyHostDict.Clear();
_isAdvertising = false;
_isBrowsing = false;
}
MPC_Shutdown();
// Reset variables
_pendingConnectionRequestDict.Clear();
_nearbyHostDict.Clear();
_isAdvertising = false;
_isBrowsing = false;
}

/// <summary>
/// Start advertising.
/// </summary>
public void StartAdvertising()
{
if (IsRuntime && !_isAdvertising)
if (!_isAdvertising)
{
_pendingConnectionRequestDict.Clear();
Debug.Log("Start advertising");
MPC_StartAdvertising(SessionId, AutoApproveConnectionRequest);
_isAdvertising = true;
}
Expand All @@ -438,7 +438,7 @@ public void StartAdvertising()
/// </summary>
public void StopAdvertising()
{
if (IsRuntime && _isAdvertising)
if (_isAdvertising)
{
MPC_StopAdvertising();
_isAdvertising = false;
Expand All @@ -451,7 +451,7 @@ public void StopAdvertising()
/// </summary>
public void StartBrowsing()
{
if (IsRuntime && !_isBrowsing)
if (!_isBrowsing)
{
_nearbyHostDict.Clear();
MPC_StartBrowsing(SessionId, AutoSendConnectionRequest);
Expand All @@ -464,7 +464,7 @@ public void StartBrowsing()
/// </summary>
public void StopBrowsing()
{
if (IsRuntime && _isBrowsing)
if (_isBrowsing)
{
MPC_StopBrowsing();
_isBrowsing = false;
Expand All @@ -474,18 +474,12 @@ public void StopBrowsing()

public void SendConnectionRequest(int nearbyHostKey)
{
if (IsRuntime)
{
MPC_SendConnectionRequest(nearbyHostKey);
}
MPC_SendConnectionRequest(nearbyHostKey);
}

public void ApproveConnectionRequest(int connectionRequestKey)
{
if (IsRuntime)
{
MPC_ApproveConnectionRequest(connectionRequestKey);
}
MPC_ApproveConnectionRequest(connectionRequestKey);
}
}
}
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Runtime/Plugins/visionOS.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Loading

0 comments on commit 23e44ef

Please sign in to comment.