221 lines
7.6 KiB
C#
221 lines
7.6 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
[RequireComponent(typeof(CharacterController))]
|
|
public class BlobController : MonoBehaviour
|
|
{
|
|
private Transform playerCamera;
|
|
|
|
[Header("Movement Speeds")]
|
|
[SerializeField] private float walkSpeed = 5f;
|
|
[SerializeField] private float sprintSpeed = 9f;
|
|
[SerializeField] private float acceleration = 10f;
|
|
[SerializeField] private float deceleration = 15f;
|
|
|
|
[Header("Jump & Gravity")]
|
|
[SerializeField] private float jumpHeight = 1.5f;
|
|
[SerializeField] private float gravity = -20f;
|
|
[SerializeField] private float groundedGravity = -2f;
|
|
|
|
[Header("Camera Settings (3rd Person)")]
|
|
[SerializeField] private float cameraDistance = 5f;
|
|
[SerializeField] private float cameraHeightOffset = 1.5f;
|
|
[SerializeField] private float cameraSmoothSpeed = 15f;
|
|
[SerializeField] private float lookSensitivity = 0.2f;
|
|
[SerializeField] private float minPitch = -20f;
|
|
[SerializeField] private float maxPitch = 60f;
|
|
|
|
[Header("Input Actions")]
|
|
[SerializeField] private InputActionReference moveAction;
|
|
[SerializeField] private InputActionReference sprintAction;
|
|
[SerializeField] private InputActionReference jumpAction;
|
|
[SerializeField] private InputActionReference lookAction;
|
|
|
|
[Header("Shader / Material")]
|
|
[Tooltip("Laissez vide pour chercher automatiquement le Renderer sur ce GameObject ou ses enfants.")]
|
|
[SerializeField] private Renderer blobRenderer;
|
|
[Tooltip("Vitesse d'interpolation des paramètres _Moving et _Jumping.")]
|
|
[SerializeField] private float shaderTransitionSpeed = 5f;
|
|
|
|
private Material blobMaterial;
|
|
private readonly int movingPropertyID = Shader.PropertyToID("_Moving");
|
|
private readonly int jumpingPropertyID = Shader.PropertyToID("_Jumping");
|
|
|
|
private CharacterController controller;
|
|
private Vector3 currentVelocity;
|
|
private float verticalVelocity;
|
|
private bool isGrounded;
|
|
|
|
// Valeurs pour le shader
|
|
private float currentMovingValue = 0f;
|
|
private float currentJumpingValue = 0f;
|
|
|
|
// Variables de contrôle de la caméra
|
|
private float yaw = 0f;
|
|
private float pitch = 15f;
|
|
private Vector3 smoothedTargetFocusPoint;
|
|
private bool isCameraInitialized = false;
|
|
|
|
private void Awake()
|
|
{
|
|
controller = GetComponent<CharacterController>();
|
|
|
|
if (Camera.main != null)
|
|
{
|
|
playerCamera = Camera.main.transform;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("Aucune 'Main Camera' n'a été trouvée dans la scène !");
|
|
}
|
|
|
|
if (blobRenderer == null)
|
|
{
|
|
blobRenderer = GetComponentInChildren<Renderer>();
|
|
}
|
|
|
|
if (blobRenderer != null)
|
|
{
|
|
blobMaterial = blobRenderer.material;
|
|
}
|
|
|
|
// Verrouillage et masquage du curseur de la souris au démarrage
|
|
Cursor.lockState = CursorLockMode.Locked;
|
|
Cursor.visible = false;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (moveAction != null) moveAction.action.Enable();
|
|
if (sprintAction != null) sprintAction.action.Enable();
|
|
if (jumpAction != null) jumpAction.action.Enable();
|
|
if (lookAction != null) lookAction.action.Enable();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (moveAction != null) moveAction.action.Disable();
|
|
if (sprintAction != null) sprintAction.action.Disable();
|
|
if (jumpAction != null) jumpAction.action.Disable();
|
|
if (lookAction != null) lookAction.action.Disable();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
HandleGroundCheck();
|
|
HandleGravity();
|
|
HandleMovement();
|
|
UpdateShaderParameters();
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
HandleCamera();
|
|
}
|
|
|
|
private void HandleGroundCheck()
|
|
{
|
|
isGrounded = controller.isGrounded;
|
|
if (isGrounded && verticalVelocity < 0.0f)
|
|
{
|
|
verticalVelocity = groundedGravity;
|
|
}
|
|
}
|
|
|
|
private void HandleGravity()
|
|
{
|
|
if (isGrounded && jumpAction != null && jumpAction.action.triggered)
|
|
{
|
|
verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
|
}
|
|
|
|
verticalVelocity += gravity * Time.deltaTime;
|
|
}
|
|
|
|
private void HandleMovement()
|
|
{
|
|
Vector2 inputVector = moveAction != null ? moveAction.action.ReadValue<Vector2>() : Vector2.zero;
|
|
|
|
if (playerCamera == null && Camera.main != null)
|
|
{
|
|
playerCamera = Camera.main.transform;
|
|
}
|
|
|
|
Vector3 forward = playerCamera ? playerCamera.forward : Vector3.forward;
|
|
Vector3 right = playerCamera ? playerCamera.right : Vector3.right;
|
|
|
|
forward.y = 0f;
|
|
right.y = 0f;
|
|
forward.Normalize();
|
|
right.Normalize();
|
|
|
|
Vector3 targetDirection = (forward * inputVector.y + right * inputVector.x).normalized;
|
|
|
|
bool isSprinting = sprintAction != null && sprintAction.action.IsPressed();
|
|
float targetSpeed = isSprinting ? sprintSpeed : walkSpeed;
|
|
|
|
if (inputVector.sqrMagnitude == 0f)
|
|
{
|
|
targetSpeed = 0f;
|
|
}
|
|
|
|
float currentAccel = (inputVector.sqrMagnitude > 0f) ? acceleration : deceleration;
|
|
Vector3 targetVelocity3D = targetDirection * targetSpeed;
|
|
|
|
currentVelocity.x = Mathf.MoveTowards(currentVelocity.x, targetVelocity3D.x, currentAccel * Time.deltaTime);
|
|
currentVelocity.z = Mathf.MoveTowards(currentVelocity.z, targetVelocity3D.z, currentAccel * Time.deltaTime);
|
|
|
|
Vector3 finalMovement = new Vector3(currentVelocity.x, verticalVelocity, currentVelocity.z);
|
|
controller.Move(finalMovement * Time.deltaTime);
|
|
|
|
if (targetDirection != Vector3.zero)
|
|
{
|
|
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 15f * Time.deltaTime);
|
|
}
|
|
}
|
|
|
|
private void HandleCamera()
|
|
{
|
|
if (playerCamera == null) return;
|
|
|
|
Vector2 lookInput = lookAction != null ? lookAction.action.ReadValue<Vector2>() : Vector2.zero;
|
|
yaw += lookInput.x * lookSensitivity;
|
|
pitch -= lookInput.y * lookSensitivity;
|
|
pitch = Mathf.Clamp(pitch, minPitch, maxPitch);
|
|
|
|
Vector3 rawTargetFocusPoint = transform.position + Vector3.up * cameraHeightOffset;
|
|
|
|
if (!isCameraInitialized)
|
|
{
|
|
smoothedTargetFocusPoint = rawTargetFocusPoint;
|
|
isCameraInitialized = true;
|
|
}
|
|
else
|
|
{
|
|
smoothedTargetFocusPoint = Vector3.Lerp(smoothedTargetFocusPoint, rawTargetFocusPoint, cameraSmoothSpeed * Time.deltaTime);
|
|
}
|
|
|
|
Quaternion rotation = Quaternion.Euler(pitch, yaw, 0f);
|
|
Vector3 finalCameraPosition = smoothedTargetFocusPoint - (rotation * Vector3.forward * cameraDistance);
|
|
|
|
playerCamera.position = finalCameraPosition;
|
|
playerCamera.rotation = rotation;
|
|
}
|
|
|
|
private void UpdateShaderParameters()
|
|
{
|
|
if (blobMaterial == null) return;
|
|
|
|
Vector3 horizontalVelocity = new Vector3(currentVelocity.x, 0f, currentVelocity.z);
|
|
float currentSpeed = horizontalVelocity.magnitude;
|
|
float targetMovingValue = walkSpeed > 0.001f ? currentSpeed / walkSpeed : 0f;
|
|
|
|
currentMovingValue = Mathf.MoveTowards(currentMovingValue, targetMovingValue, shaderTransitionSpeed * Time.deltaTime);
|
|
blobMaterial.SetFloat(movingPropertyID, currentMovingValue);
|
|
|
|
float targetJumpingValue = isGrounded ? 0f : 1f;
|
|
currentJumpingValue = Mathf.MoveTowards(currentJumpingValue, targetJumpingValue, shaderTransitionSpeed * Time.deltaTime);
|
|
blobMaterial.SetFloat(jumpingPropertyID, currentJumpingValue);
|
|
}
|
|
} |