From 63795c45af9ecca5aea36fbe291b18fcd9fb9b7d Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 18 Feb 2022 14:38:20 +0800 Subject: *rename folder name --- .../Scripts/FPSCharacterController.cs | 396 +++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs (limited to 'JamHelper/Assets/JamUtils/FPSControllerVelocity/Scripts/FPSCharacterController.cs') 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 checkHit; + public Action 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(); + } + + 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(); + } + + } +} -- cgit v1.1-26-g67d0