유니티/팀프로젝트 프로젝트-J
11-25 일지 회의록 및 사다리 오르내리기까지 완료
hyunjin-dev-log
2022. 1. 18. 20:26
캐릭터가 사다리를 타는기능 변경사항
- 사다리에 태그하자마자 사다리에 매달림 -> 사다리 태그 후 조이스틱을 위,
아래키를 입력받아 사다리에 매달림
- 캐릭터가 매달려있을 시 애니메이션 추가
- 매달린상태에서 점프가 가능하고 점프키를 눌러야만 매달린상태에서
벗어난다
캐릭터의 앉기키관련 토의
- 앉기상태의 캐릭터 구현 : 상체와 머리부분을 낮추고 머리부분을 약간 앞으로
뺀다
- 앉기상태는 앉기버튼을 입력하여 온오프방식으로 구현
- 앉기키를 다시 입력하거나 점프키를 입력시 앉기상태를 해제함
사다리를 올라가서 위의 발판에 착지한다음 다시 내려오려할때 발판때문에 막혀서 못내려오게 되버렸다.
사다리에 스크립트를 붙여 플레이어와 접촉하는중에 플레이어가 위아래로 이동하려할경우 작동하게하는 방법을 찾았었는데 현재 문제의 해결법이 아니었다
더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ladder : MonoBehaviour
{
public PlayerControll player;
Rigidbody2D playerRigidbody;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.tag == "Player")
{
this.playerRigidbody = collision.GetComponent<Rigidbody2D>();
}
if (collision.tag == "Player" && player.V == 1)
{
this.playerRigidbody.velocity = new Vector2(0, 2);
this.playerRigidbody.gravityScale = 0;
}
else if (collision.tag == "Player" && player.V == -1)
{
this.playerRigidbody.velocity = new Vector2(0, -2);
this.playerRigidbody.gravityScale = 0;
}
else
{
this.playerRigidbody.velocity = new Vector2(0, 0);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.tag == "Player")
{
this.playerRigidbody = collision.GetComponent<Rigidbody2D>();
this.playerRigidbody.gravityScale = 1;
}
}
}
사다리에 매달려있는 상태라면
사다리에 접해있는 발판의 콜라이더를 끄는 방법으로 해결했다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ladder : MonoBehaviour
{
public Collider2D platformCollider;
public PlayerControll player;
private void OnTriggerStay2D(Collider2D collision)
{
if (collision.tag == "Player" && this.player.NowHangOn == true)
{
Physics2D.IgnoreCollision(collision.GetComponent<Collider2D>(), this.platformCollider, true);
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.tag == "Player" && this.player.NowHangOn == false)
{
Physics2D.IgnoreCollision(collision.GetComponent<Collider2D>(), this.platformCollider, false);
}
}
}
뛸때와 점프할때의 애니메이션 재생이나, 매달렸을때의 캐릭터의 모습변화같은
하나하나는 실제로는 중요도가 높지않은 디테일적인 부분이 모이고모여서 그럴싸해진거같다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControll : MonoBehaviour
{
public MyJoystick joystick;
[SerializeField]
private float jumpForce = 200;
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.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;
}
//살아있고 매달려있다면 움직임
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();
}
}
}
//점프애니메이션을 그만 재생하기위해 레이
Debug.DrawRay(this.rbody.position, Vector2.down, Color.blue);
if (this.rbody.velocity.y <= 0)
{
RaycastHit2D rayHitDown = Physics2D.Raycast(this.rbody.position, Vector2.down, 1f, LayerMask.GetMask("Platform"));
if (rayHitDown.collider != null)
{
if (rayHitDown.distance < 1f)
{
//Debug.Log(rayHit.collider.name);
anim.SetBool("isJumping", false);
}
}
}
}
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();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class MyJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
public GameObject decoTop;
public GameObject decoLeft;
public GameObject decoRight;
public GameObject decoBottom;
private FloatingJoystick joystick;
public UnityAction<Vector2> OnDragAction;
public UnityAction OnDownAction;
public UnityAction OnUpAction;
void Start()
{
this.joystick = this.GetComponent<FloatingJoystick>();
this.joystick.SnapX = true;
this.joystick.SnapY = true;
this.AllDecoDisable();
}
public void OnDrag(PointerEventData eventData)
{
//Debug.Log(this.joystick.Direction);
var dir = this.joystick.Direction;
var dirX = dir.x;
var dirY = dir.y;
if (dirY == 1 && dirX == 1)
{
this.AllDecoDisable();
this.decoRight.SetActive(true);
this.decoTop.SetActive(true);
}
else if (dirY == 1 && dirX == -1)
{
this.AllDecoDisable();
this.decoTop.SetActive(true);
this.decoLeft.SetActive(true);
}
else if (dirY == -1 && dirX == 1)
{
this.AllDecoDisable();
this.decoBottom.SetActive(true);
this.decoRight.SetActive(true);
}
else if (dirY == -1 && dirX == -1)
{
this.AllDecoDisable();
this.decoLeft.SetActive(true);
this.decoBottom.SetActive(true);
}
else if (dirY == 1)
{
this.AllDecoDisable();
this.decoTop.SetActive(true);
}
else if (dirY == -1)
{
this.AllDecoDisable();
this.decoBottom.SetActive(true);
}
else if (dirX == 1)
{
this.AllDecoDisable();
this.decoRight.SetActive(true);
}
else if (dirX == -1)
{
this.AllDecoDisable();
this.decoLeft.SetActive(true);
}
this.OnDragAction(this.joystick.Direction);
}
private void AllDecoDisable()
{
this.decoTop.SetActive(false);
this.decoLeft.SetActive(false);
this.decoBottom.SetActive(false);
this.decoRight.SetActive(false);
}
public void OnPointerUp(PointerEventData eventData)
{
this.AllDecoDisable();
this.OnUpAction();
}
public void OnPointerDown(PointerEventData eventData)
{
this.OnDownAction();
}
}
참고한 영상
https://www.youtube.com/watch?v=chGYyJcpJTA&t=322s
https://www.youtube.com/watch?v=2SikOdH7xvQ&list=PLO-mt5Iu5TeZGR_y6mHmTWyo0RyGgO0N_&index=5