본문 바로가기

유니티/팀프로젝트 프로젝트-J

UI버튼으로 점프하기

 

 

조이스틱을 조작하면서 점프버튼을 누르기 어려워서

WASD로 이동할수있게끔 테스트환경을 갖췄다.

그랬더니 사다리를 내려갈때 바닥에 닿을때 자동으로 매달려있는상태 해제를 또 못하겠다

그리고 점프를 계속누르면서 한층 높은곳에 올라가면 바닥에 닿기전에 점프가 되고 점프력은 작아지는둥,

이전부터 있었던 점프에서의 예외상황도 한번 수정할수있게끔 시도해봐야겠다.

 

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PlayerControll : MonoBehaviour
{
    public MyJoystick joystick;
    public Transform bottomPos;
    public Transform topPos;
    public Button btnJump;

    [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.btnJump.onClick.AddListener(() =>
        {
            if (this.isAllive && this.onGround && this.anim.GetBool("isJumping") == false)
            {
                this.Jump();
            }
            else if (this.isAllive && this.NowHangOn && this.anim.GetBool("isJumping") == false)
            {
                //매달린상태 해제하고 점프
                this.Init();
                this.Jump();
            }
        });
        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();
        //}

        //테스트용 A,B,S,D 이동

        if (this.isAllive && this.onGround)
        {
            if (Input.GetKey(KeyCode.A))
            {
                this.anim.SetBool("isRunning", true);
                this.h = -1;
                this.transform.localScale = new Vector3(-1, 1, 1);
            }
            else if (Input.GetKey(KeyCode.D))
            {
                this.anim.SetBool("isRunning", true);
                this.h = 1;
                this.transform.localScale = new Vector3(1, 1, 1);
            }
            else if (Input.GetKey(KeyCode.W))
            {
                this.v = 1;
            }
            else if (Input.GetKey(KeyCode.S))
            {
                this.v = -1;
            }
            else
            {
                this.anim.SetBool("isRunning", false);
                this.h = 0;
                this.v = 0;
            }

            Vector2 dir = new Vector2(this.h, 0);   //상하이동은 하지않는다
            this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        }
        if (this.isAllive && this.NowHangOn)
        {
            //매달려있을때
            if (Input.GetKey(KeyCode.W))
            {
                this.v = 1;
                //위로 사다리를 감지하는 레이
                RaycastHit2D rayHitUp = Physics2D.Raycast(this.bottomPos.position, Vector3.up, 1, LayerMask.GetMask("Ladder"));
                if (rayHitUp.collider != null && this.canHangOn)
                {
                    //사다리가 있고 매달릴수 있는 상태라면 매달린다
                    this.ChangeHangonForm();
                }
                else
                {
                    //아니라면 매달린상태 해제
                    this.Init();
                }
            }
            else if (Input.GetKey(KeyCode.S))
            {
                this.v = -1;
                //밑으로 사다리를 감지하는 레이
                RaycastHit2D rayHitDown = Physics2D.Raycast(this.bottomPos.position, Vector3.down, 1, LayerMask.GetMask("Ladder"));
                if (rayHitDown.collider != null)
                {
                    //사다리가 있다면 매달린다
                    this.ChangeHangonForm();

                }
                else
                {
                    //사다리가 없다면 매달린상태 해제
                    this.Init();
                }
            }
            else
            {
                this.v = 0;
            }

            Vector2 dir = new Vector2(0, this.v);   //좌우는 이동하지 않는다
            this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        }


        //매달릴수있는 상태에서 위 또는 아래로 이동하려한다면
        if (this.canHangOn && this.v != 0)
        {
            //매달린 상태로 변경
            this.ChangeHangonForm();
        }

        //살아있고 매달려있을때의 움직임
        //if (this.isAllive && this.NowHangOn)
        //{
        //    //점프하려한다면
        //    //if (Input.GetKeyDown(KeyCode.Space))
        //    //{
        //    //    if (this.anim.GetBool("isJumping") == false)
        //    //    {
        //    //        //매달린상태 해제하고 점프
        //    //        this.Init();
        //    //        this.Jump();
        //    //    }
        //    //}

        //    //조이스틱을 위아래로 움직일때
        //    if (this.v == -1)
        //    {
        //        //밑으로 사다리를 감지하는 레이
        //        RaycastHit2D rayHitDown = Physics2D.Raycast(this.bottomPos.position, Vector3.down, 1, LayerMask.GetMask("Ladder"));
        //        if (rayHitDown.collider != null)
        //        {
        //            //사다리가 있다면 매달린다
        //            this.ChangeHangonForm();

        //        }
        //        else
        //        {
        //            //사다리가 없다면 매달린상태 해제
        //            this.Init();
        //        }
        //    }
        //    if (this.v == 1)
        //    {
        //        //위로 사다리를 감지하는 레이
        //        RaycastHit2D rayHitUp = Physics2D.Raycast(this.bottomPos.position, Vector3.up, 1, LayerMask.GetMask("Ladder"));
        //        if (rayHitUp.collider != null && this.canHangOn)
        //        {
        //            //사다리가 있고 매달릴수 있는 상태라면 매달린다
        //            this.ChangeHangonForm();
        //        }
        //        else
        //        {
        //            //아니라면 매달린상태 해제
        //            this.Init();
        //        }
        //    }

        //    Vector2 dir = new Vector2(0, this.v);   //좌우는 이동하지 않는다
        //    this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        //}

        //에디터상에서만 보이는 레이
        Debug.DrawRay(this.rbody.position, Vector3.down, Color.blue);

        //점프애니메이션을 그만 재생하기위해 레이
        if (this.rbody.velocity.y <= 0)
        {
            RaycastHit2D hitPlatform = Physics2D.Raycast(this.bottomPos.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();
        }
    }
}