From 60c2e26bc432273d41365165c5457db7e51aa03d Mon Sep 17 00:00:00 2001 From: chai Date: Sat, 29 Jan 2022 11:36:08 +0800 Subject: *rename --- .../Scripts/FPSCharacterController.cs | 359 +++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs (limited to 'JamHelper/Assets/JamTools/FPSControllerVelocity/Scripts/FPSCharacterController.cs') 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 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"); + + 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(); + } + + 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() + { + + } + + } + +} -- cgit v1.1-26-g67d0