From 0e8ce5318fe683d0cf3d2c7c98fb361f62d4428f Mon Sep 17 00:00:00 2001
From: chai <chaifix@163.com>
Date: Sun, 20 Feb 2022 17:29:32 +0800
Subject: * rename folder

---
 .../Scripts/FPSCharacterController.cs              | 431 +++++++++++++++++++++
 1 file changed, 431 insertions(+)
 create mode 100644 JamHelper/Assets/JamUtils/FirstPersonCharacterController/Scripts/FPSCharacterController.cs

(limited to 'JamHelper/Assets/JamUtils/FirstPersonCharacterController/Scripts/FPSCharacterController.cs')

diff --git a/JamHelper/Assets/JamUtils/FirstPersonCharacterController/Scripts/FPSCharacterController.cs b/JamHelper/Assets/JamUtils/FirstPersonCharacterController/Scripts/FPSCharacterController.cs
new file mode 100644
index 0000000..db0cb20
--- /dev/null
+++ b/JamHelper/Assets/JamUtils/FirstPersonCharacterController/Scripts/FPSCharacterController.cs
@@ -0,0 +1,431 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace JamUtils
+{
+
+    // ��һ�˳ƽ�ɫ����
+    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,  // ��������
+            Crouch = 1 << 15,
+        }
+
+        [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;
+
+        [SerializeField] private MainCameraFollow m_Camera;
+
+        #region Modules
+
+        [Header("Look Around")]
+        [SerializeField] private float m_LookSensitive = 1000f;
+        [Range(0.01f, 1)]
+        [SerializeField] private float m_LookSmooth = 0.2f;
+        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;
+        private Vector3 m_MoveDirection;
+        private bool m_ReadyMoveAround = false;
+        [SerializeField] private bool m_HeadBobbing = false;
+
+        [Header("Move In Air")]
+        [SerializeField] private float m_MoveSpeedInAir = 50f;
+        [SerializeField] private float m_MoveInAirSmooth = 0.2f;
+        private Vector3 m_MoveInAirDirection;
+
+        [Header("Jump")]
+        [SerializeField] private float m_JumpPower = 300f;
+        private bool m_ReadyToJump = false;
+
+        [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;
+        private bool m_ReadyWallJump = false;
+
+        [Header("WallRun")]
+        [SerializeField] private float m_WallRunSpeed = 1;
+
+		[Header("ExtraGravity")]
+        [SerializeField] private Vector3 m_ExtraGravity;
+
+		[Header("WalkOnStairs")]
+		[SerializeField] private Transform m_Lower;
+		[SerializeField] private Transform m_Upper;
+		[SerializeField] private float m_StepSmooth;
+
+		#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");
+
+            //mouseX = -0.1f; // test jittery
+
+            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 );
+
+            m_BodyRotation += mouseX * Time.deltaTime * m_LookSensitive;
+            rot = Quaternion.Euler(0, m_BodyRotation, 0);
+            transform.localRotation = Quaternion.Slerp(transform.localRotation, rot, m_LookSmooth);
+        }
+
+        void MoveAroundUpdate()
+        {
+            if (!IsModuleActive(CharacterModule.MoveAround))
+                return;
+
+            if (!m_GroundChecker.isOnGround)
+                return;
+
+            float moveX = Input.GetAxisRaw("Horizontal");
+            float moveZ = Input.GetAxisRaw("Vertical");
+
+            Vector3 right = transform.right;
+            Vector3 forward = transform.forward;
+
+            Vector3 dir = 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;
+                        dir = Vector3.ProjectOnPlane(dir, normal);
+                        GizmosHandle.Instance.DoGizmos(() =>
+                        {
+                            Gizmos.DrawLine(hitInfo.point + new Vector3(0, 0.1f, 0), hitInfo.point + dir);
+                        });
+                    }
+                }
+            }
+
+            dir = dir.normalized;
+
+			m_MoveDirection = Vector3.Slerp(m_MoveDirection, dir, 1f);
+		}
+
+        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);
+
+			Vector3 rigidVel = m_Rigidbody.velocity;
+
+			// ���ٶ�Slerp�Ƚ�Σ��
+			//if (Vector3.Angle(rigidVel, velocity) > 90)
+			//{
+			//	m_Rigidbody.velocity = Vector3.Lerp(rigidVel, velocity, m_MoveSmooth); 
+			//}
+			//else
+			//{
+			//	m_Rigidbody.velocity = Vector3.Slerp(rigidVel, velocity, m_MoveSmooth); 
+			//}
+
+			m_Rigidbody.velocity = Vector3.Lerp(rigidVel, velocity, m_MoveSmooth);
+		}
+
+		void MoveInAirUpdate()
+        {
+            if (!IsModuleActive(CharacterModule.MoveInAir))
+                return;
+
+            if (m_GroundChecker.isOnGround)
+                return;
+
+            float moveX = Input.GetAxisRaw("Horizontal");
+            float moveZ = Input.GetAxisRaw("Vertical");
+
+            m_MoveInAirDirection = Vector3.ClampMagnitude(transform.right * moveX + transform.forward * moveZ, 1);
+        }
+
+        void MoveInAirFixedUpdate()
+        {
+            if (!IsModuleActive(CharacterModule.MoveInAir))
+                return;
+
+            if (m_GroundChecker.isOnGround)
+                return;
+
+            if (m_MoveInAirDirection.magnitude == 0f)
+                return;
+
+            float vy = m_Rigidbody.velocity.y;
+            Vector3 velocity = new Vector3(m_MoveInAirDirection.x * Time.deltaTime * m_MoveSpeedInAir, vy, m_MoveInAirDirection.z * Time.deltaTime * m_MoveSpeedInAir);
+
+            m_Rigidbody.velocity = Vector3.Lerp(m_Rigidbody.velocity, velocity, m_MoveInAirSmooth);
+        }
+
+        void Jump()
+        {
+            if (!IsModuleActive(CharacterModule.Jump))
+                return;
+
+            if (!m_GroundChecker.isOnGround)
+                return;
+
+            if (Input.GetButtonDown("Jump"))
+            {
+                m_ReadyToJump = true;
+            }
+        }
+
+        void JumpFixedUpdate()
+        {
+            if(m_ReadyToJump)
+            {
+                m_ReadyToJump = false;
+                m_Rigidbody.AddForce(Vector3.up * m_JumpPower, ForceMode.Acceleration);
+            }
+        }
+
+        void Dodge()
+        {
+            if (!IsModuleActive(CharacterModule.Dodge))
+                return;
+
+            if (Input.GetKeyDown(KeyCode.LeftShift))
+            {
+
+            }
+        }
+
+        void DodgeFixed()
+        {
+
+        }
+
+        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"))
+			{
+                m_ReadyWallJump = true;
+			}
+		}
+
+        void WallJumpFixedUpdate()
+        {
+            if(m_ReadyWallJump)
+            {
+                m_ReadyWallJump = false;
+                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);
+        }
+
+		void WalkOnStairs()
+		{
+			//int layermask = ~(1 << LayerMask.NameToLayer("Player"));
+
+			//RaycastHit hitLower;
+			//if (Physics.Raycast(m_Lower.position, transform.TransformDirection(Vector3.forward), out hitLower, 0.6f, layermask))
+			//{
+			//	RaycastHit hitUpper;
+			//	if (!Physics.Raycast(m_Upper.position, transform.TransformDirection(Vector3.forward), out hitUpper, 0.7f, layermask))
+			//	{
+			//		m_Rigidbody.position += new Vector3(0f, m_StepSmooth * Time.deltaTime, 0f);
+			//	}
+			//}
+		}
+
+
+		void SetCamera ()
+        {
+            m_Camera.SetCameraPositionAndRotation(m_Eye);
+        }
+
+        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();
+
+            SetCamera();
+        }
+
+		private void FixedUpdate()
+		{
+			WalkOnStairs();
+			MoveAroundFixedUpdate();
+            MoveInAirFixedUpdate();
+            DodgeFixed();
+            ExtraGravity();
+            JumpFixedUpdate();
+            WallJumpFixedUpdate();
+        }
+
+    }
+}
-- 
cgit v1.1-26-g67d0