FiE-Game/Assets/Scripts/ThirdPersonController.cs

413 lines
9.2 KiB
C#

using System;
using UnityEngine;
[Serializable]
[RequireComponent(typeof(CharacterController))]
public class ThirdPersonController : MonoBehaviour
{
public AnimationClip idleAnimation;
public AnimationClip walkAnimation;
public AnimationClip runAnimation;
public AnimationClip jumpPoseAnimation;
public float walkMaxAnimationSpeed;
public float trotMaxAnimationSpeed;
public float runMaxAnimationSpeed;
public float jumpAnimationSpeed;
public float landAnimationSpeed;
private Animation _animation;
private CharacterState _characterState;
public float walkSpeed;
public float trotSpeed;
public float runSpeed;
public float inAirControlAcceleration;
public float jumpHeight;
public float gravity;
public float speedSmoothing;
public float rotateSpeed;
public float trotAfterSeconds;
public bool canJump;
private float jumpRepeatTime;
private float jumpTimeout;
private float groundedTimeout;
private float lockCameraTimer;
private Vector3 moveDirection;
private float verticalSpeed;
private float moveSpeed;
private CollisionFlags collisionFlags;
private bool jumping;
private bool jumpingReachedApex;
private bool movingBack;
private bool isMoving;
private float walkTimeStart;
private float lastJumpButtonTime;
private float lastJumpTime;
private float lastJumpStartHeight;
private Vector3 inAirVelocity;
private float lastGroundedTime;
private bool isControllable;
public ThirdPersonController()
{
walkMaxAnimationSpeed = 0.75f;
trotMaxAnimationSpeed = 1f;
runMaxAnimationSpeed = 1f;
jumpAnimationSpeed = 1.15f;
landAnimationSpeed = 1f;
walkSpeed = 2f;
trotSpeed = 4f;
runSpeed = 6f;
inAirControlAcceleration = 3f;
jumpHeight = 0.5f;
gravity = 20f;
speedSmoothing = 10f;
rotateSpeed = 500f;
trotAfterSeconds = 3f;
canJump = true;
jumpRepeatTime = 0.05f;
jumpTimeout = 0.15f;
groundedTimeout = 0.25f;
moveDirection = Vector3.zero;
lastJumpButtonTime = -10f;
lastJumpTime = -1f;
inAirVelocity = Vector3.zero;
isControllable = true;
}
public override void Awake()
{
moveDirection = transform.TransformDirection(Vector3.forward);
_animation = (Animation)GetComponent(typeof(Animation));
if (!(bool)_animation)
{
Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");
}
if (!(bool)idleAnimation)
{
_animation = null;
Debug.Log("No idle animation found. Turning off animations.");
}
if (!(bool)walkAnimation)
{
_animation = null;
Debug.Log("No walk animation found. Turning off animations.");
}
if (!(bool)runAnimation)
{
_animation = null;
Debug.Log("No run animation found. Turning off animations.");
}
if (!(bool)jumpPoseAnimation && canJump)
{
_animation = null;
Debug.Log("No jump animation found and the character has canJump enabled. Turning off animations.");
}
}
public override void UpdateSmoothedMovementDirection()
{
Transform transform = Camera.main.transform;
bool flag = IsGrounded();
Vector3 a = transform.TransformDirection(Vector3.forward);
a.y = 0f;
a = a.normalized;
Vector3 a2 = new Vector3(a.z, 0f, 0f - a.x);
float axisRaw = Input.GetAxisRaw("Vertical");
float axisRaw2 = Input.GetAxisRaw("Horizontal");
if (!(axisRaw >= -0.2f))
{
movingBack = true;
}
else
{
movingBack = false;
}
bool flag2 = isMoving;
int num = (Mathf.Abs(axisRaw2) > 0.1f) ? 1 : 0;
if (num == 0)
{
num = ((Mathf.Abs(axisRaw) > 0.1f) ? 1 : 0);
}
isMoving = ((byte)num != 0);
Vector3 vector = axisRaw2 * a2 + axisRaw * a;
if (flag)
{
lockCameraTimer += Time.deltaTime;
if (isMoving != flag2)
{
lockCameraTimer = 0f;
}
if (vector != Vector3.zero)
{
if (!(moveSpeed >= walkSpeed * 0.9f) && flag)
{
moveDirection = vector.normalized;
}
else
{
moveDirection = Vector3.RotateTowards(moveDirection, vector, rotateSpeed * 0.0174532924f * Time.deltaTime, 1000f);
moveDirection = moveDirection.normalized;
}
}
float t = speedSmoothing * Time.deltaTime;
float num2 = Mathf.Min(vector.magnitude, 1f);
_characterState = CharacterState.Idle;
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
num2 *= runSpeed;
_characterState = CharacterState.Running;
}
else if (!(Time.time - trotAfterSeconds <= walkTimeStart))
{
num2 *= trotSpeed;
_characterState = CharacterState.Trotting;
}
else
{
num2 *= walkSpeed;
_characterState = CharacterState.Walking;
}
moveSpeed = Mathf.Lerp(moveSpeed, num2, t);
if (!(moveSpeed >= walkSpeed * 0.3f))
{
walkTimeStart = Time.time;
}
}
else
{
if (jumping)
{
lockCameraTimer = 0f;
}
if (isMoving)
{
inAirVelocity += vector.normalized * Time.deltaTime * inAirControlAcceleration;
}
}
}
public override void ApplyJumping()
{
if (lastJumpTime + jumpRepeatTime <= Time.time && IsGrounded() && canJump && !(Time.time >= lastJumpButtonTime + jumpTimeout))
{
verticalSpeed = CalculateJumpVerticalSpeed(jumpHeight);
SendMessage("DidJump", SendMessageOptions.DontRequireReceiver);
}
}
public override void ApplyGravity()
{
if (isControllable)
{
bool button = Input.GetButton("Jump");
if (jumping && !jumpingReachedApex && !(verticalSpeed > 0f))
{
jumpingReachedApex = true;
SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
}
if (IsGrounded())
{
verticalSpeed = 0f;
}
else
{
verticalSpeed -= gravity * Time.deltaTime;
}
}
}
public override float CalculateJumpVerticalSpeed(float targetJumpHeight)
{
return Mathf.Sqrt(2f * targetJumpHeight * gravity);
}
public override void DidJump()
{
jumping = true;
jumpingReachedApex = false;
lastJumpTime = Time.time;
Vector3 position = transform.position;
lastJumpStartHeight = position.y;
lastJumpButtonTime = -10f;
_characterState = CharacterState.Jumping;
}
public override void Update()
{
if (!isControllable)
{
Input.ResetInputAxes();
}
if (Input.GetButtonDown("Jump"))
{
lastJumpButtonTime = Time.time;
}
UpdateSmoothedMovementDirection();
ApplyGravity();
ApplyJumping();
Vector3 a = moveDirection * moveSpeed + new Vector3(0f, verticalSpeed, 0f) + inAirVelocity;
a *= Time.deltaTime;
CharacterController characterController = (CharacterController)GetComponent(typeof(CharacterController));
collisionFlags = characterController.Move(a);
if ((bool)_animation)
{
if (_characterState == CharacterState.Jumping)
{
if (!jumpingReachedApex)
{
_animation[jumpPoseAnimation.name].speed = jumpAnimationSpeed;
_animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
_animation.CrossFade(jumpPoseAnimation.name);
}
else
{
_animation[jumpPoseAnimation.name].speed = 0f - landAnimationSpeed;
_animation[jumpPoseAnimation.name].wrapMode = WrapMode.ClampForever;
_animation.CrossFade(jumpPoseAnimation.name);
}
}
else if (!(characterController.velocity.sqrMagnitude >= 0.1f))
{
_animation.CrossFade(idleAnimation.name);
}
else if (_characterState == CharacterState.Running)
{
_animation[runAnimation.name].speed = Mathf.Clamp(characterController.velocity.magnitude, 0f, runMaxAnimationSpeed);
_animation.CrossFade(runAnimation.name);
}
else if (_characterState == CharacterState.Trotting)
{
_animation[walkAnimation.name].speed = Mathf.Clamp(characterController.velocity.magnitude, 0f, trotMaxAnimationSpeed);
_animation.CrossFade(walkAnimation.name);
}
else if (_characterState == CharacterState.Walking)
{
_animation[walkAnimation.name].speed = Mathf.Clamp(characterController.velocity.magnitude, 0f, walkMaxAnimationSpeed);
_animation.CrossFade(walkAnimation.name);
}
}
if (IsGrounded())
{
transform.rotation = Quaternion.LookRotation(moveDirection);
}
else
{
Vector3 forward = a;
forward.y = 0f;
if (!(forward.sqrMagnitude <= 0.001f))
{
transform.rotation = Quaternion.LookRotation(forward);
}
}
if (IsGrounded())
{
lastGroundedTime = Time.time;
inAirVelocity = Vector3.zero;
if (jumping)
{
jumping = false;
SendMessage("DidLand", SendMessageOptions.DontRequireReceiver);
}
}
}
public override void OnControllerColliderHit(ControllerColliderHit hit)
{
Vector3 vector = hit.moveDirection;
if (vector.y <= 0.01f)
{
}
}
public override float GetSpeed()
{
return moveSpeed;
}
public override bool IsJumping()
{
return jumping;
}
public override bool IsGrounded()
{
return (collisionFlags & CollisionFlags.Below) != CollisionFlags.None;
}
public override Vector3 GetDirection()
{
return moveDirection;
}
public override bool IsMovingBackwards()
{
return movingBack;
}
public override float GetLockCameraTimer()
{
return lockCameraTimer;
}
public override bool IsMoving()
{
return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5f;
}
public override bool HasJumpReachedApex()
{
return jumpingReachedApex;
}
public override bool IsGroundedWithTimeout()
{
return lastGroundedTime + groundedTimeout > Time.time;
}
public override void Reset()
{
gameObject.tag = "Player";
}
public override void Main()
{
}
}