first commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Minimal Rigidbody-based third-person controller for the lab prototype.
|
||||
/// Uses the classic Unity input axes, so it works in a default 3D template.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
[RequireComponent(typeof(CapsuleCollider))]
|
||||
public class SimplePlayerController : MonoBehaviour
|
||||
{
|
||||
public float moveSpeed = 6f;
|
||||
public float jumpForce = 7f;
|
||||
public float groundCheckRadius = 0.25f;
|
||||
public LayerMask groundMask = ~0;
|
||||
public float fallResetY = -10f;
|
||||
public Transform respawnPoint;
|
||||
public Vector3 lastSafePosition;
|
||||
|
||||
private Rigidbody rb;
|
||||
private CapsuleCollider capsuleCollider;
|
||||
private Collider[] ownColliders;
|
||||
private bool isGrounded;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
rb = GetComponent<Rigidbody>();
|
||||
capsuleCollider = GetComponent<CapsuleCollider>();
|
||||
ownColliders = GetComponentsInChildren<Collider>();
|
||||
rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
|
||||
lastSafePosition = transform.position;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateGroundedState();
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.Space) && isGrounded && rb.velocity.y <= 0.1f)
|
||||
{
|
||||
Vector3 velocity = rb.velocity;
|
||||
velocity.y = 0f;
|
||||
rb.velocity = velocity;
|
||||
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
|
||||
}
|
||||
|
||||
if (transform.position.y < fallResetY)
|
||||
{
|
||||
ResetToLastSafePosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
float horizontal = Input.GetAxisRaw("Horizontal");
|
||||
float vertical = Input.GetAxisRaw("Vertical");
|
||||
Vector3 input = new Vector3(horizontal, 0f, vertical);
|
||||
|
||||
if (input.sqrMagnitude > 1f)
|
||||
{
|
||||
input.Normalize();
|
||||
}
|
||||
|
||||
Vector3 horizontalVelocity = input * moveSpeed;
|
||||
rb.velocity = new Vector3(horizontalVelocity.x, rb.velocity.y, horizontalVelocity.z);
|
||||
|
||||
if (input.sqrMagnitude > 0.01f)
|
||||
{
|
||||
Quaternion targetRotation = Quaternion.LookRotation(input, Vector3.up);
|
||||
rb.MoveRotation(Quaternion.Slerp(rb.rotation, targetRotation, 12f * Time.fixedDeltaTime));
|
||||
}
|
||||
|
||||
if (isGrounded && rb.velocity.y <= 0.05f)
|
||||
{
|
||||
lastSafePosition = transform.position;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetToPosition(Vector3 position)
|
||||
{
|
||||
if (rb == null)
|
||||
{
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
transform.position = position;
|
||||
lastSafePosition = position;
|
||||
|
||||
if (rb != null)
|
||||
{
|
||||
rb.velocity = Vector3.zero;
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetToLastSafePosition()
|
||||
{
|
||||
Vector3 target = respawnPoint != null ? respawnPoint.position : lastSafePosition;
|
||||
ResetToPosition(target + Vector3.up * 0.25f);
|
||||
}
|
||||
|
||||
private void UpdateGroundedState()
|
||||
{
|
||||
Vector3 capsuleCenter = transform.TransformPoint(capsuleCollider.center);
|
||||
Vector3 sphereCenter = capsuleCenter + Vector3.down * ((capsuleCollider.height * 0.5f) - (groundCheckRadius * 0.5f));
|
||||
|
||||
Collider[] hits = Physics.OverlapSphere(
|
||||
sphereCenter,
|
||||
groundCheckRadius,
|
||||
groundMask,
|
||||
QueryTriggerInteraction.Ignore);
|
||||
|
||||
isGrounded = false;
|
||||
for (int i = 0; i < hits.Length; i++)
|
||||
{
|
||||
Collider hit = hits[i];
|
||||
if (hit == null || IsOwnCollider(hit))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// A valid jump surface must be below the player's feet, not inside the player body.
|
||||
if (hit.bounds.max.y <= sphereCenter.y + groundCheckRadius)
|
||||
{
|
||||
isGrounded = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsOwnCollider(Collider collider)
|
||||
{
|
||||
if (ownColliders == null || ownColliders.Length == 0)
|
||||
{
|
||||
ownColliders = GetComponentsInChildren<Collider>();
|
||||
}
|
||||
|
||||
for (int i = 0; i < ownColliders.Length; i++)
|
||||
{
|
||||
if (ownColliders[i] == collider)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user