using UnityEngine;
namespace SpriteMan3D
{
///
/// A simple Input controller for detecting player actions.
///
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
public class PersonPlayerController : PersonController
{
///
/// A character's walking speed.
///
public float walkSpeed = 2f;
///
/// A character's running speed.
///
public float runSpeed = 3f;
///
/// A character's jump velocity.
///
///
/// Increase your project's Physics gravity and increase this value to make a character jump quickly.
///
public float jumpVelocity;
///
/// How far to look for the distance to ground.
///
public float groundDistanceOffset = 0.2f;
///
/// The collider used for a mellee attack.
///
public Collider attackCollider;
///
/// Determines if this character can move.
///
public bool canMove = true;
///
/// Determines if this character can jump.
///
public bool canJump = true;
///
/// Determines if this character can attack.
///
public bool canAttack = true;
private Rigidbody rb;
private float distToGround;
private Collider charCollider;
public float attackCooldown = 0.2f;
private float attackTimer = 0f;
void Start()
{
rb = transform.GetComponent();
// get the distance to ground
charCollider = GetComponent();
distToGround = charCollider.bounds.extents.y;
}
Vector3 offset;
void Update()
{
IsGrounded = Physics.Raycast(transform.position, -Vector3.up, distToGround + groundDistanceOffset);
HandleAttack();
HandleJump();
}
void FixedUpdate()
{
HandleMove();
}
void HandleMove()
{
if (canMove)
{
var speed = walkSpeed;
// detect input movement
var moveHorizontal = Input.GetAxis("Horizontal");
var moveVertical = Input.GetAxis("Vertical");
IsMoving = moveHorizontal != 0 || moveVertical != 0;
IsRunning = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
if(IsRunning)
{
speed = runSpeed;
}
// rotate the character
var movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
var rot = movement * (speed / 10);
if (attackTimer <= 0 && movement != Vector3.zero)
{
var newRotation = Quaternion.LookRotation(rot);
rb.rotation = Quaternion.RotateTowards(transform.rotation, newRotation, 360f);
}
// move the character
if (IsMoving && offset.y != 0f)
{
movement.y = offset.normalized.y * movement.magnitude;
}
movement *= (speed / 10);
var characterMovement = transform.position + movement;
if (attackTimer <= 0 || !IsGrounded)
{
rb.MovePosition(characterMovement);
}
}
}
private void HandleJump()
{
if (canJump)
{
// detect jump
JumpStarted = Input.GetButtonDown("Jump");
// make the character jump
if (JumpStarted && IsGrounded)
{
var velocity = rb.velocity;
velocity.y = jumpVelocity;
rb.velocity = velocity;
}
}
}
private void HandleAttack()
{
if (canAttack)
{
if (attackTimer <= 0)
{
// detect attack
AttackStarted = Input.GetButtonDown("Fire1");
if (AttackStarted)
{
attackTimer = attackCooldown;
}
}
else
{
if(AttackStarted)
{
AttackStarted = false;
}
attackTimer -= Time.deltaTime;
}
}
}
///
/// called as animation event from Attack animation.
///
public void StartAttack()
{
attackCollider.enabled = true;
}
///
/// called as animation event from Attack animation.
///
public void EndAttack()
{
attackCollider.enabled = false;
}
}
}