케릭터가 벽타기 점프도 되면서 2단점프만 되게 하고 싶은데 무한 점프가 적용됩니다.
어떻게 고쳐야 할까요?
주석부분과 의문인 부분 붉은색으로 해놨는데 해결 방법 좀 알려주시면 감사드리겠습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField] GameObject m_slideDust;
private int m_facingDirection = 1;
public float jumpSpeed = 5f;
Rigidbody2D rigid;
Animator anim;
public Transform groundChkFront; // 바닥 체크 position
public Transform groundChkBack; // 바닥 체크 position
public Transform wallChk;
public float wallchkDistance;
public LayerMask w_layer;
bool isWall;
public float slidingSpeed;
public float wallJumpPower;
public bool isWallJump;
public float runSpeed; // 이동 속도
float isRight = 1; // 바라보는 방향 1 = 오른쪽 , -1 = 왼쪽
float input_x;
bool isGround;
public bool isGrounded = false; //이거 처음에 false로 하는게 맞나요?
public int jumpCount=0;
public float chkDistance;
public float jumpPower = 1;
public LayerMask g_Layer;
public Transform pos;
public Vector2 boxSize;
void Start()
{
rigid = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
jumpCount = 2;
isGrounded = true;
}
private void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Platforms")
{
isGrounded= true;
jumpCount = 2; //플랫폼에 닿았을때 2로 초기화 요거 맞죠?
}
}
private float curTime;
public float coolTime =0.5f;
void Update()
{
// 캐릭터 점프
if (isGrounded) {
if(jumpCount>0) { // 빨간 부분을 넣으면 점프 한번 한뒤에 0으로 초기화되어서 점프가 안되고
뻬버리면 무한점프가 되는 상태입니다.
if (Input.GetAxis("Jump") != 0 )
{
rigid.velocity = Vector2.up * jumpPower;
jumpCount--;
}
}
}
input_x = Input.GetAxis("Horizontal");
// 캐릭터의 앞쪽과 뒤쪽의 바닥 체크를 진행
bool ground_front = Physics2D.Raycast(groundChkFront.position, Vector2.down, chkDistance, g_Layer);
bool ground_back = Physics2D.Raycast(groundChkBack.position, Vector2.down, chkDistance, g_Layer);
// 점프 상태에서 앞 또는 뒤쪽에 바닥이 감지되면 바닥에 붙어서 이동하게 변경
if (!isGround && (ground_front || ground_back))
rigid.velocity = new Vector2(rigid.velocity.x, 0);
// 앞 또는 뒤쪽의 바닥이 감지되면 isGround 변수를 참으로!
if (ground_front || ground_back)
isGround = true;
else
isGround = false;
anim.SetBool("isGround", isGround);
isWall = Physics2D.Raycast(wallChk.position,Vector2.right* isRight,wallchkDistance,w_layer);
anim.SetBool("isSliding",isWall);
// 스페이스바가 눌리면 점프 애니메이션을 동작
if (Input.GetAxis("Jump") != 0)
{
anim.SetTrigger("Jump");
}
// 방향키가 눌리는 방향과 캐릭터가 바라보는 방향이 다르다면 캐릭터의 방향을 전환.
if(!isWallJump)
if ((input_x > 0 && isRight < 0) || (input_x < 0 && isRight > 0))
{
FlipPlayer();
anim.SetBool("run", true);
}
else if (input_x == 0)
{
anim.SetBool("run", false);
}
//공격 마우스버튼
if(curTime <=0)
{
if (Input.GetMouseButton(0) &&
!anim.GetCurrentAnimatorStateInfo(0).IsName("Attack"))
{ curTime = coolTime;
anim.SetTrigger("Attack");
Collider2D[] collider2Ds = Physics2D.OverlapBoxAll ( pos.position , boxSize ,0);
foreach (Collider2D collider in collider2Ds)
{
if(collider.tag == "Enemy")
{ collider.GetComponent<Enemy>() .TakeDamage(1); }
}
}
}
else
{curTime -= Time.deltaTime;}
}
// Animation Events
// Called in slide animation.
void AE_SlideDust ()
{
Vector3 spawnPosition;
if (m_facingDirection == 1)
spawnPosition = groundChkBack.transform.position;
else
spawnPosition = groundChkFront.transform.position;
if (m_slideDust != null)
{
// Set correct arrow spawn position
GameObject dust = Instantiate(m_slideDust, spawnPosition, gameObject.transform.localRotation) as GameObject;
// Turn arrow in correct direction
dust.transform.localScale = new Vector3(m_facingDirection, 6, 1);
}
}
private void FixedUpdate()
{
// 캐릭터 이동
if(!isWallJump)
rigid.velocity = (new Vector2((input_x) * runSpeed , rigid.velocity.y));
if (isWall)
{
isWallJump = false;
rigid.velocity = new Vector2(rigid.velocity.x,rigid.velocity.y * slidingSpeed);
if(Input.GetAxis("Jump")!=0)
{isWallJump =true;
Invoke("FreezeX", 0.3f);
rigid.velocity = new Vector2( -isRight * wallJumpPower, 0.9f * wallJumpPower);
FlipPlayer();
}
}
}
void FreezeX()
{ isWallJump = false;}
void FlipPlayer()
{
// 방향을 전환.
transform.eulerAngles = new Vector3(0, Mathf.Abs(transform.eulerAngles.y - 180), 0);
isRight = isRight * -1;
}
// 바닥 체크 Ray를 씬화면에 표시
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawRay(groundChkFront.position, Vector2.down * chkDistance);
Gizmos.DrawRay(groundChkBack.position, Vector2.down * chkDistance);
Gizmos.color = Color.blue;
Gizmos.DrawRay(wallChk.position,Vector2.right * isRight * wallchkDistance);
Gizmos.color =Color.blue;
Gizmos.DrawWireCube (pos.position, boxSize);
}
}
void OnCollisionEnter, Update내 groundCheck가 둘다 있는 건 무슨 심보임?
내가 유니티는 모르지만 로직부터 다시짜는게어떠냐 못봐줄정도다 isGround 거짓이면 애초에 2단점프안되는데 무한점프가 되는것부터 이상하지않냐
유니티 유투브 보면서 공부한지 일주일정도 되었어요. 여러사람들꺼 복붙하면서 작동유무만 확인하다보니 정리를 어떻게 할지 지식이 없습니다...
그리고 isGround 는 거짓선언되지 않았고 케릭터 발바닥에 레이캐스트용이고
isGrounded 가 따로 false 로 되어있습니다.
플랫포머에서 가장 중요한 로직이 명확하지 않아 설명도 이해하기 힘든데 포기하고 하이퍼 캐쥬얼이나 만들거나 기초 실력이나 길러라
if (Input.GetAxis("Jump") != 0 ) 이거 연속으로 값 받게 돼서 한번만 눌렀다고 생각해도 여러 번 입력되가지고 jumpCount--; 이게 여러번 실행되는거임
Input.GetButtonDown 으로 입력받아보셈
if(Input.GetButtonDown("Jump") &&isGround || jumpCount>0) { 점프실행; jumpCount--;} 이렇게 해봐요
https://www.youtube.com/watch?v=lghplYxN7u8&t=329s
요거랑 다른 블로그글 보면서 성공했습니다. 이거 해결하는데 4시간걸렸네요. ㅎㅎ 감사합니다.
이러면서 배우는거지 화이팅