Skip to content

Commit 98b8b8d

Browse files
NoelStephensUnityLarah Armstrong
and
Larah Armstrong
authored
update (#861)
adding some additional documentation on setting alternate player prefabs within the connection approval process. Co-authored-by: Larah Armstrong <[email protected]>
1 parent d50ae5e commit 98b8b8d

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

docs/basics/connection-approval.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,72 @@ The connection data is not encrypted or authenticated.
9898
:::important
9999
A man in the middle attack can be done. It is strongly suggested to not send authentication tokens such as steam tickets or user passwords over connection approval.
100100
:::
101+
102+
## Changing the Player Prefab
103+
There might be times when you want to specify an alternate player prefab to use for a player connecting. The connection approval process provides you with the ability to accomplish this task.
104+
### Step 1: Modify/Create an In-Scene Placed Connection Approval Component
105+
```csharp
106+
public class ClientConnectionHandler : NetworkBehaviour
107+
{
108+
public List<uint> AlternatePlayerPrefabs;
109+
110+
public void SetClientPlayerPrefab(int index)
111+
{
112+
if (index > AlternatePlayerPrefabs.Count)
113+
{
114+
Debug.LogError($"Trying to assign player prefab index of {index} when there are onlky {AlternatePlayerPrefabs.Count} entries!");
115+
return;
116+
}
117+
if (NetworkManager.IsListening || IsSpawned)
118+
{
119+
Debug.LogError("This needs to be set this prior to connecting!");
120+
return;
121+
}
122+
NetworkManager.NetworkConfig.ConnectionData = System.BitConverter.GetBytes(index);
123+
}
124+
125+
public override void OnNetworkSpawn()
126+
{
127+
if (IsServer)
128+
{
129+
NetworkManager.ConnectionApprovalCallback = ConnectionApprovalCallback;
130+
}
131+
}
132+
133+
private void ConnectionApprovalCallback(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
134+
{
135+
var playerPrefabIndex = System.BitConverter.ToInt32(request.Payload);
136+
if (AlternatePlayerPrefabs.Count < playerPrefabIndex)
137+
{
138+
response.PlayerPrefabHash = AlternatePlayerPrefabs[playerPrefabIndex];
139+
}
140+
else
141+
{
142+
Debug.LogError($"Client provided player prefab index of {playerPrefabIndex} when there are onlky {AlternatePlayerPrefabs.Count} entries!");
143+
return;
144+
}
145+
// Continue filling out the response
146+
}
147+
}
148+
149+
```
150+
In the above example, we created a list of unsigned integers to store our alternate player prefab GlobalObjectIdHash values (`AlternatePlayerPrefabs`). For example purposes, we added a public method that a client could invoke to set their selected player prefab's index that is relative to `AlternatePlayerPrefabs` (you could do this in some other component). The general idea for this approach is that the client provides the server with the alternate player prefab index that the player whishes to use.
151+
152+
The server assigns the `ConnectionApprovalCallback` when it spawns the in-scene placed NetworkObject that the `ClientConnectionHandler` is attached to. When a connection request is handled, the server grabs the alternate player prefab index from the request's Payload field and then obtains the GlobalObjectIdHash value from the `AlternatePlayerPrefabs` list and assigns that to the `response.PlayerPrefabHash`.
153+
154+
### Step 2: Copy the Alternate Player Prefab's GlobalObjectIdHash Value
155+
![Copy-GlobalObjectIdHash](images/CopyGlobalObjectIdHash.png)
156+
In order to populate the `AlternatePlayerPrefabs` list:
157+
- Open the scene containing the in-scene placed `NetworkObject` that the `ConnectionApprovalCallback` is attached to.
158+
- Find each alternate player prefab you wish to add to the list, select the prefab (but don't open it), and copy the GlobalObjectIdHash value by right-clicking and selecting "copy".
159+
- Paste the copied GlobalObjectIdHash value into a new list item entry in the `AlternatePlayerPrefabs` list.
160+
161+
### Step 3: Assign Client's Selected Player Prefab Index
162+
This part is really up to your project's design. We did include a method that could be invoked by the client, but that also requires the client to have that scene loaded. You could choose to have a ScriptableObject that contains the list of alternate player prefab GlobalObjectIdHash values and share that between components (this would require you to change the `AlternatePlayerPrefabs` to a reference of the `ScriptableObject`). The general idea is to have the client populate the NetworkConfig.ConnectionData prior to starting.
163+
164+
:::tip
165+
An alternate way to handle this is by using a generic player prefab that is used as the parent to the actual player's character and allowing the player to select their player once they are connected. This would involve dynamically spawning the player's selected character with the client as the owner and parenting that under the player's generic player prefab instance.<br />
166+
Suggested Reading: <br />
167+
[NetworkObject Parenting](../advanced-topics/networkobject-parenting.md)<br />
168+
[Session Management](../advanced-topics/session-management.md)<br />
169+
:::
34.8 KB
Loading

0 commit comments

Comments
 (0)