fps 게임의 기본인 wasd조작 등등을 만들었는데 점프 부분에서 자꾸 연속점프가 되는데 이거 원인 아시는분?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// 스피드 조정 변수
[SerializeField]
private float walkSpeed;
[SerializeField]
private float runSpeed;
[SerializeField]
private float crouchSpeed;
private float applySpeed;
[SerializeField]
private float jumpForce;
// 상태 변수
private bool isRun = false;
private bool isCrouch = false;
private bool isGround = true;
// 앉았을 때 얼마나 앉을지 결정하는 변수.
[SerializeField]
private float crouchPosY;
private float originPosY;
private float applyCrouchPosY;
// 땅 착지 여부
private CapsuleCollider capsuleCollider;
// 민감도
[SerializeField]
private float lookSensitivity;
// 카메라 한계
[SerializeField]
private float cameraRotationLimit;
private float currentCameraRotationX = 0;
//필요한 컴포넌트
[SerializeField]
private Camera theCamera;
private Rigidbody myRigid;
// Use this for initialization
void Start()
{
capsuleCollider = GetComponent<CapsuleCollider>();
myRigid = GetComponent<Rigidbody>();
applySpeed = walkSpeed;
// 초기화.
originPosY = theCamera.transform.localPosition.y;
applyCrouchPosY = originPosY;
}
// Update is called once per frame
void Update()
{
IsGround();
TryJump();
TryRun();
TryCrouch();
Move();
CameraRotation();
CharacterRotation();
}
// 앉기 시도
private void TryCrouch()
{
if (Input.GetKeyDown(KeyCode.LeftControl))
{
Crouch();
}
}
// 앉기 동작
private void Crouch()
{
isCrouch = !isCrouch;
if (isCrouch)
{
applySpeed = crouchSpeed;
applyCrouchPosY = crouchPosY;
}
else
{
applySpeed = walkSpeed;
applyCrouchPosY = originPosY;
}
StartCoroutine(CrouchCoroutine());
}
// 부드러운 동작 실행.
IEnumerator CrouchCoroutine()
{
float _posY = theCamera.transform.localPosition.y;
int count = 0;
while (_posY != applyCrouchPosY)
{
count++;
_posY = Mathf.Lerp(_posY, applyCrouchPosY, 0.3f);
theCamera.transform.localPosition = new Vector3(0, _posY, 0);
if (count > 15)
break;
yield return null;
}
theCamera.transform.localPosition = new Vector3(0, applyCrouchPosY, 0f);
}
// 지면 체크.
private void IsGround()
{
isGround = Physics.Raycast(transform.position, Vector3.down, capsuleCollider.bounds.extents.y + 0.1f);
}
// 점프 시도
private void TryJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGround)
{
Jump();
}
}
// 점프
private void Jump()
{
// 앉은 상태에서 점프시 앉은 상태 해제.
if (isCrouch)
Crouch();
myRigid.velocity = transform.up * jumpForce;
}
// 달리기 시도
private void TryRun()
{
if (Input.GetKey(KeyCode.LeftShift))
{
Running();
}
if (Input.GetKeyUp(KeyCode.LeftShift))
{
RunningCancel();
}
}
// 달리기 실행
private void Running()
{
if (isCrouch)
Crouch();
isRun = true;
applySpeed = runSpeed;
}
// 달리기 취소
private void RunningCancel()
{
isRun = false;
applySpeed = walkSpeed;
}
// 움직임 실행
private void Move()
{
float _moveDirX = Input.GetAxisRaw("Horizontal");
float _moveDirZ = Input.GetAxisRaw("Vertical");
Vector3 _moveHorizontal = transform.right * _moveDirX;
Vector3 _moveVertical = transform.forward * _moveDirZ;
Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * applySpeed;
myRigid.MovePosition(transform.position + _velocity * Time.deltaTime);
}
// 좌우 캐릭터 회전
private void CharacterRotation()
{
float _yRotation = Input.GetAxisRaw("Mouse X");
Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f) * lookSensitivity;
myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));
}
// 상하 카메라 회전
private void CameraRotation()
{
float _xRotation = Input.GetAxisRaw("Mouse Y");
float _cameraRotationX = _xRotation * lookSensitivity;
currentCameraRotationX -= _cameraRotationX;
currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit);
theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f);
}
ray문제랑 update에서 체크를하고잇으면 문제발생가능성이있음
아 update에서 체크를 하면 안되는거임?
그럼 ray는 어떤 식으로 고쳐야함? 유니티 배운지 얼마 안돼서 잘 모르겠음
Jump에서 Crouch쓰는것도 좀 뭔가 이상하네... 함수명을 좀더 명확하게 지어. Crouch라고 하면 Crouch해야한다고 생각하지, 안에 저렇게 Crouch하고 안하고 코드가 뒤섞여있으면 읽는사람도 혼란스럽고 처리하는것도이상하게됨
방법은 여러가지가 있는데 일단 내가 생각할때 우려사항만 얘기해줄게. 어짜피 해결방법을 떠올리는건 너가해야할 일임. Update에서 rigidbody.velocity를 가령 Vector.up으로 해줘도, 다음 Update에서 velocity만큼 올라갈거라는 보장은 없음. velocity가 position으로 반영되는건 FixedUpdate후임. Update는 렌더링할때마다 호출되는함수임. 그리고 길이가 0.1짜리 ray로 바닥체크가 문제없으려면 체크된후에 어떻게든 다음업데이트에는 0.1보단 밖으로 나가야됨. 여러모로 문제가될수있는 코드인셈임. 해결방법은 많어. 잘 생각해봐
RAY 길이가 너무 길지 않은지 체크해봐
연속점프가 뭐냐? 공중에서 2단 점프한다는 거야?
ㅇㅇ
ray 길이가 정상인경우 physics 설정에서 ray 충돌에 걸린 오브젝트가 뭔지 확인해보고
ㅇㅋㅇㅋ 감사
그냥 가끔씩 2단 점프가 가능한 유능한 주인공을 컨셉으로 잡고 출시해라.
점프 중일 때 bool꺼버리면 되지 않음?