Luke Stampfli
4 年前
当前提交
77b59d92
共有 4 个文件被更改,包括 144 次插入 和 131 次删除
-
43Assets/BossRoom/Scripts/Client/ClientCharacter.cs
-
62Assets/BossRoom/Scripts/Client/ClientInput.cs
-
142Assets/BossRoom/Scripts/Server/ServerMovement.cs
-
28Assets/BossRoom/Scripts/Shared/NetworkCharacterState.cs
|
|||
using System; |
|||
using BossRoom.Shared; |
|||
[RequireComponent(typeof(NetworkCharacterState))] |
|||
public class ClientCharacter: NetworkedBehaviour |
|||
namespace BossRoom.Client |
|||
private NetworkCharacterState networkCharacterState; |
|||
[RequireComponent(typeof(NetworkCharacterState))] |
|||
public class ClientCharacter: NetworkedBehaviour |
|||
{ |
|||
private NetworkCharacterState networkCharacterState; |
|||
[SerializeField] |
|||
private Transform clientInterpolatedObject; |
|||
[SerializeField] |
|||
private Transform clientInterpolatedObject; |
|||
public override void NetworkStart() |
|||
{ |
|||
if (!IsClient) |
|||
public override void NetworkStart() |
|||
enabled = false; |
|||
if (!IsClient) |
|||
{ |
|||
enabled = false; |
|||
} |
|||
} |
|||
void Awake() |
|||
{ |
|||
networkCharacterState = GetComponent<NetworkCharacterState>(); |
|||
} |
|||
void Awake() |
|||
{ |
|||
networkCharacterState = GetComponent<NetworkCharacterState>(); |
|||
} |
|||
void Update() |
|||
{ |
|||
// TODO Needs core sdk support. This and rotation should grab the interpolated value of network position based on the last received snapshots.
|
|||
clientInterpolatedObject.position = networkCharacterState.NetworkPosition.Value; |
|||
void Update() |
|||
{ |
|||
// TODO Needs core sdk support. This and rotation should grab the interpolated value of network position based on the last received snapshots.
|
|||
clientInterpolatedObject.position = networkCharacterState.NetworkPosition.Value; |
|||
clientInterpolatedObject.rotation = Quaternion.Euler(0, networkCharacterState.NetworkRotationY.Value, 0); |
|||
clientInterpolatedObject.rotation = Quaternion.Euler(0, networkCharacterState.NetworkRotationY.Value, 0); |
|||
} |
|||
} |
|||
} |
|
|||
using BossRoom.Shared; |
|||
using MLAPI.NetworkedVar; |
|||
[RequireComponent(typeof(NetworkCharacterState))] |
|||
public class ClientInput : NetworkedBehaviour |
|||
namespace BossRoom.Client |
|||
private NetworkCharacterState networkCharacter; |
|||
|
|||
public override void NetworkStart() |
|||
[RequireComponent(typeof(NetworkCharacterState))] |
|||
public class ClientInput : NetworkedBehaviour |
|||
// TODO The entire disabling/enabling is still sketchy and the reason why this has to be a NetworkedBehaviour
|
|||
if (!IsClient) |
|||
private NetworkCharacterState networkCharacter; |
|||
|
|||
public override void NetworkStart() |
|||
enabled = false; |
|||
// TODO The entire disabling/enabling is still sketchy and the reason why this has to be a NetworkedBehaviour
|
|||
if (!IsClient) |
|||
{ |
|||
enabled = false; |
|||
} |
|||
} |
|||
void Awake() |
|||
{ |
|||
networkCharacter = GetComponent<NetworkCharacterState>(); |
|||
enabled = false; |
|||
} |
|||
void Awake() |
|||
{ |
|||
networkCharacter = GetComponent<NetworkCharacterState>(); |
|||
} |
|||
// Update is called once per frame
|
|||
void FixedUpdate() |
|||
{ |
|||
// EDU Multiplayer games poll update in fixed step because server processes game simulation in a fixed step as well
|
|||
// Update is called once per frame
|
|||
void FixedUpdate() |
|||
{ |
|||
// EDU Multiplayer games poll update in fixed step because server processes game simulation in a fixed step as well
|
|||
// TODO can we use new Unity input system which supports fixed update polling? Right now implementation is broken
|
|||
// TODO can we use new Unity input system which supports fixed update polling? Right now implementation is broken
|
|||
// Is mouse button pressed (not checking for down for continuous input)
|
|||
if (Input.GetMouseButton(0)) |
|||
{ |
|||
RaycastHit hit; |
|||
// Is mouse button pressed (not checking for down for continuous input)
|
|||
if (Input.GetMouseButton(0)) |
|||
{ |
|||
RaycastHit hit; |
|||
// TODO Camera.main is horrible in Unity < 2020.2
|
|||
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit)) |
|||
{ |
|||
// TODO Send reliable sequenced
|
|||
// TODO Call syntax is still ugly
|
|||
networkCharacter.InvokeServerRpc(networkCharacter.ServerRpcReceiveMovementInput, hit.point); |
|||
// TODO Camera.main is horrible in Unity < 2020.2
|
|||
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit)) |
|||
{ |
|||
// TODO Send reliable sequenced
|
|||
// TODO Call syntax is still ugly
|
|||
networkCharacter.InvokeServerRpc(networkCharacter.ServerRpcReceiveMovementInput, hit.point, "MLAPI_INTERNAL"); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Linq; |
|||
using BossRoom.Shared; |
|||
public enum MovementState |
|||
{ |
|||
Idle = 0, |
|||
PathFollowing = 1, |
|||
} |
|||
|
|||
[RequireComponent(typeof(NavMeshAgent))] |
|||
[RequireComponent(typeof(NetworkCharacterState))] // TODO decouple this from network character state?
|
|||
public class ServerMovement : NetworkedBehaviour |
|||
namespace BossRoom.Server |
|||
private NavMeshAgent navMeshAgent; |
|||
private NetworkCharacterState networkCharacterState; |
|||
|
|||
private NavMeshPath path; |
|||
private MovementState movementState; |
|||
|
|||
[SerializeField] |
|||
private float movementSpeed; // TODO this should be assigned based on character definition
|
|||
|
|||
public override void NetworkStart() |
|||
public enum MovementState |
|||
if (!IsServer) |
|||
{ |
|||
// Disable server component on clients
|
|||
enabled = false; |
|||
return; |
|||
} |
|||
|
|||
// On the server enable navMeshAgent and initialize
|
|||
navMeshAgent.enabled = true; |
|||
networkCharacterState.OnReceivedClientInput += SetMovementTarget; |
|||
path = new NavMeshPath(); |
|||
Idle = 0, |
|||
PathFollowing = 1, |
|||
private void SetMovementTarget(Vector3 position) |
|||
[RequireComponent(typeof(NavMeshAgent))] |
|||
[RequireComponent(typeof(NetworkCharacterState))] // TODO decouple this from network character state?
|
|||
public class ServerMovement : NetworkedBehaviour |
|||
// Receive a target movement position and calculate the navmesh path for moving towards it.
|
|||
navMeshAgent.CalculatePath(position, path); |
|||
movementState = MovementState.PathFollowing; |
|||
} |
|||
private NavMeshAgent navMeshAgent; |
|||
private NetworkCharacterState networkCharacterState; |
|||
private void Awake() |
|||
{ |
|||
navMeshAgent = GetComponent<NavMeshAgent>(); |
|||
networkCharacterState = GetComponent<NetworkCharacterState>(); |
|||
} |
|||
private NavMeshPath path; |
|||
private MovementState movementState; |
|||
|
|||
[SerializeField] |
|||
private float movementSpeed; // TODO this should be assigned based on character definition
|
|||
private void FixedUpdate() |
|||
{ |
|||
if (movementState == MovementState.PathFollowing) |
|||
public override void NetworkStart() |
|||
Movement(); |
|||
} |
|||
} |
|||
if (!IsServer) |
|||
{ |
|||
// Disable server component on clients
|
|||
enabled = false; |
|||
return; |
|||
} |
|||
private void Movement() |
|||
{ |
|||
var corners = path.corners; // TODO: maybe use non-alloc version
|
|||
// On the server enable navMeshAgent and initialize
|
|||
navMeshAgent.enabled = true; |
|||
networkCharacterState.OnReceivedClientInput += SetMovementTarget; |
|||
path = new NavMeshPath(); |
|||
} |
|||
// If we don't have a movement path stop moving
|
|||
if (!corners.Any()) |
|||
private void SetMovementTarget(Vector3 position) |
|||
movementState = MovementState.Idle; |
|||
return; |
|||
// Receive a target movement position and calculate the navmesh path for moving towards it.
|
|||
navMeshAgent.CalculatePath(position, path); |
|||
movementState = MovementState.PathFollowing; |
|||
var desiredMovementAmount = movementSpeed * Time.fixedDeltaTime; |
|||
private void Awake() |
|||
{ |
|||
navMeshAgent = GetComponent<NavMeshAgent>(); |
|||
networkCharacterState = GetComponent<NetworkCharacterState>(); |
|||
} |
|||
// If there is less distance to move left in the path than our desired amount
|
|||
if (Vector3.SqrMagnitude(corners[corners.Length - 1] - transform.position) < (desiredMovementAmount * desiredMovementAmount)) |
|||
private void FixedUpdate() |
|||
// Set to destination and stop moving
|
|||
transform.position = corners[corners.Length - 1]; |
|||
movementState = MovementState.Idle; |
|||
return; |
|||
if (movementState == MovementState.PathFollowing) |
|||
{ |
|||
Movement(); |
|||
} |
|||
// Get the direction to move along based on the calculated path.
|
|||
var direction = corners.Length > 1 |
|||
? (corners[1] - corners[0]).normalized |
|||
: throw new InvalidOperationException("Navigation path should have a start and end position"); |
|||
private void Movement() |
|||
{ |
|||
var corners = path.corners; // TODO: maybe use non-alloc version
|
|||
|
|||
// If we don't have a movement path stop moving
|
|||
if (!corners.Any()) |
|||
{ |
|||
movementState = MovementState.Idle; |
|||
return; |
|||
} |
|||
|
|||
var desiredMovementAmount = movementSpeed * Time.fixedDeltaTime; |
|||
|
|||
// If there is less distance to move left in the path than our desired amount
|
|||
if (Vector3.SqrMagnitude(corners[corners.Length - 1] - transform.position) < (desiredMovementAmount * desiredMovementAmount)) |
|||
{ |
|||
// Set to destination and stop moving
|
|||
transform.position = corners[corners.Length - 1]; |
|||
movementState = MovementState.Idle; |
|||
return; |
|||
} |
|||
|
|||
// Get the direction to move along based on the calculated path.
|
|||
var direction = corners.Length > 1 |
|||
? (corners[1] - corners[0]).normalized |
|||
: throw new InvalidOperationException("Navigation path should have a start and end position"); |
|||
var movementVector = direction * desiredMovementAmount; |
|||
var movementVector = direction * desiredMovementAmount; |
|||
navMeshAgent.Move(movementVector); |
|||
transform.rotation = Quaternion.LookRotation(movementVector); |
|||
//navMeshAgent.CalculatePath(corners[corners.Length - 1], path);
|
|||
navMeshAgent.Move(movementVector); |
|||
transform.rotation = Quaternion.LookRotation(movementVector); |
|||
//navMeshAgent.CalculatePath(corners[corners.Length - 1], path);
|
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using MLAPI; |
|||
using MLAPI; |
|||
// RPCStateComponent from the GDD
|
|||
public class NetworkCharacterState : NetworkedBehaviour |
|||
|
|||
namespace BossRoom.Shared |
|||
public NetworkedVarVector3 NetworkPosition; |
|||
public NetworkedVarFloat NetworkRotationY; |
|||
// RPCStateComponent from the GDD
|
|||
public class NetworkCharacterState : NetworkedBehaviour |
|||
{ |
|||
public NetworkedVarVector3 NetworkPosition; |
|||
public NetworkedVarFloat NetworkRotationY; |
|||
// TODO Should we use Unity events or c# events?
|
|||
public event Action<Vector3> OnReceivedClientInput; |
|||
// TODO Should we use Unity events or c# events?
|
|||
public event Action<Vector3> OnReceivedClientInput; |
|||
[ServerRPC] |
|||
public void ServerRpcReceiveMovementInput(Vector3 position) |
|||
{ |
|||
// Assumption that RPC is snaphshotted and buffered already here
|
|||
OnReceivedClientInput?.Invoke(position); |
|||
[ServerRPC] |
|||
public void ServerRpcReceiveMovementInput(Vector3 position) |
|||
{ |
|||
// Assumption that RPC is snaphshotted and buffered already here
|
|||
OnReceivedClientInput?.Invoke(position); |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue