Forum Discussion
ysun60
2 years agoHonored Guest
How do I integrate teleportation prefab with Netcode
I'm doing a multiplayer project using Unity Netcode. I'm using the LocomotionControllerInteractorGroup prefab to handle the teleportation, and there is a script from the SDK called PlayerLocomotor that changes the player position. Based on the Netcode tutorial, I should handle movement through NetworkBehavior rather than MonoBehavior, so I duplicated the script and changed it to a NetworkBehavior script, but the modified one is not functioning at all. I attached the modified script below. Could someone give me some hits about how to integrate the locomotion prefab into the NetworkBehavior, please?
using System;
using System.Collections;
using System.Collections.Generic;
using Oculus.Interaction;
using Oculus.Interaction.Locomotion;
using Unity.Netcode;
using UnityEngine;
public class RPCPlayer : NetworkBehaviour, ILocomotionEventHandler
{
// Start is called before the first frame update
[SerializeField]
private Transform _playerOrigin;
[SerializeField]
private Transform _playerHead;
private Action<LocomotionEvent, Pose> _whenLocomotionEventHandled = delegate { };
public event Action<LocomotionEvent, Pose> WhenLocomotionEventHandled
{
add
{
_whenLocomotionEventHandled += value;
}
remove
{
_whenLocomotionEventHandled -= value;
}
}
protected bool _started;
private Queue<LocomotionEvent> _deferredEvent = new Queue<LocomotionEvent>();
protected virtual void Start()
{
this.BeginStart(ref _started);
this.AssertField(_playerOrigin, nameof(_playerOrigin));
this.AssertField(_playerHead, nameof(_playerHead));
this.EndStart(ref _started);
}
private void OnEnable()
{
if (_started)
{
//this.RegisterEndOfFrameCallback(MovePlayer);
//It's not available to the NetworkBehavior
MovePlayer();
}
}
private void OnDisable()
{
if (_started)
{
_deferredEvent.Clear();
//this.UnregisterEndOfFrameCallback();
}
}
public void HandleLocomotionEvent(LocomotionEvent locomotionEvent)
{
_deferredEvent.Enqueue(locomotionEvent);
}
//[ServerRpc (RequireOwnership = false)]
private void MovePlayer()
{
while (_deferredEvent.Count > 0)
{
LocomotionEvent locomotionEvent = _deferredEvent.Dequeue();
Pose originalPose = _playerOrigin.GetPose();
MovePlayer(locomotionEvent.Pose.position, locomotionEvent.Translation);
RotatePlayer(locomotionEvent.Pose.rotation, locomotionEvent.Rotation);
Pose delta = PoseUtils.Delta(originalPose, _playerOrigin.GetPose());
_whenLocomotionEventHandled.Invoke(locomotionEvent, delta);
}
}
private void MovePlayer(Vector3 targetPosition, LocomotionEvent.TranslationType translationMode)
{
if (translationMode == LocomotionEvent.TranslationType.None)
{
return;
}
if (translationMode == LocomotionEvent.TranslationType.Absolute)
{
Vector3 positionOffset = _playerOrigin.position - _playerHead.position;
positionOffset.y = 0f;
_playerOrigin.position = targetPosition + positionOffset;
}
else if (translationMode == LocomotionEvent.TranslationType.AbsoluteEyeLevel)
{
Vector3 positionOffset = _playerOrigin.position - _playerHead.position;
_playerOrigin.position = targetPosition + positionOffset;
}
else if (translationMode == LocomotionEvent.TranslationType.Relative)
{
_playerOrigin.position = _playerOrigin.position + targetPosition;
}
else if (translationMode == LocomotionEvent.TranslationType.Velocity)
{
_playerOrigin.position = _playerOrigin.position + targetPosition * Time.deltaTime;
}
}
private void RotatePlayer(Quaternion targetRotation, LocomotionEvent.RotationType rotationMode)
{
if (rotationMode == LocomotionEvent.RotationType.None)
{
return;
}
Vector3 originalHeadPosition = _playerHead.position;
if (rotationMode == LocomotionEvent.RotationType.Absolute)
{
Vector3 headForward = Vector3.ProjectOnPlane(_playerHead.forward, _playerOrigin.up).normalized;
Quaternion headFlatRotation = Quaternion.LookRotation(headForward, _playerOrigin.up);
Quaternion rotationOffset = Quaternion.Inverse(_playerOrigin.rotation) * headFlatRotation;
_playerOrigin.rotation = Quaternion.Inverse(rotationOffset) * targetRotation;
}
else if (rotationMode == LocomotionEvent.RotationType.Relative)
{
_playerOrigin.rotation = targetRotation * _playerOrigin.rotation;
}
else if (rotationMode == LocomotionEvent.RotationType.Velocity)
{
targetRotation.ToAngleAxis(out float angle, out Vector3 axis);
angle *= Time.deltaTime;
_playerOrigin.rotation = Quaternion.AngleAxis(angle, axis) * _playerOrigin.rotation;
}
_playerOrigin.position = _playerOrigin.position + originalHeadPosition - _playerHead.position;
}
#region Inject
public void InjectAllPlayerLocomotor(Transform playerOrigin, Transform playerHead)
{
InjectPlayerOrigin(playerOrigin);
InjectPlayerHead(playerHead);
}
public void InjectPlayerOrigin(Transform playerOrigin)
{
_playerOrigin = playerOrigin;
}
public void InjectPlayerHead(Transform playerHead)
{
_playerHead = playerHead;
}
#endregion
}
1 Reply
Replies have been turned off for this discussion
- OgethelPartner
I don't know either but I also want to know a solution as I would like to not only set up multiplayer but also set up continuous joystick movement and I am being frustrated in a similar way.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 7 months ago