Newer
Older
Simple-Multiplayer-Unity3D / Assets / Scripts / PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using TMPro;
using Multiplayer.Network;

public class PlayerController : MonoBehaviour
{
    //Player Movement
    private float horizontalAxis, verticalAxis;
    [SerializeField] private float speed = 5f;

    private GameClient client;

    //Components
    private Rigidbody rb;
    [SerializeField] private Animator animator;
    [SerializeField] private Transform cameraTransform;

    //Player Information
    public PlayerData playerData;
    [SerializeField] private string name;

    //DisplayPlayerWorldUI
    [SerializeField] private TextMeshPro tmp;
    private float sendTimer = 0f;
    public float sendRate = 0.1f; // 10 times per second

    [Header("Mouse Look Settings")]
    [SerializeField] private float mouseSensitivity = 100f;
    [SerializeField] private bool invertY = false;
    private float xRotation = 0f;
    private float mouseX;
    private float mouseY;
    private float lastSentYRotation;

    private void Awake()
    {
        rb = gameObject.GetComponent<Rigidbody>();
        playerData = new PlayerData(name, transform.position, transform.localRotation);
    }

    // Start is called before the first frame update
    void Start()
    {
        client = GameClient.Instance;
        tmp.text = playerData.username;
        name = playerData.username;
    }

    // Update is called once per frame
    void Update()
    {
        // Get raw input
        horizontalAxis = Input.GetAxis("Horizontal");
        verticalAxis = Input.GetAxis("Vertical");

        // Get mouse input (remove Time.deltaTime from here)
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;

        // Apply Time.deltaTime just once when rotating
        mouseX *= Time.deltaTime;
        mouseY *= Time.deltaTime;

        // Player rotates left/right (Y-axis)
        transform.Rotate(Vector3.up * mouseX);

        // Camera rotates up/down (X-axis)
        xRotation += (invertY ? 1 : -1) * mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        cameraTransform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

        if (IsMoving())
        {
            sendTimer += Time.deltaTime;
            if (sendTimer >= sendRate)
            {
                playerData.position = transform.position;
                playerData.rotation = Quaternion.Euler(0, transform.eulerAngles.y, 0);
                client.SendNetworkMessage(NetworkCommand.PlayerMove, playerData);
                sendTimer = 0f;
            }
        }
    }


    void FixedUpdate()
    {
        // Get movement input direction
        Vector3 moveInput = new Vector3(horizontalAxis, 0, verticalAxis).normalized;

        // Calculate movement direction relative to player's rotation
        Vector3 moveDirection = transform.forward * moveInput.z + transform.right * moveInput.x;

        // Apply movement
        rb.velocity = new Vector3(moveDirection.x * speed, rb.velocity.y, moveDirection.z * speed);
    }


    private bool IsMoving()
    {
        bool positionMoving = Mathf.Abs(horizontalAxis) > 0.01f ||
                             Mathf.Abs(verticalAxis) > 0.01f;

        bool rotationChanged = Mathf.Abs(transform.eulerAngles.y - lastSentYRotation) > 1f;

        if (positionMoving || rotationChanged ||
            Mathf.Abs(mouseY) > 0.01f ||
            Mathf.Abs(mouseX) > 0.01f)
        {
            lastSentYRotation = transform.eulerAngles.y;
            return true;
        }
        return false;
    }
}