아래 3D강좌 기반 공부 시작
-캐릭터 기본 조작
- 캐릭터 컨트롤 하기. 객체에 일단 RigidBody+Capsule Collider 넣고 시작.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed;
float hAxis;
float vAxis;
bool wDown;
Vector3 moveVec;
Animator animator;
void Awake()
{
animator = GetComponentInChildren<Animator>();
}
void Update()
{
hAxis = Input.GetAxisRaw("Horizontal");
vAxis = Input.GetAxisRaw("Vertical");
wDown = Input.GetButton("Walk");
moveVec = new Vector3(hAxis, 0, vAxis).normalized;
transform.position += moveVec * speed * (wDown ? 0.3f : 1f) * Time.deltaTime;
animator.SetBool("isRun", moveVec != Vector3.zero);
animator.SetBool("isWalk", wDown);
transform.LookAt(transform.position + moveVec);
}
}
- Input System : Edit->Project Settings->Input Manager 에서 받아오는 값.
여기서 Size를 추가하여 'Walk'라는 새로운 인풋 추가, Shift입력 받아 올 경우 걷게 구현.
아래 코드로 캐릭터 이동 구현.
hAxis = Input.GetAxisRaw("Horizontal");
vAxis = Input.GetAxisRaw("Vertical");
moveVec = new Vector3(hAxis, 0, vAxis).normalized;
transform.position += moveVec * speed * Time.deltaTime;
아래 코드로 입력에 따라 캐릭터 방향 회전 설정
transform.LookAt(transform.position + moveVec);
wDown 입력시 속도를 늦춰 걷는 속도 설정
wDown = Input.GetButton("Walk");
transform.position += moveVec * speed * (wDown ? 0.3f : 1f) * Time.deltaTime;
isRun이나 isWalk는 Animator Controller에서 3D 모델링 기준 애니메이션 설정인데,
이전 강의의 2D 게임 Sprite Animation과 사용 방법이 동일하다.
* 객체간 충돌 체크를 좀더 정확하게 하려면?
- 캐릭터 객체 선택, 'Rigidbody'의 'Collision Detection'을 'Continuous'로 설정.
- 충돌 대상이 되는 객체(Floor, Wall)은 Inspector의 'Static'으로 설정할 것.
Rigidbody를 추가하고 Use Gravity 해제, IsKinematic 설정할 것.
- 벽에는 Physic Material 추가하기
- 카메라가 캐릭터 따라오게 하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follow : MonoBehaviour
{
public Transform target;
public Vector3 offset;
void Update()
{
transform.position = target.position + offset;
}
}
위 스크립트를 카메라에 붙여준다.
target에 캐릭터를 입력.
offset은 캐릭터를 기준으로 떨어진 위치. 입력값(0, 21, -11)
기본 조작 완성
- 캐릭터 점프와 회피
https://youtu.be/eZ8Dm809j4c
- 코드 정리로 시작, 함수로 묶기.
void Update()
{
GetInput();
Move();
Turn();
}
void GetInput()
{
hAxis = Input.GetAxisRaw("Horizontal");
vAxis = Input.GetAxisRaw("Vertical");
wDown = Input.GetButton("Walk");
}
void Move()
{
moveVec = new Vector3(hAxis, 0, vAxis).normalized;
transform.position += moveVec * speed * (wDown ? 0.3f : 1f) * Time.deltaTime;
animator.SetBool("isRun", moveVec != Vector3.zero);
animator.SetBool("isWalk", wDown);
}
void Turn()
{
transform.LookAt(transform.position + moveVec);
}
- 점프 만들기
//변수추가
bool isJump;
Rigidbody rigid;
//Input- 점프 입력 추가
jDown = Input.GetButton("Jump");
//Jump 함수 추가
void Jump()
{
//점프가 눌릴때 && 점프중이 아닐때
if (jDown && !isJump)
{
//위로 AddForce
rigid.AddForce(Vector3.up * 20, ForceMode.Impulse);
//설정한 Animation paramter:isJump & doJump trigger
animator.SetBool("isJump", true);
animator.SetTrigger("doJump");
isJump = true;
}
}
//바닥 충돌 검사
private void OnCollisionEnter(Collision collision)
{
//바닥 tag Floor 추가하기
if (collision.gameObject.tag == "Floor")
{
//바닥에 닿은경우 점프 끝.
animator.SetBool("isJump", false);
isJump = false;
}
}
아래와 같이 애니메이션 추가, 설정
- DoJump trigger 발생시 Jump 애니메이션
- Jump종료(바닥에 닿을 경우), isJump가 false가 되면서 착지 애니메이션
- 착지 애니메이션은 'HasExitTime'체크 설정 해두어야 그대로 애니메이션 종료
- Dodge(회피) 시스템 추가
bool isDodge;
Vector3 dodgeVec;
void Update()
{
GetInput();
Move();
Turn();
Jump();
Dodge();
}
void Move()
{
moveVec = new Vector3(hAxis, 0, vAxis).normalized;
if(isDodge)
{
moveVec = dodgeVec;
}
transform.position += moveVec * speed * (wDown ? 0.3f : 1f) * Time.deltaTime;
animator.SetBool("isRun", moveVec != Vector3.zero);
animator.SetBool("isWalk", wDown);
}
void Jump()
{
if (jDown && moveVec == Vector3.zero && !isJump && !isDodge)
{
rigid.AddForce(Vector3.up * 12, ForceMode.Impulse);
animator.SetBool("isJump", true);
animator.SetTrigger("doJump");
isJump = true;
}
}
void Dodge()
{
if (jDown && moveVec != Vector3.zero && !isJump && !isDodge)
{
dodgeVec = moveVec;
speed *= 2;
animator.SetTrigger("doDodge");
isDodge = true;
Invoke("DodgeOut", 0.6f);
}
}
void DodgeOut()
{
isDodge = false;
speed *= 0.5f;
}
- 닷지는 이동 중 점프 키가 눌렸을 때 동작
- 점프는 제자리에 가만히 있을 때만 동작
- 닷지와 점프는 동시에 발생하지 않도록 처리
- 닷지 시 속도 증가,. 닷지 애니메이션 발동. 닷지 끝나는건 Invoke로 타임설정
- 닷지 시 이동 벡터 저장해서 닷지중 이동 키가 눌려도 자연스럽게 설정
완성.
캐릭터 전체 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed;
float hAxis;
float vAxis;
bool wDown;
bool jDown;
bool isJump;
bool isDodge;
Vector3 moveVec;
Vector3 dodgeVec;
Rigidbody rigid;
Animator animator;
void Awake()
{
rigid = GetComponent<Rigidbody>();
animator = GetComponentInChildren<Animator>();
}
void Update()
{
GetInput();
Move();
Turn();
Jump();
Dodge();
}
void GetInput()
{
hAxis = Input.GetAxisRaw("Horizontal");
vAxis = Input.GetAxisRaw("Vertical");
wDown = Input.GetButton("Walk");
jDown = Input.GetButton("Jump");
}
void Move()
{
moveVec = new Vector3(hAxis, 0, vAxis).normalized;
if(isDodge)
{
moveVec = dodgeVec;
}
transform.position += moveVec * speed * (wDown ? 0.3f : 1f) * Time.deltaTime;
animator.SetBool("isRun", moveVec != Vector3.zero);
animator.SetBool("isWalk", wDown);
}
void Turn()
{
transform.LookAt(transform.position + moveVec);
}
void Jump()
{
if (jDown && moveVec == Vector3.zero && !isJump && !isDodge)
{
rigid.AddForce(Vector3.up * 12, ForceMode.Impulse);
animator.SetBool("isJump", true);
animator.SetTrigger("doJump");
isJump = true;
}
}
void Dodge()
{
if (jDown && moveVec != Vector3.zero && !isJump && !isDodge)
{
dodgeVec = moveVec;
speed *= 2;
animator.SetTrigger("doDodge");
isDodge = true;
Invoke("DodgeOut", 0.6f);
}
}
void DodgeOut()
{
isDodge = false;
speed *= 0.5f;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Floor")
{
animator.SetBool("isJump", false);
isJump = false;
}
}
}
'Software Development > Unity' 카테고리의 다른 글
유니티 3D 간보기 - 골드메탈 3D강좌:아이템 처리/수류탄 장착 구현 (0) | 2022.02.06 |
---|---|
유니티 3D 간보기 - 골드메탈 3D강좌:아이템 먹기/장착 (0) | 2022.02.06 |
유니티 간보기 - 골드메탈 2D 따라하기_마지막 강의 (0) | 2022.02.05 |
유니티 간보기 - 골드메탈 2D 따라하기_피격이벤트 (0) | 2022.02.05 |
유니티 간보기 - 골드메탈 2D 따라하기_몬스터기초 AI (0) | 2022.02.04 |