//출처는 골드메탈님 강의입니다!
강의 시간 - 6:30
복습 - 10:25 고고..23:40 완료
중요한 것이 GetButtonDown 인지 GetButton인지 용도에 맞게 사용해야 한다.
스페이스바 + 눌렀을 때에만 단 한번 실행하므로
Input.GetButtonDown("Jump") 를 사용한다.
한 번 동작 후 착지 할때 다시 뛸수 있게 하기 위해서 불변수를 추가하자
여기서 사용되는 불변수는 키입력값 불변수와는 다르므로 새로운 변수를 선언하자.
바닥 충돌에 따른 충돌이나 트리거 처리를 해야한다.
1) 충돌 처리는 물리적인 충돌 결과가 따라온다.
2) 트리거 처리는 물리적인 충돌 결과 없이 해당 오브젝트를 통과한다.
-> 즉 여기서는 바닥과의 충돌 처리이므로 OnCollision 계열의 함수를 사용하자.
파라미터를 추가하자.
트리거 변수 2개와 점프완료를 판단할 불변수 1개 추가함.
점프와 회피는 언제든 해야 하므로 Any State에 연결하자.
일회성 애니메이션이므로 Trigger 파라미터를 사용하자.
즉발적으로 애니메이션 동작시키려고 하므로 duration을 0으로 놓자.
Exit 나갈때는 Trigger를 설정할 수 없으므로 HasExitTime을 체크해놓자.
Dodge 동작 마친 후 바로 Exit가 실행된다.
점프는 독특하게 점프와 착륙(land) 동작이 실행되야 한다.
중력값 변경함.
Dodge 속도 올림.
3으로 해야 타이밍 맞다.
static 눌러서 자식 모두 정적으로 변경하자.
정적으로 왜 바꾸냐? 플레이어에서 물리 충돌을 무시하지 않도록
리지드바디에서 continuous를 사용했다.
continuous는 static과 충돌할 때 효과적이다.
: 마찰력이 없는 벽을 만들기 위해 Physics Material을 추가하자.
마찰력은 최소로
움직임을 조건으로 추가해서 점프와 회피를 나눈다.
회피는 점프 후 Invoke함수를 사용해 일정 시간이 지난후 실행하도록 하자.
Invoke("함수명", 시간값)
//player.cs
//코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
Animator anim;
Rigidbody rigid;
Vector3 moveVec;
Vector3 DodgeVec;
float h;
float v;
public float speed;
bool wDown;
bool jDown; // 키 입력에 따른 불변수
bool isJump;
bool isDodge;
private void Awake()
{
rigid = GetComponent<Rigidbody>();
anim = GetComponentInChildren<Animator>();
}
void Update()
{
GetInput();
Move();
Turn();
Jump();
Dodge();
}
void GetInput()
{
h = Input.GetAxis("Horizontal");
v = Input.GetAxis("Vertical");
wDown = Input.GetButton("Walk");
jDown = Input.GetButtonDown("Jump");
}
void Move()
{
moveVec = new Vector3(h, 0, v).normalized;
//회피 중에 무브시에 다른방향 전환하는 것을 방지함.
if (isDodge)
moveVec = DodgeVec;
transform.position += moveVec * (wDown ? 0.3f : 1.0f) * Time.deltaTime * speed;
anim.SetBool("run", moveVec != Vector3.zero);
anim.SetBool("walk", wDown);
}
void Turn()
{
transform.LookAt(moveVec + transform.position);
}
void Jump()
{
//점프 중에 회피 하는 것을 방지.
if (jDown && !isJump && moveVec == Vector3.zero && !isDodge)
{
rigid.AddForce(Vector3.up * 20.0f, ForceMode.Impulse);
anim.SetBool("isJump", true);
anim.SetTrigger("do_Jump");
isJump = true;
}
}
void Dodge()
{
if (jDown && !isJump && moveVec != Vector3.zero && !isDodge)
{
DodgeVec = moveVec;
speed *= 2;
anim.SetTrigger("do_Dodge");
isDodge = true;
//Invoke 함수로 시간차 함수를 호출함.
//"함수명", 시간차를 매개변수로 사용한다.
Invoke("DodgeOut", 0.4f);
}
}
//트리거 처리가 아닌 충돌처리로 해야한다.
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Floor")
{
isJump = false;
anim.SetBool("isJump", false);
}
}
//시간차를 줘서 회피를 완료하는 기능
void DodgeOut()
{
isDodge = false;
speed *= 0.5f;
}
}