Untitled
unknown
csharp
22 days ago
7.3 kB
2
Indexable
Never
using UnityEngine; public class SonicController : MonoBehaviour { [Header("Movement Variables")] public float acceleration; // How fast Sonic accelerates on the ground public float deceleration; // How fast Sonic slows down when no input is given public float topSpeed; // Maximum speed Sonic can reach while on the ground public float maxSpeed; // Speed Sonic can instantly reach when boosting [Header("Air Movement Variables")] public float airAcceleration; // How fast Sonic accelerates while in the air public float airDeceleration; // How fast Sonic slows down in the air public float airTopSpeed; // Maximum speed Sonic can reach while in the air public float gravity = 9.81f; // Gravity to apply when in the air [Header("Jumping Variables")] public float jumpForce; // Initial force applied when Sonic jumps public float minJumpHeight; // Minimum height Sonic can reach when jump button is released early public float maxJumpHeight; // Maximum height Sonic can reach if the jump button is held [Header("Ground Detection Variables")] public float groundCheckDistance = 0.1f; // Distance to check below Sonic to determine if grounded public LayerMask groundLayer; // Layers considered as ground for detection [Header("Slope Physics Variables")] public float slopeAssistance = 5f; // Multiplier for increasing speed when moving downhill public float slopeDrag = 5f; // Multiplier for decreasing speed when moving uphill public float wallStickSpeedThreshold = 2f; // Speed threshold below which Sonic will stick to walls on steep slopes private bool isGrounded; // Boolean to check if Sonic is currently on the ground public float currentSpeed; // Sonic's current movement speed private Vector3 groundNormal = Vector3.up; // The normal of the surface Sonic is currently on private Vector3 inputDirection; // The direction of the player's input private Vector3 velocity; // Sonic's current velocity private Vector3 targetPosition; // Target position for smooth movement void Update() { HandleInput(); // Capture input before movement and jumping HandleJump(); // Handle Sonic's jumping } void FixedUpdate() { CheckGrounded(); // Check if Sonic is grounded HandleMovement(); // Handle Sonic's movement ApplyMovement(); // Apply the calculated movement to Sonic } void HandleInput() { float horizontalInput = Input.GetAxis("Horizontal"); // Get horizontal input (left/right movement) float verticalInput = Input.GetAxis("Vertical"); // Get vertical input (forward/backward movement) inputDirection = new Vector3(horizontalInput, 0f, verticalInput).normalized; // Combine inputs into a direction vector } void HandleMovement() { bool isBoosting = Input.GetAxis("Fire2") > 0.1f; // Check if the boost button is pressed if (isGrounded) { float slopeRotation = Vector3.Dot(inputDirection, groundNormal); // Calculate rotation based on slope if (isBoosting) { currentSpeed = maxSpeed; // Set speed to max if boosting } else { if (inputDirection.magnitude > 0) { currentSpeed += acceleration * Time.deltaTime; // Increase speed based on acceleration currentSpeed = Mathf.Clamp(currentSpeed, 0, topSpeed); // Clamp speed to topSpeed if (slopeRotation > 0) // Moving downhill { currentSpeed += slopeRotation * slopeAssistance * Time.deltaTime; // Increase speed downhill } else if (slopeRotation < 0) // Moving uphill { currentSpeed += slopeRotation * slopeDrag * Time.deltaTime; // Decrease speed uphill } } else { currentSpeed -= deceleration * Time.deltaTime; // Decrease speed when no input if (currentSpeed < 0) currentSpeed = 0; // Prevent speed from going negative } } if (inputDirection.magnitude > 0) { Quaternion targetRotation = Quaternion.LookRotation(inputDirection, groundNormal); // Calculate target rotation transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 10f); // Smooth rotation } } else { if (inputDirection.magnitude > 0) { currentSpeed += airAcceleration * Time.deltaTime; // Increase speed in the air currentSpeed = Mathf.Clamp(currentSpeed, 0, airTopSpeed); // Clamp speed to airTopSpeed } // Apply gravity when in the air velocity.y -= gravity * Time.deltaTime; } Vector3 moveDirection = transform.forward * currentSpeed; // Calculate movement direction velocity = new Vector3(moveDirection.x, velocity.y, moveDirection.z); // Update velocity with the calculated movement } void HandleJump() { if (Input.GetButtonDown("Jump") && isGrounded) { velocity.y = jumpForce; // Apply jump force } if (Input.GetButtonUp("Jump") && velocity.y > minJumpHeight) { velocity.y = minJumpHeight; // Limit jump height when button is released } } void CheckGrounded() { RaycastHit hit; Vector3 rayDirection = -transform.up; // Raycast in the direction of Sonic's down if (Physics.Raycast(transform.position, rayDirection, out hit, groundCheckDistance, groundLayer)) { isGrounded = true; groundNormal = hit.normal; // Store the ground normal targetPosition = hit.point; // Target position is the hit point if (Vector3.Angle(Vector3.up, groundNormal) >= 90f && currentSpeed < wallStickSpeedThreshold) { isGrounded = false; // Disable grounding on steep slopes if speed is low } } else { isGrounded = false; groundNormal = Vector3.up; // Default to upwards normal if not grounded } } void ApplyMovement() { if (isGrounded) { transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * 10f); // Smoothly move to the target position } else { transform.position += velocity * Time.deltaTime; // Apply the velocity to move Sonic } } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; // Set Gizmo color Gizmos.DrawLine(transform.position, transform.position + -transform.up * groundCheckDistance); // Draw ground check line relative to Sonic } }
Leave a Comment