namespace StarterAssets { using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(CharacterController))] [RequireComponent(typeof(PlayerInput))] public class ThirdPersonController : MonoBehaviour { public float MoveSpeed = 2.0f; public float SprintSpeed = 5.335f; public float SpeedChangeRate = 10.0f; public float JumpHeight = 1.2f; public float Gravity = -15.0f; public float JumpTimeout = 0.50f; public float FallTimeout = 0.15f; public bool Grounded = true; public float GroundedOffset = -0.14f; public float GroundedRadius = 0.28f; public LayerMask GroundLayers; public Camera PlayerCamera; public float TopClamp = 70.0f; public float BottomClamp = -30.0f; public float CameraAngleOverride = 0.0f; public bool LockCameraPosition = false; private float _cinemachineTargetYaw; private float _cinemachineTargetPitch; private float _speed; private float _verticalVelocity; private float _terminalVelocity = 53.0f; private float _jumpTimeoutDelta; private float _fallTimeoutDelta; private PlayerInput _playerInput; private CharacterController _controller; private StarterAssetsInputs _input; private Animator _animator; private int _animIDSpeed; private int _animIDGrounded; private int _animIDJump; private int _animIDFreeFall; private int _animIDMotionSpeed; private const float _threshold = 0.01f; private bool _hasAnimator; private bool IsCurrentDeviceMouse { get { return _playerInput != null && _playerInput.currentControlScheme == "KeyboardMouse"; } } private void Awake() { if (PlayerCamera == null) { PlayerCamera = Camera.main; } } private void Start() { _cinemachineTargetYaw = PlayerCamera.transform.rotation.eulerAngles.y; _controller = GetComponent(); _input = GetComponent(); _hasAnimator = TryGetComponent(out _animator); _playerInput = GetComponent(); AssignAnimationIDs(); _jumpTimeoutDelta = JumpTimeout; _fallTimeoutDelta = FallTimeout; } private void Update() { JumpAndGravity(); GroundedCheck(); Move(); } private void LateUpdate() { CameraRotation(); } private void AssignAnimationIDs() { _animIDSpeed = Animator.StringToHash("Speed"); _animIDGrounded = Animator.StringToHash("Grounded"); _animIDJump = Animator.StringToHash("Jump"); _animIDFreeFall = Animator.StringToHash("FreeFall"); _animIDMotionSpeed = Animator.StringToHash("MotionSpeed"); } private void GroundedCheck() { Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z); //https://docs.unity3d.com/6000.4/Documentation/ScriptReference/Physics.CheckSphere.html Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore); if (_hasAnimator) { _animator.SetBool(_animIDGrounded, Grounded); } } private void CameraRotation() { if (_input.look.sqrMagnitude >= _threshold && !LockCameraPosition) { float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime; _cinemachineTargetYaw += _input.look.x * deltaTimeMultiplier; _cinemachineTargetPitch += _input.look.y * deltaTimeMultiplier; } _cinemachineTargetYaw = ClampAngle(_cinemachineTargetYaw, float.MinValue, float.MaxValue); _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp); PlayerCamera.transform.rotation = Quaternion.Euler(_cinemachineTargetPitch + CameraAngleOverride, _cinemachineTargetYaw, 0.0f); transform.rotation = Quaternion.Euler(0.0f, _cinemachineTargetYaw, 0.0f); } //https://docs.unity3d.com/6000.4/Documentation/ScriptReference/CharacterController.Move.html private void Move() { float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed; if (_input.move == Vector2.zero) targetSpeed = 0.0f; float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude; float speedOffset = 0.1f; float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f; if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset) { _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate); _speed = Mathf.Round(_speed * 1000f) / 1000f; } else { _speed = targetSpeed; } Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized; Vector3 moveDirection = PlayerCamera.transform.right * inputDirection.x + PlayerCamera.transform.forward * inputDirection.z; moveDirection.y = 0f; _controller.Move(moveDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime); if (_hasAnimator) { _animator.SetFloat(_animIDSpeed, _speed); _animator.SetFloat(_animIDMotionSpeed, inputMagnitude); } } //https://docs.unity3d.com/6000.4/Documentation/ScriptReference/Mathf.Sqrt.html private void JumpAndGravity() { if (Grounded) { _fallTimeoutDelta = FallTimeout; if (_hasAnimator) { _animator.SetBool(_animIDJump, false); _animator.SetBool(_animIDFreeFall, false); } if (_verticalVelocity < 0.0f) { _verticalVelocity = -2f; } if (_input.jump && _jumpTimeoutDelta <= 0.0f) { _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity); if (_hasAnimator) { _animator.SetBool(_animIDJump, true); } } if (_jumpTimeoutDelta >= 0.0f) { _jumpTimeoutDelta -= Time.deltaTime; } } else { _jumpTimeoutDelta = JumpTimeout; if (_fallTimeoutDelta >= 0.0f) { _fallTimeoutDelta -= Time.deltaTime; } else { if (_hasAnimator) { _animator.SetBool(_animIDFreeFall, true); } } _input.jump = false; } if (_verticalVelocity < _terminalVelocity) { _verticalVelocity += Gravity * Time.deltaTime; } } private static float ClampAngle(float lfAngle, float lfMin, float lfMax) { if (lfAngle < -360f) lfAngle += 360f; if (lfAngle > 360f) lfAngle -= 360f; return Mathf.Clamp(lfAngle, lfMin, lfMax); } private void OnFootstep(AnimationEvent animationEvent) { } // Die beiden teile sind einfach da damit das spiel nicht einfriert, immernoch keinen plan warum, aber es ist so private void OnLand(AnimationEvent animationEvent) { } private void OnDrawGizmosSelected() { Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f); Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f); if (Grounded) Gizmos.color = transparentGreen; else Gizmos.color = transparentRed; Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius); } } }