aboutsummaryrefslogtreecommitdiff
path: root/JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs
diff options
context:
space:
mode:
Diffstat (limited to 'JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs')
-rw-r--r--JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs359
1 files changed, 359 insertions, 0 deletions
diff --git a/JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs b/JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs
new file mode 100644
index 0000000..f995c8e
--- /dev/null
+++ b/JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs
@@ -0,0 +1,359 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace JamTools
+{
+
+ // 第一人称角色控制
+ public class FPSCharacterController : MonoBehaviour
+ {
+ [Flags]
+ public enum CharacterModule
+ {
+ None,
+ LookAround = 1 << 0, // 相机环绕
+ MoveAround = 1 << 1, // 水平地面移动
+ MoveInAir = 1 << 2, // 空中移动
+ Dodge = 1 << 3, // 冲刺
+ Rush = 1 << 4, // 加速
+ WalkOnSlope = 1 << 5 | 1 << 1, // 斜面移动
+ WalkOnStairs = 1 << 6 | 1 << 1, // 楼梯移动
+ WallRun = 1 << 7, // 飞檐走壁
+ Jump = 1 << 8, // 跳跃
+ WallJump = 1 << 9, // 忍者跳
+ Slide = 1 << 10, // 滑铲
+ Shot = 1 << 11, // 射击
+ Step = 1 << 12, // 脚步
+ PullTrick = 1 << 13, //
+ ExtraGravity = 1 << 14, // 额外重力
+ }
+
+ [SerializeField] private CharacterModule m_Modules;
+
+ [SerializeField] private Transform m_Eye;
+
+ [SerializeField] private PlayerBody m_Body;
+ [SerializeField] private GroundChecker m_GroundChecker;
+ [SerializeField] private WallChecker m_WallChecker;
+
+ #region Modules
+
+ [Header("Look Around")]
+ [SerializeField] private float m_LookSensitive = 1000f;
+ [Range(0.01f, 1)]
+ [SerializeField] private float m_LookSmooth = 0.2f;
+ [SerializeField] private float m_LookSmoothMultiplier = 100;
+ [SerializeField] private bool m_LookSmoothWithTime = true;
+ private float m_CameraRotation;
+ private float m_BodyRotation;
+
+ [Header("Move Around")]
+ [SerializeField] private float m_MoveSpeed = 100f;
+ [Range(0.01f, 1)]
+ [SerializeField] private float m_MoveSmooth = 0.2f;
+ [SerializeField] private float m_MoveSmoothMultiplier = 100;
+ [SerializeField] private bool m_MoveSmoothWithTime = true;
+ private Vector3 m_MoveDirection;
+
+ [Header("Move In Air")]
+ [SerializeField] private float m_MoveSpeedInAir = 50f;
+
+ [Header("Shot")]
+ [SerializeField] private Transform m_Muzzle;
+ [SerializeField] private LayerMask m_HittableLayers;
+ [SerializeField] private float m_ShotInfiniteDistance = 100f;
+
+ [Header("WallJump")]
+ [SerializeField] private float m_WallJumpForce = 1;
+ [SerializeField] private float m_WallJumpPower = 1000;
+
+
+ [Header("ExtraGravity")]
+ [SerializeField] private Vector3 m_ExtraGravity;
+
+ #endregion
+
+ public Func<RaycastHit, bool> checkHit;
+ public Action<Vector3, Transform> shootTarget;
+
+ private Rigidbody m_Rigidbody;
+
+ private bool m_LockCursor = false;
+ public bool lockCursor
+ {
+ get
+ {
+ return m_LockCursor;
+ }
+ set
+ {
+ m_LockCursor = value;
+ if (value)
+ {
+ Cursor.lockState = CursorLockMode.Locked;
+ }
+ else
+ {
+ Cursor.lockState = CursorLockMode.None;
+ }
+ }
+ }
+
+ bool IsModuleActive(CharacterModule module)
+ {
+ return (module & m_Modules) != 0;
+ }
+
+ void ActivateModule(CharacterModule module)
+ {
+ m_Modules |= module;
+ }
+
+ void LookAround()
+ {
+ if (!IsModuleActive(CharacterModule.LookAround))
+ return;
+
+ float mouseX = Input.GetAxis("Mouse X");
+ float mouseY = Input.GetAxis("Mouse Y");
+
+ float t = m_LookSmoothWithTime ? Time.deltaTime : 1;
+
+ m_CameraRotation -= mouseY * Time.deltaTime * m_LookSensitive;
+ m_CameraRotation = Mathf.Clamp(m_CameraRotation, -90, 90);
+ Quaternion rot = Quaternion.Euler(m_CameraRotation, 0, 0);
+ m_Eye.localRotation = Quaternion.Slerp(m_Eye.localRotation, rot, m_LookSmooth * t * m_LookSmoothMultiplier);
+
+ m_BodyRotation += mouseX * Time.deltaTime * m_LookSensitive;
+ rot = Quaternion.Euler(0, m_BodyRotation, 0);
+ transform.localRotation = Quaternion.Slerp(transform.localRotation, rot, m_LookSmooth * t * m_LookSmoothMultiplier);
+ }
+
+ void MoveAroundUpdate()
+ {
+ if (!IsModuleActive(CharacterModule.MoveAround))
+ return;
+
+ if (!m_GroundChecker.isOnGround)
+ return;
+
+ float moveX = Input.GetAxis("Horizontal");
+ float moveZ = Input.GetAxis("Vertical");
+
+ Vector3 right = transform.right;
+ Vector3 forward = transform.forward;
+
+ m_MoveDirection = right * moveX + forward * moveZ;
+
+ //if (IsModuleActive(CharacterModule.WalkOnSlope))
+ //{
+ // if (m_GroundChecker.isOnGround)
+ // {
+ // RaycastHit hitInfo;
+ // if (Physics.Raycast(m_GroundChecker.foot.position, Vector3.down, out hitInfo))
+ // {
+ // Vector3 normal = hitInfo.normal;
+ // m_MoveDirection = Vector3.ProjectOnPlane(m_MoveDirection, normal);
+ // GizmosHandle.Instance.DoGizmos(() => {
+ // Gizmos.DrawLine(hitInfo.point + new Vector3(0, 0.1f, 0), hitInfo.point + m_MoveDirection);
+ // });
+ // }
+ // }
+ //}
+
+ m_MoveDirection = m_MoveDirection.normalized;
+ }
+
+ void MoveAroundFixedUpdate()
+ {
+ if (!IsModuleActive(CharacterModule.MoveAround))
+ return;
+
+ if (!m_GroundChecker.isOnGround)
+ return;
+
+ float vy = m_Rigidbody.velocity.y;
+ Vector3 velocity = new Vector3(m_MoveDirection.x * Time.deltaTime * m_MoveSpeed, vy, m_MoveDirection.z * Time.deltaTime * m_MoveSpeed);
+
+ float t = m_MoveSmoothWithTime ? Time.deltaTime : 1;
+ m_Rigidbody.velocity = Vector3.Lerp(m_Rigidbody.velocity, velocity, m_MoveSmooth * t * m_MoveSmoothMultiplier);
+ //m_Rigidbody.AddForce(velocity * m_MoveSmoothMultiplier, ForceMode.VelocityChange);
+ }
+
+ void MoveInAirUpdate()
+ {
+ if (!IsModuleActive(CharacterModule.MoveInAir))
+ return;
+
+ if (m_GroundChecker.isOnGround)
+ return;
+
+ float moveX = Input.GetAxis("Horizontal");
+ float moveZ = Input.GetAxis("Vertical");
+
+ m_MoveDirection = Vector3.ClampMagnitude(transform.right * moveX + transform.forward * moveZ, 1);
+ }
+
+ void MoveInAirFixedUpdate()
+ {
+ if (!IsModuleActive(CharacterModule.MoveInAir))
+ return;
+
+ if (m_GroundChecker.isOnGround)
+ return;
+
+ if (m_MoveDirection.magnitude == 0)
+ return;
+
+ float vy = m_Rigidbody.velocity.y;
+ Vector3 velocity = new Vector3(m_MoveDirection.x * Time.deltaTime * m_MoveSpeedInAir, vy, m_MoveDirection.z * Time.deltaTime * m_MoveSpeedInAir);
+
+ m_Rigidbody.velocity = Vector3.Lerp(m_Rigidbody.velocity, velocity, 0.1f);
+ }
+
+ void Jump()
+ {
+ if (!IsModuleActive(CharacterModule.Jump))
+ return;
+
+ if (!m_GroundChecker.isOnGround)
+ return;
+
+ if (Input.GetButtonDown("Jump"))
+ {
+ m_Rigidbody.AddForce(Vector3.up * 300, ForceMode.Acceleration);
+ }
+ }
+
+ void Dodge()
+ {
+ if (!IsModuleActive(CharacterModule.Dodge))
+ return;
+
+ if (Input.GetKeyDown(KeyCode.LeftShift))
+ {
+ m_Rigidbody.AddForce(transform.forward * 5000, ForceMode.Acceleration);
+ }
+ }
+
+ void Shot()
+ {
+ if (!IsModuleActive(CharacterModule.Shot))
+ return;
+
+ if (Input.GetButtonDown("Fire1"))
+ {
+ Vector3 hitPoint = GetHitPoint();
+ if (shootTarget != null)
+ shootTarget(hitPoint, m_Muzzle);
+ }
+ }
+
+ Vector3 GetHitPoint()
+ {
+ RaycastHit[] hits = Physics.RaycastAll(m_Eye.position, m_Eye.forward, m_HittableLayers, (int)QueryTriggerInteraction.Ignore);
+ if (hits.Length < 1)
+ {
+ return m_Eye.position + m_Eye.forward * m_ShotInfiniteDistance;
+ }
+ else
+ {
+ for (int i = 0; i < hits.Length; ++i)
+ {
+ if (checkHit != null && checkHit(hits[i]))
+ {
+ return hits[i].point;
+ }
+ }
+ }
+ return hits[0].point;
+ }
+
+ void WallJump()
+ {
+ if (!IsModuleActive(CharacterModule.WallJump))
+ return;
+
+ if (!m_WallChecker.IsOnWall)
+ return;
+
+ if (m_GroundChecker.isOnGround)
+ return;
+
+ if (Input.GetButtonDown("Jump"))
+ {
+ Vector3 poc;
+ if (m_WallChecker.GetCollisionPoint(out poc))
+ {
+ Vector3 dir = Vector3.ClampMagnitude(transform.position - poc, 1f);
+ Vector3 wallJumpDirection = new Vector3(dir.x, 1, dir.z);
+ m_Rigidbody.velocity = Vector3.zero;
+ m_Rigidbody.AddForce(wallJumpDirection * m_WallJumpPower);
+ }
+ }
+ }
+
+ void WallRun()
+ {
+ if (!IsModuleActive(CharacterModule.WallRun))
+ return;
+
+ if (!m_WallChecker.IsOnWall)
+ return;
+
+ }
+
+ void PullTrick()
+ {
+
+ }
+
+ void ExtraGravity()
+ {
+ if (!IsModuleActive(CharacterModule.ExtraGravity))
+ return;
+
+ m_Rigidbody.AddForce(m_ExtraGravity, ForceMode.Acceleration);
+ }
+
+ private void Awake()
+ {
+ m_Rigidbody = GetComponent<Rigidbody>();
+ }
+
+ private void Start()
+ {
+ m_CameraRotation = 0;
+
+ lockCursor = true;
+ }
+
+ private void Update()
+ {
+ LookAround();
+ MoveAroundUpdate();
+ MoveInAirUpdate();
+ Jump();
+ Dodge();
+ Shot();
+ WallJump();
+ PullTrick();
+ }
+
+ private void FixedUpdate()
+ {
+ MoveAroundFixedUpdate();
+ MoveInAirFixedUpdate();
+ ExtraGravity();
+ }
+
+ private void OnDrawGizmos()
+ {
+
+ }
+
+ }
+
+}