Untitled
unknown
csharp
a year ago
7.3 kB
10
Indexable
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
}
}
Editor is loading...
Leave a Comment