유니티/팀프로젝트 프로젝트-J
사다리 예외상황
hyunjin-dev-log
2022. 1. 18. 20:26
사다리를 레이로 감지하여 해결하려 했지만 해결되지않음
//레이로 매달릴수있는 사다리 감지
RaycastHit2D hitLadder = Physics2D.Raycast(this.rbody.position, Vector3.up, 1, LayerMask.GetMask("Ladder"));
if (hitLadder.collider != null)
{
if (hitLadder.distance < 1f)
{
//Debug.Log(hitLadder.collider.name);
this.canHangOn = true;
}
}
else
{
this.canHangOn = false;
this.Init();
}
다음 코드를 추가하면 위의 발판에서 내려오질 못함
//아래로 내려간다면
if (this.v == -1)
{
//레이를 그리고
RaycastHit2D rayHitDown = Physics2D.Raycast(this.rbody.position, Vector3.down, 1, LayerMask.GetMask("Platform"));
if (rayHitDown.collider != null)
{
//발판을 감지했고 거리가 가깝다면
if (rayHitDown.distance < 0.8f)
{
//Debug.Log(rayHit.collider.name);
//매달린상태 해제
this.Init();
}
}
}
사다리를 내려갈때 타일에 가까워지면 통상 상태로 변경하는데는 성공했으나,
사다리를 오르고나서도 조이스틱을 위쪽으로 하면 사다리의 콜라이더와 접촉하고있어서 떨리는현상은 해결하지못함
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControll : MonoBehaviour
{
public MyJoystick joystick;
public Transform rayDownPosition;
public Transform rayUpPosition;
[SerializeField]
private float jumpForce = 5;
private bool isAllive = true;
private bool onGround = true;
private bool canHangOn = false;
public bool NowHangOn { get; private set; }
private int v;
private int h;
[SerializeField]
private float moveSpeed = 2.0f;
Rigidbody2D rbody;
Animator anim;
void Start()
{
this.rbody = this.GetComponent<Rigidbody2D>();
this.anim = this.transform.Find("sword_man").GetComponent<Animator>();
this.anim.Play("Idle");
this.Init();
this.joystick.OnDragAction = (dir) =>
{
//Debug.Log(dir);
if (dir.x == 1)
{
this.h = 1;
}
else if (dir.x == -1)
{
this.h = -1;
}
else if (dir.x == 0)
{
this.h = 0;
}
if (dir.y == 1)
{
this.v = 1;
}
else if (dir.y == -1)
{
this.v = -1;
}
else if (dir.y == 0)
{
this.v = 0;
}
};
this.joystick.OnDownAction = () =>
{
//Debug.Log("down");
};
this.joystick.OnUpAction = () =>
{
//Debug.Log("up");
this.v = 0;
this.h = 0;
};
}
void Init()
{
//초기화
this.onGround = true;
this.NowHangOn = false;
this.transform.Find("sword_man").gameObject.SetActive(true);
this.transform.Find("back").gameObject.SetActive(false);
this.rbody.gravityScale = 1;
}
private void FixedUpdate()
{
//살아있고 땅을 밟고있을경우의 움직임
if (this.isAllive && this.onGround && this.h != 0)
{
this.anim.SetBool("isRunning", true);
//캐릭터가 이동방향을 바라본다
if (this.h == -1)
{
this.transform.localScale = new Vector3(-1, 1, 1);
}
else if (this.h == 1)
{
this.transform.localScale = new Vector3(1, 1, 1);
}
Vector2 dir = new Vector2(this.h, 0); //상하이동은 하지않는다
this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
}
//Run애니메이션 중지
if (this.isAllive && this.onGround && this.h == 0)
{
this.anim.SetBool("isRunning", false);
}
//점프
if (this.isAllive && this.onGround && Input.GetKeyDown(KeyCode.Space) && this.anim.GetBool("isJumping") == false)
{
this.Jump();
}
//매달릴수있는 상태에서 위 또는 아래로 이동하려한다면
if (this.canHangOn && this.v != 0)
{
//매달린 상태로 변경
this.ChangeHangonForm();
}
//살아있고 매달려있을때의 움직임
if (this.isAllive && this.NowHangOn)
{
Vector2 dir = new Vector2(0, this.v); //좌우는 이동하지 않는다
this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
//점프하려한다면
if (Input.GetKeyDown(KeyCode.Space))
{
if (this.anim.GetBool("isJumping") == false)
{
//매달린상태 해제하고 점프
this.Init();
this.Jump();
}
}
//조이스틱을 위아래로 움직일때
else if (this.v == -1)
{
//밑으로 사다리를 감지하는 레이
RaycastHit2D rayHitDown = Physics2D.Raycast(this.rayDownPosition.position, Vector3.down, 1, LayerMask.GetMask("Ladder"));
if (rayHitDown.collider != null)
{
//사다리가 있다면 매달린다
this.ChangeHangonForm();
}
else
{
//사다리가 없다면 매달린상태 해제
this.Init();
}
}
else if (this.v == 1)
{
//위로 사다리를 감지하는 레이
RaycastHit2D rayHitUp = Physics2D.Raycast(this.rayDownPosition.position, Vector3.up, 1, LayerMask.GetMask("Ladder"));
if (rayHitUp.collider != null && this.canHangOn)
{
//사다리가 있고 매달릴수 있는 상태라면 매달린다
this.ChangeHangonForm();
}
else
{
//아니라면 매달린상태 해제
this.Init();
}
}
}
//에디터상에서만 보이는 레이
Debug.DrawRay(this.rbody.position, Vector3.down, Color.blue);
//점프애니메이션을 그만 재생하기위해 레이
if (this.rbody.velocity.y <= 0)
{
RaycastHit2D hitPlatform = Physics2D.Raycast(this.rayDownPosition.position, Vector3.down, 1, LayerMask.GetMask("Platform"));
if (hitPlatform.collider != null)
{
if (hitPlatform.distance < 0.5f)
{
//Debug.Log(hitPlatform.collider.name);
anim.SetBool("isJumping", false);
}
}
}
}
void ChangeHangonForm()
{
this.NowHangOn = true;
this.onGround = false;
this.transform.Find("sword_man").gameObject.SetActive(false);
this.transform.Find("back").gameObject.SetActive(true);
this.rbody.velocity = Vector2.zero;
this.rbody.gravityScale = 0;
}
void Jump()
{
this.anim.SetBool("isJumping", true);
this.rbody.AddForce(Vector2.up * this.jumpForce, ForceMode2D.Impulse);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Ladder")
{
this.canHangOn = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.tag == "Ladder")
{
this.canHangOn = false;
this.Init();
}
}
}