2017-05-09 16:15:21 +02:00
|
|
|
|
using System;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.Networking;
|
2017-05-09 18:42:28 +02:00
|
|
|
|
using Cyber.Networking.Clientside;
|
2017-05-08 23:03:02 +02:00
|
|
|
|
|
2017-05-10 15:05:02 +02:00
|
|
|
|
namespace Cyber.Entities.SyncBases {
|
2017-05-08 23:03:02 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A syncable component that all characters have. Controls the character's subsystems.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Character : SyncBase {
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// How fast the player should move in Unity's spatial units per second.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float MovementSpeed = 5.0f;
|
|
|
|
|
|
2017-05-10 17:37:58 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The interaction distance of this player.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float InteractionDistance = 2.0f;
|
|
|
|
|
|
2017-05-08 23:03:02 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The character controller, used to move the character. Handles collisions.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public CharacterController CharacterController;
|
|
|
|
|
|
2017-05-09 12:11:36 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The head transform for looking around.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Transform Head;
|
|
|
|
|
|
2017-05-08 23:03:02 +02:00
|
|
|
|
private Vector3 MovementDirection = new Vector3();
|
2017-05-09 18:42:28 +02:00
|
|
|
|
private Vector3 ServerPosition = new Vector3();
|
|
|
|
|
private bool ServerPositionShouldLerpSync = false;
|
2017-05-11 21:19:37 +02:00
|
|
|
|
private Vector3 ServerRotation = new Vector3();
|
|
|
|
|
private bool ServerRotationShouldLerpSync = false;
|
2017-05-08 23:03:02 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Moves the character in the given direction.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Direction">Movement direction.</param>
|
|
|
|
|
public void Move(Vector3 Direction) {
|
|
|
|
|
if (!Direction.Equals(MovementDirection)) {
|
|
|
|
|
MovementDirection = Direction.normalized;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Stops the player from moving.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Stop() {
|
|
|
|
|
if (Moving()) {
|
|
|
|
|
MovementDirection = new Vector3();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-09 12:11:36 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets the character's rotation.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="EulerAngles">Rotation in euler angles.</param>
|
|
|
|
|
public void SetRotation(Vector3 EulerAngles) {
|
2017-05-09 12:30:56 +02:00
|
|
|
|
Vector3 HeadRot = Head.localEulerAngles;
|
|
|
|
|
HeadRot.x = EulerAngles.x;
|
|
|
|
|
HeadRot.z = EulerAngles.z;
|
|
|
|
|
Head.localEulerAngles = HeadRot;
|
|
|
|
|
|
|
|
|
|
Vector3 BodyRot = transform.localEulerAngles;
|
|
|
|
|
BodyRot.y = EulerAngles.y;
|
|
|
|
|
transform.localEulerAngles = BodyRot;
|
2017-05-09 12:11:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-10 17:37:58 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets the position of this character.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Position">Position.</param>
|
|
|
|
|
public void SetPosition(Vector3 Position) {
|
|
|
|
|
transform.position = Position;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-08 23:03:02 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether the player is moving or not.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool Moving() {
|
|
|
|
|
return MovementDirection.sqrMagnitude != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-11 21:00:52 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the current movement direction;
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The Movement Direction Vector3</returns>
|
|
|
|
|
public Vector3 GetMovementDirection() {
|
|
|
|
|
return MovementDirection;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-09 12:30:56 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The character's rotation. Intended to be given as an input to
|
|
|
|
|
/// <see cref="SetRotation"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The rotation.</returns>
|
|
|
|
|
public Vector3 GetRotation() {
|
2017-05-09 12:32:39 +02:00
|
|
|
|
return new Vector3(Head.localEulerAngles.x,
|
2017-05-09 12:30:56 +02:00
|
|
|
|
transform.localEulerAngles.y, Head.localEulerAngles.z);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-10 17:37:58 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the position of this character.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The position.</returns>
|
|
|
|
|
public Vector3 GetPosition() {
|
|
|
|
|
return transform.position;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-09 16:15:21 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the Sync Handletype for Character, which doesn't require hash differences and syncs every tick.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public override SyncHandletype GetSyncHandletype() {
|
|
|
|
|
return new SyncHandletype(false, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Deserializes the character.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="reader"></param>
|
|
|
|
|
public override void Deserialize(NetworkReader reader) {
|
2017-05-09 18:42:28 +02:00
|
|
|
|
ServerPosition = reader.ReadVector3();
|
2017-05-09 18:06:50 +02:00
|
|
|
|
Vector3 ServerMovementDirection = reader.ReadVector3();
|
2017-05-11 21:19:37 +02:00
|
|
|
|
ServerRotation = reader.ReadVector3();
|
2017-05-09 18:06:50 +02:00
|
|
|
|
|
2017-05-10 17:37:58 +02:00
|
|
|
|
float Drift = (ServerPosition - GetPosition()).magnitude;
|
2017-05-09 18:42:28 +02:00
|
|
|
|
|
|
|
|
|
// Update position if this is the local player
|
2017-05-10 17:37:58 +02:00
|
|
|
|
Character LocalCharacter = Client.GetConnectedPlayer().Character;
|
|
|
|
|
if (Drift > MovementSpeed * 0.5f && LocalCharacter.Equals(this)) {
|
|
|
|
|
SetPosition(ServerPosition);
|
2017-05-09 18:06:50 +02:00
|
|
|
|
MovementDirection = ServerMovementDirection;
|
2017-05-09 17:20:10 +02:00
|
|
|
|
}
|
2017-05-09 18:42:28 +02:00
|
|
|
|
|
2017-05-11 21:19:37 +02:00
|
|
|
|
// Update position and rotation more often (with lerping)
|
|
|
|
|
// if this is not the local player
|
|
|
|
|
ServerRotationShouldLerpSync = !LocalCharacter.Equals(this);
|
|
|
|
|
ServerPositionShouldLerpSync = !LocalCharacter.Equals(this) && Drift > 0.1;
|
2017-05-09 16:15:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Serializes the character.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="writer"></param>
|
|
|
|
|
public override void Serialize(NetworkWriter writer) {
|
2017-05-10 17:37:58 +02:00
|
|
|
|
writer.Write(GetPosition());
|
2017-05-09 17:59:12 +02:00
|
|
|
|
writer.Write(MovementDirection);
|
2017-05-09 16:15:21 +02:00
|
|
|
|
writer.Write(GetRotation());
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-09 18:42:28 +02:00
|
|
|
|
private void Update() {
|
|
|
|
|
if (ServerPositionShouldLerpSync) {
|
2017-05-10 17:37:58 +02:00
|
|
|
|
SetPosition(Vector3.Lerp(GetPosition(), ServerPosition, 10f * Time.deltaTime));
|
2017-05-09 18:42:28 +02:00
|
|
|
|
}
|
2017-05-11 21:19:37 +02:00
|
|
|
|
if (ServerRotationShouldLerpSync) {
|
|
|
|
|
Quaternion ServerRot = Quaternion.Euler(ServerRotation);
|
|
|
|
|
Quaternion LocalRot = Quaternion.Euler(GetRotation());
|
|
|
|
|
Vector3 NewRot = Quaternion.Lerp(LocalRot, ServerRot,
|
|
|
|
|
10f * Time.deltaTime).eulerAngles;
|
|
|
|
|
SetRotation(NewRot);
|
|
|
|
|
}
|
2017-05-09 18:42:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-08 23:03:02 +02:00
|
|
|
|
private void FixedUpdate() {
|
|
|
|
|
CharacterController.Move(MovementDirection * MovementSpeed * Time.fixedDeltaTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|