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();
        }
    }
}