HoangMinhNguyen

Player Controller Example

Jul 13th, 2025
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.04 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3.  
  4. public class CharacterController : MonoBehaviour
  5. {
  6.     [Header("Character Settings")]
  7.     public short slot;
  8.     public bool isLocalPlayer = false;
  9.    
  10.     [Header("Movement Settings")]
  11.     public float moveSpeed = 5f;
  12.     public float rotationSpeed = 10f;
  13.    
  14.     [Header("Visual Settings")]
  15.     public GameObject characterModel;
  16.     public GameObject nameTag;
  17.     public TextMesh nameText;
  18.    
  19.     private UnityPositionSync positionSync;
  20.     private Vector3 targetPosition;
  21.     private Vector3 currentVelocity;
  22.     private bool isMoving = false;
  23.    
  24.     // For local player
  25.     private CharacterControllerInput inputController;
  26.    
  27.     // For remote players
  28.     private Vector3 lastInterpolatedPosition;
  29.     private float lastUpdateTime;
  30.    
  31.     void Start()
  32.     {
  33.         // Get position sync component
  34.         positionSync = FindObjectOfType<UnityPositionSync>();
  35.         if (positionSync == null)
  36.         {
  37.             Debug.LogError("UnityPositionSync not found in scene!");
  38.             return;
  39.         }
  40.        
  41.         // Setup for local player
  42.         if (isLocalPlayer)
  43.         {
  44.             SetupLocalPlayer();
  45.         }
  46.         else
  47.         {
  48.             SetupRemotePlayer();
  49.         }
  50.        
  51.         // Setup visual elements
  52.         SetupVisuals();
  53.     }
  54.    
  55.     void Update()
  56.     {
  57.         if (positionSync == null) return;
  58.        
  59.         if (isLocalPlayer)
  60.         {
  61.             UpdateLocalPlayer();
  62.         }
  63.         else
  64.         {
  65.             UpdateRemotePlayer();
  66.         }
  67.     }
  68.    
  69.     void SetupLocalPlayer()
  70.     {
  71.         // Add input controller for local player
  72.         inputController = gameObject.AddComponent<CharacterControllerInput>();
  73.         inputController.moveSpeed = moveSpeed;
  74.        
  75.         // Set slot when assigned
  76.         StartCoroutine(WaitForSlotAssignment());
  77.     }
  78.    
  79.     void SetupRemotePlayer()
  80.     {
  81.         // Remote players don't need input
  82.         if (inputController != null)
  83.         {
  84.             Destroy(inputController);
  85.         }
  86.     }
  87.    
  88.     System.Collections.IEnumerator WaitForSlotAssignment()
  89.     {
  90.         while (positionSync.GetMySlot() == -1)
  91.         {
  92.             yield return null;
  93.         }
  94.        
  95.         slot = positionSync.GetMySlot();
  96.         Debug.Log($"Local player assigned to slot: {slot}");
  97.     }
  98.    
  99.     void SetupVisuals()
  100.     {
  101.         // Setup name tag
  102.         if (nameTag != null && nameText != null)
  103.         {
  104.             nameText.text = $"Player {slot}";
  105.            
  106.             // Different color for local player
  107.             if (isLocalPlayer)
  108.             {
  109.                 nameText.color = Color.green;
  110.             }
  111.             else
  112.             {
  113.                 nameText.color = Color.white;
  114.             }
  115.         }
  116.        
  117.         // Setup character model
  118.         if (characterModel != null)
  119.         {
  120.             // Different material for local player
  121.             Renderer renderer = characterModel.GetComponent<Renderer>();
  122.             if (renderer != null && isLocalPlayer)
  123.             {
  124.                 Material localPlayerMaterial = new Material(renderer.material);
  125.                 localPlayerMaterial.color = Color.cyan;
  126.                 renderer.material = localPlayerMaterial;
  127.             }
  128.         }
  129.     }
  130.    
  131.     void UpdateLocalPlayer()
  132.     {
  133.         // Local player movement is handled by CharacterControllerInput
  134.         // Position sync will automatically send updates
  135.        
  136.         // Update visual feedback
  137.         UpdateMovementVisuals();
  138.     }
  139.    
  140.     void UpdateRemotePlayer()
  141.     {
  142.         // Get interpolated position from position sync
  143.         Dictionary<short, Vector3> positions = positionSync.GetOtherPlayerPositions();
  144.         Dictionary<short, Vector3> velocities = positionSync.GetOtherPlayerVelocities();
  145.        
  146.         if (positions.ContainsKey(slot))
  147.         {
  148.             Vector3 interpolatedPosition = positions[slot];
  149.             Vector3 interpolatedVelocity = velocities.ContainsKey(slot) ? velocities[slot] : Vector3.zero;
  150.            
  151.             // Smooth movement to interpolated position
  152.             float smoothTime = 0.1f; // Adjust for responsiveness
  153.             transform.position = Vector3.SmoothDamp(transform.position, interpolatedPosition, ref currentVelocity, smoothTime);
  154.            
  155.             // Update movement state
  156.             isMoving = interpolatedVelocity.magnitude > 0.1f;
  157.            
  158.             // Rotate character towards movement direction
  159.             if (isMoving)
  160.             {
  161.                 Vector3 moveDirection = interpolatedVelocity.normalized;
  162.                 if (moveDirection != Vector3.zero)
  163.                 {
  164.                     Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
  165.                     transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
  166.                 }
  167.             }
  168.            
  169.             // Update visual feedback
  170.             UpdateMovementVisuals();
  171.            
  172.             lastInterpolatedPosition = interpolatedPosition;
  173.             lastUpdateTime = Time.time;
  174.         }
  175.         else
  176.         {
  177.             // Player not found, maybe disconnected
  178.             isMoving = false;
  179.             UpdateMovementVisuals();
  180.         }
  181.     }
  182.    
  183.     void UpdateMovementVisuals()
  184.     {
  185.         // Update character model animations
  186.         Animator animator = GetComponent<Animator>();
  187.         if (animator != null)
  188.         {
  189.             animator.SetBool("IsMoving", isMoving);
  190.             animator.SetFloat("MoveSpeed", currentVelocity.magnitude);
  191.         }
  192.        
  193.         // Update particle effects
  194.         ParticleSystem moveParticles = GetComponentInChildren<ParticleSystem>();
  195.         if (moveParticles != null)
  196.         {
  197.             if (isMoving && !moveParticles.isPlaying)
  198.             {
  199.                 moveParticles.Play();
  200.             }
  201.             else if (!isMoving && moveParticles.isPlaying)
  202.             {
  203.                 moveParticles.Stop();
  204.             }
  205.         }
  206.        
  207.         // Update name tag position
  208.         if (nameTag != null)
  209.         {
  210.             nameTag.transform.position = transform.position + Vector3.up * 2f;
  211.             nameTag.transform.LookAt(Camera.main.transform);
  212.         }
  213.     }
  214.    
  215.     // Public methods for external access
  216.     public short GetSlot()
  217.     {
  218.         return slot;
  219.     }
  220.    
  221.     public bool IsMoving()
  222.     {
  223.         return isMoving;
  224.     }
  225.    
  226.     public Vector3 GetCurrentVelocity()
  227.     {
  228.         return currentVelocity;
  229.     }
  230.    
  231.     public bool IsLocalPlayer()
  232.     {
  233.         return isLocalPlayer;
  234.     }
  235. }
  236.  
  237. // Input controller for local player
  238. public class CharacterControllerInput : MonoBehaviour
  239. {
  240.     public float moveSpeed = 5f;
  241.     private CharacterController characterController;
  242.     private UnityPositionSync positionSync;
  243.    
  244.     void Start()
  245.     {
  246.         characterController = GetComponent<CharacterController>();
  247.         positionSync = FindObjectOfType<UnityPositionSync>();
  248.     }
  249.    
  250.     void Update()
  251.     {
  252.         if (characterController == null || positionSync == null) return;
  253.        
  254.         // Handle input
  255.         float horizontal = Input.GetAxis("Horizontal");
  256.         float vertical = Input.GetAxis("Vertical");
  257.        
  258.         Vector3 movement = new Vector3(horizontal, 0, vertical).normalized;
  259.        
  260.         if (movement.magnitude > 0.1f)
  261.         {
  262.             // Move character
  263.             transform.Translate(movement * moveSpeed * Time.deltaTime, Space.World);
  264.            
  265.             // Rotate character towards movement direction
  266.             Quaternion targetRotation = Quaternion.LookRotation(movement);
  267.             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 10f * Time.deltaTime);
  268.         }
  269.        
  270.         // Handle sprint
  271.         if (Input.GetKey(KeyCode.LeftShift))
  272.         {
  273.             moveSpeed = 8f;
  274.         }
  275.         else
  276.         {
  277.             moveSpeed = 5f;
  278.         }
  279.     }
  280. }
Advertisement
Add Comment
Please, Sign In to add comment