diff options
author | chai <chaifix@163.com> | 2022-02-18 14:38:20 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2022-02-18 14:38:20 +0800 |
commit | 63795c45af9ecca5aea36fbe291b18fcd9fb9b7d (patch) | |
tree | 60d811d8a0b1944ab32d24aa28394183b82cadeb /JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs | |
parent | a41c8da0787e0285d4c5b16a5cf5bc3e7a34f521 (diff) |
*rename folder name
Diffstat (limited to 'JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs')
-rw-r--r-- | JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs b/JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs new file mode 100644 index 0000000..a6d844f --- /dev/null +++ b/JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs @@ -0,0 +1,396 @@ +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, // 额外重力
+ 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;
+
+ #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;
+
+ 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);
+
+ m_Rigidbody.velocity = Vector3.Slerp(m_Rigidbody.velocity, 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 SetCamera ()
+ {
+ m_Camera.SetCameraPositionAndRotation(m_Eye);
+ }
+
+ private void Awake()
+ {
+ m_Rigidbody = GetComponent<Rigidbody>();
+ }
+
+ private void Start()
+ {
+ m_CameraRotation = 0;
+
+ lockCursor = true;
+ }
+
+ private void Update()
+ {
+ MoveAroundUpdate();
+ MoveInAirUpdate();
+ Jump();
+ Dodge();
+ Shot();
+ WallJump();
+ PullTrick();
+
+ SetCamera();
+ }
+
+ private void FixedUpdate()
+ {
+ LookAround();
+ MoveAroundFixedUpdate();
+ MoveInAirFixedUpdate();
+ DodgeFixed();
+ ExtraGravity();
+ JumpFixedUpdate();
+ WallJumpFixedUpdate();
+ }
+
+ }
+}
|