feat: Blob

This commit is contained in:
2026-09-14 15:04:45 +02:00
parent 2b3ff30aeb
commit 60d0a81f3c
9 changed files with 7248 additions and 1 deletions

View File

@@ -0,0 +1,221 @@
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);
}
}