Skip to content

Commit b51726b

Browse files
authored
Add Guide on How to Add Network-Synced Animations (#88)
* Add Guide on How to Add Network-Synced Animations * Add Clarification that sharing BEE files with passwords is pretty safe * Add clarification on how to host/connect via local or remote servers
1 parent bb2cde7 commit b51726b

4 files changed

Lines changed: 132 additions & 2 deletions

File tree

content/docs/faq.mdx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,16 @@ You can create custom worlds using Unity. Check out the [World Creation Guide](/
5252
We welcome contributions! See the [Contributing Guide](/docs/contributing) for more information on how to get involved.
5353

5454
### What's the difference between core component contributions and add-on contributions?
55-
A: Core components include systems that make up the key features of Basis. Contributions (or modules) include extra features which, while useful, are not required by default. Therefore, contributions may provide features that are outside the scope of the main Basis offering, which may provide value to developers using Basis.
55+
A: Core components include systems that make up the key features of Basis. Contributions (or modules) include extra features which, while useful, are not required by default. Therefore, contributions may provide features that are outside the scope of the main Basis offering, which may provide value to developers using Basis.
56+
57+
### Does sharing Bee Files Compromise Remote Content Hosting Server Credentials?
58+
59+
No! You can share your BEE files with your friends for instance. A BEE file encompasses the Basis asset (even for multiple platforms), excluding the encryption key used to decrypt it. In other words, it is basically a multi-asset-bundle. If you share a BEE file's password, then this allows anyone that has it to be able to access whatever is inside the BEE file (i.e., the specific UGC like props, avatars, worlds).
60+
61+
## How can I connect to a local server from different devices?
62+
63+
There are several options for connecting to a local server from different devices. For instance, you can enable port forwarding on your router. Alternatively, if you prefer not to tinker with your router, you can install [`Tailscale`](https://tailscale.com/download), which is very simple to set up.
64+
65+
## Where can I set up a remote server?
66+
67+
There are a variety of Cloud services you can host your servers in. Examples include: Bunny, DigitalOcean, CloudFlare, AWS, Microsoft Azure, Google Cloud, and more.

content/docs/world/props.mdx

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,122 @@ Note: Both local and remote players can spawn cubes!
189189

190190
<Callout type="info">
191191
Double note: You can access Basis VR via Steam as well. To get an access key, [join the discord](https://discord.gg/v6ve6WT562)!
192-
</Callout>
192+
</Callout>
193+
194+
## Adding Network-Synced Animations
195+
196+
Adding networked animations for props, as well as worlds and avatars, is quite simple as they can be created using the Unity `Animator`.
197+
198+
The example code below shows example code for a network-synced Opticor rifle, and the corresponding Animator state machine and triggers it uses:
199+
200+
```
201+
using UnityEngine;
202+
using System.Collections;
203+
using Basis.Scripts.BasisSdk.Interactions;
204+
using Basis.Scripts.Device_Management.Devices;
205+
using Basis.Network.Core;
206+
using Basis;
207+
208+
[Cilboxable]
209+
public class OpticorShooting : MonoBehaviour
210+
{
211+
private BasisPickupInteractable pickup;
212+
private BasisNetworkShim network;
213+
private Animator animator;
214+
public AudioSource audioSource;
215+
public AudioClip audioClipCharge;
216+
public AudioClip audioClipMisfire;
217+
218+
void Start()
219+
{
220+
this.pickup = GetComponent<BasisPickupInteractable>();
221+
this.pickup.OnInteractStartEvent.AddListener(OnPickup);
222+
this.pickup.OnInteractEndEvent.AddListener(OnDrop);
223+
this.pickup.OnPickupUse.AddListener(OnUse);
224+
this.network = Basis.SafeUtil.MakeNetworkable(this);
225+
this.network.NetworkMessageReceived = OnNetworkMessage;
226+
this.animator = GetComponent<Animator>();
227+
}
228+
229+
public void OnNetworkMessage(ushort PlayerID, byte[] buffer, DeliveryMethod DeliveryMethod)
230+
{
231+
Debug.Log("Opticor: Received network message!, PlayerID: " + PlayerID + ", buffer length: " + buffer.Length + ", DeliveryMethod: " + DeliveryMethod);
232+
if(buffer.Length < 1) return;
233+
if(buffer[0] == 1)
234+
{
235+
//Debug.Log("Opticor: Start the Pew Pew! (networked)");
236+
CheckShoot();
237+
}
238+
else if(buffer[0] == 2)
239+
{
240+
//Debug.Log("Opticor: Stop the Pew Pew! (networked)");
241+
StopShoot();
242+
}
243+
}
244+
245+
private void OnPickup(BasisInput input)
246+
{
247+
//Debug.Log("Opticor: Picked up!");
248+
}
249+
250+
private void OnDrop(BasisInput input)
251+
{
252+
//Debug.Log("Opticor: Dropped!");
253+
}
254+
255+
void OnUse(BasisPickUpUseMode mode)
256+
{
257+
switch (mode)
258+
{
259+
case BasisPickUpUseMode.OnPickUpUseDown:
260+
//Debug.Log("Opticor: Start the Pew Pew! (local)");
261+
this.CheckShoot();
262+
this.network.SendCustomNetworkEvent(new byte[] { 1 }, DeliveryMethod.ReliableSequenced);
263+
break;
264+
case BasisPickUpUseMode.OnPickUpUseUp:
265+
//Debug.Log("Opticor: Stop the Pew Pew! (local)");
266+
this.StopShoot();
267+
this.network.SendCustomNetworkEvent(new byte[] { 2 }, DeliveryMethod.ReliableSequenced);
268+
break;
269+
}
270+
}
271+
272+
private void CheckShoot()
273+
{
274+
animator.SetBool("GunTrigger", true);
275+
if (this.animator.GetCurrentAnimatorStateInfo(0).IsName("Firing") || this.animator.GetCurrentAnimatorStateInfo(0).IsName("Misfire"))
276+
return;
277+
else
278+
CheckIdleState();
279+
280+
void CheckIdleState()
281+
{
282+
if (this.animator.GetCurrentAnimatorStateInfo(0).IsName("Idle Overheated"))
283+
{
284+
this.animator.SetTrigger("GunMisfire");
285+
audioSource.PlayOneShot(audioClipMisfire);
286+
}
287+
else
288+
{
289+
this.animator.SetTrigger("GunShoot");
290+
audioSource.PlayOneShot(audioClipCharge);
291+
}
292+
}
293+
}
294+
295+
private void StopShoot()
296+
{
297+
this.animator.SetBool("GunTrigger", false);
298+
}
299+
}
300+
```
301+
302+
<Callout type="info">
303+
The `BasisNetworkShim` is used to allow Cilbox scripts to have networking functionalities.
304+
</Callout>
305+
306+
![Inspector Window showing button and components](/img/props/7A.png)
307+
308+
![Inspector Window showing button and components](/img/props/7B.png)
309+
310+
You can try out the Opticor example for yourself by downloading its asset package [here](https://drive.google.com/file/d/1C0kOI8tfK4xD6j_Bqys3oSMJpV_OWNPR/view?usp=drive_link).

public/img/props/7A.png

33.6 KB
Loading

public/img/props/7B.png

191 KB
Loading

0 commit comments

Comments
 (0)