Я написал контроллер персонажа, используя Kinematic Character Controller из хранилища ресурсов, и когда я нажимаю кнопку воспроизведения в Unity, персонаж начинает двигаться назад без каких-либо действий. Если я дам ему какой-либо сигнал, он будет двигаться в этом направлении бесконечно, не останавливаясь. Ниже я включил свой сценарий проигрывателя, сценарий проигрывателя камеры и сценарий контроллера персонажа.
`using UnityEngine;
public class Player : MonoBehaviour { [SerializeField] private PlayerCamera _playerCamera; // Reference to PlayerCamera script [SerializeField] private Transform _cameraFollowPoint; // Follow point for the camera [SerializeField] private CharacterController _characterController;
private Vector3 _lookInputVector;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
_playerCamera.SetFollowTransform(_cameraFollowPoint);
}
private void HandleCameraInput()
{
float mouseUp = Input.GetAxisRaw("Mouse Y");
float mouseRight = Input.GetAxisRaw("Mouse X");
_lookInputVector = new Vector3(mouseRight, mouseUp, 0f);
float scrollInput = -Input.GetAxis("Mouse ScrollWheel");
_playerCamera.UpdateWithInput(Time.deltaTime, scrollInput, _lookInputVector);
}
private void HandleCharacterInputs()
{
PlayerInputs inputs = new PlayerInputs();
inputs.MoveAxisForward = Input.GetAxisRaw("Vertical");
inputs.MoveAxisRight = Input.GetAxisRaw("Horizontal");
inputs.CameraRotation = _playerCamera.transform.rotation;
inputs.JumpPressed = Input.GetKeyDown(KeyCode.Space);
_characterController.SetInputs(ref inputs);
}
private void Update()
{
HandleCharacterInputs();
}
private void LateUpdate()
{
HandleCameraInput();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCamera : MonoBehaviour
{
[SerializeField]
private float _defaultDistance = 6f,
_minDistance = 3f,
_maxDistance = 10f,
_distanceMovementSpeed = 5f,
_distanceMovementSharpness = 10f,
_rotationSpeed = 10f,
_rotationSharpness = 10000f,
_followSharpness = 10000f,
_minVerticalAngle = -90f,
_maxVerticalAngle = 90f,
_defaultVerticalAngle = 20f;
private Transform _followTransform;
private Vector3 _currentFollowPosition, _planarDirection;
private float _targetVerticalAngle;
private float _currentDistance, _targetDistance;
private void Awake()
{
_currentDistance = _defaultDistance;
_targetDistance = _currentDistance;
_targetVerticalAngle = 0f;
_planarDirection = Vector3.forward;
}
public void SetFollowTransform(Transform t)
{
_followTransform = t;
_currentFollowPosition = t.position;
_planarDirection = t.forward;
}
private void OnValidate()
{
_defaultDistance = Mathf.Clamp(_defaultDistance, _minDistance, _maxDistance);
_defaultVerticalAngle = Mathf.Clamp(_defaultVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
}
private void HandleRotationInput(float deltaTime, Vector3 rotationInput, out Quaternion targetRotation)
{
Quaternion rotationFromInput = Quaternion.Euler(_followTransform.up * (rotationInput.x * _rotationSpeed));
_planarDirection = rotationFromInput * _planarDirection;
Quaternion planarRot = Quaternion.LookRotation(_planarDirection, _followTransform.up);
_targetVerticalAngle -= rotationInput.y * _rotationSpeed;
_targetVerticalAngle = Mathf.Clamp(_targetVerticalAngle, _minVerticalAngle, _maxVerticalAngle);
Quaternion verticalRot = Quaternion.Euler(_targetVerticalAngle, 0, 0);
targetRotation = Quaternion.Slerp(transform.rotation, planarRot * verticalRot, _rotationSharpness * deltaTime);
transform.rotation = targetRotation;
}
private void HandlePosition(float deltaTime, float zoomInput, Quaternion targetRotation)
{
_targetDistance += zoomInput * _distanceMovementSpeed;
_targetDistance = Mathf.Clamp(_targetDistance, _minDistance, _maxDistance);
_currentFollowPosition = Vector3.Lerp(_currentFollowPosition, _followTransform.position, 1f - Mathf.Exp(-_followSharpness * deltaTime));
Vector3 targetPosition = _currentFollowPosition - (targetRotation * Vector3.forward * _currentDistance);
_currentDistance = Mathf.Lerp(_currentDistance, _targetDistance, 1f - Mathf.Exp(-_distanceMovementSharpness * deltaTime));
transform.position = targetPosition;
}
public void UpdateWithInput(float deltaTime, float zoomInput, Vector3 rotationInput)
{
if (_followTransform)
{
HandleRotationInput(deltaTime, rotationInput, out Quaternion targetRotation);
HandlePosition(deltaTime, zoomInput, targetRotation);
}
}
}
using System.Collections;
using System.Collections.Generic;
using KinematicCharacterController;
using UnityEngine;
public struct PlayerInputs
{
public float MoveAxisForward;
public float MoveAxisRight;
public Quaternion CameraRotation;
public bool JumpPressed;
public bool CrouchDown;
public bool CrouchUp;
}
public struct AICharacterInputs
{
public Vector3 MoveVector;
public Vector3 LookVector;
}
public enum BonusOrientationMethod
{
None,
TowardsGravity,
TowardsGroundSlopeAndGravity,
}
public enum OrientationMethod
{
TowardsCamera,
TowardsMovement,
}
public class CharacterController : MonoBehaviour, ICharacterController
{
[SerializeField]
private KinematicCharacterMotor _motor;
[SerializeField]
private Vector3 _gravity = new Vector3(0f, -30f, 0f);
[SerializeField]
private float _maxStableMoveSpeed = 10f, _stableMovementSharpness = 15f, _orientationSharpness = 10f;
[SerializeField]
private float _jumpSpeed = 10f;
private Vector3 _moveInputVector;
private Vector3 _lookInputVector;
private bool _jumpRequested;
private void Start()
{
_motor.CharacterController = this;
}
public void SetInputs(ref PlayerInputs inputs)
{
// Clamp input
Vector3 moveInputVector = Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0f, inputs.MoveAxisForward), 1f);
// Only update _moveInputVector if there is input
if (moveInputVector.sqrMagnitude > 0f)
{
Vector3 cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.forward, _motor.CharacterUp).normalized;
if (cameraPlanarDirection.sqrMagnitude == 0f)
{
cameraPlanarDirection = Vector3.ProjectOnPlane(inputs.CameraRotation * Vector3.up, _motor.CharacterUp);
}
Quaternion cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, _motor.CharacterUp);
_moveInputVector = cameraPlanarRotation * moveInputVector;
_lookInputVector = _moveInputVector.normalized;
}
else
{
// Reset movement vectors if no input
_moveInputVector = Vector3.zero;
_lookInputVector = Vector3.zero;
}
if (inputs.JumpPressed)
{
_jumpRequested = true;
}
Debug.Log($"Move Input Vector: {_moveInputVector}");
}
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
if (_motor.GroundingStatus.IsStableOnGround)
{
float currentVelocityMagnitude = currentVelocity.magnitude;
Vector3 effectiveGroundNormal = _motor.GroundingStatus.GroundNormal;
currentVelocity = _motor.GetDirectionTangentToSurface(currentVelocity, effectiveGroundNormal) * currentVelocityMagnitude;
Vector3 inputRight = Vector3.Cross(_moveInputVector, _motor.CharacterUp);
Vector3 reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized * _moveInputVector.magnitude;
Vector3 targetMovementVelocity = reorientedInput * _maxStableMoveSpeed;
currentVelocity = Vector3.Lerp(currentVelocity, targetMovementVelocity, 1f - Mathf.Exp(-_stableMovementSharpness * deltaTime));
}
else
{
currentVelocity += _gravity * deltaTime;
if (_motor.GroundingStatus.IsStableOnGround)
{
float currentVelocityMagnitude = currentVelocity.magnitude;
Vector3 effectiveGroundNormal = _motor.GroundingStatus.GroundNormal;
currentVelocity = _motor.GetDirectionTangentToSurface(currentVelocity, effectiveGroundNormal) * currentVelocityMagnitude;
Vector3 inputRight = Vector3.Cross(_moveInputVector, _motor.CharacterUp);
Vector3 reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized * _moveInputVector.magnitude;
Vector3 targetMovementVelocity = reorientedInput * _maxStableMoveSpeed;
currentVelocity = Vector3.Lerp(currentVelocity, targetMovementVelocity, 1f - Mathf.Exp(-_stableMovementSharpness * deltaTime));
}
else
{
currentVelocity += _gravity * deltaTime;
// Apply drag to prevent infinite movement in air
currentVelocity *= 0.98f; // Adjust drag multiplier as needed
}
}
if (_jumpRequested)
if (_jumpRequested)
{
currentVelocity += (_motor.CharacterUp * _jumpSpeed) - Vector3.Project(currentVelocity, _motor.CharacterUp);
_jumpRequested = false;
_motor.ForceUnground();
}
Debug.Log($"Current Velocity: {currentVelocity}");
}
public void AfterCharacterUpdate(float deltaTime)
{
}
public void BeforeCharacterUpdate(float deltaTime)
{
}
public bool IsColliderValidForCollisions(Collider coll)
{
return true;
}
public void OnDiscreteCollisionDetected(Collider hitCollider)
{
}
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
{
}
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport)
{
}
public void PostGroundingUpdate(float deltaTime)
{
}
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, Vector3 atCharacterPosition, Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport)
{
}
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
if (_lookInputVector.sqrMagnitude > 0f && _orientationSharpness > 0f)
{
Vector3 smoothedLookInputDirection = Vector3.Slerp(_motor.CharacterForward, _lookInputVector, 1 - Mathf.Exp(-_orientationSharpness * deltaTime)).normalized;
currentRotation = Quaternion.LookRotation(smoothedLookInputDirection, _motor.CharacterUp);
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... troller-wh
Контроллер персонажа от третьего лица (Unity) с использованием Кинематического контроллера персонажа. Когда я нажимаю кн ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как добавить переменную высоту прыжка в сценарий контроллера от третьего лица?
Anonymous » » в форуме C# - 0 Ответы
- 59 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Мой код для камеры от третьего лица и движения вызывает ошибку, и я не знаю, почему
Anonymous » » в форуме C# - 0 Ответы
- 42 Просмотры
-
Последнее сообщение Anonymous
-