1. 기초 프로젝트 세팅 & 2D 이미지 설정하기
https://blog.naver.com/gold_metal/221609252536
위 강좌 따라하기.
리소스는 아래서 받을 수 있음.
https://assetstore.unity.com/packages/2d/characters/simple-2d-platformer-assets-pack-188518
2. 아틀라스 이용해서 Sprite Animation 적용하기
https://blog.naver.com/gold_metal/221613270615
- Animator Controller : 애니메이션을 관리하기 위한 컨트롤러
- Animation Clip : 애니메이션
-> 스프라이트의 애니메이션을 객체에 드래그하면 Animation Clip이 만들어진다. 이를 AnimatorController로 관리하면 됨.
* Window->Animation을 통해 애니메이션 키 프레임 애니메이션 관리
* Window->Animator를 통해 애니메이션 관리
아래와 같은 화면이 나옴.
특정 사건이 발생할 때 애니메이션의 흐름을 여기서 결정. (맞았거나, 공격할때, 움직일 때 등등)
위를 정리해놓은 상태. 초기엔 Entry->'Walk' 걷는 상태로 되어 있어 계속 걷는다.
내가 바꾸고 싶은 상태(State)에 마우스 우측->'Set as Layer Default State'를 누르면 초기 상태로 된다.
'Speed'를 통해 애니메이션 속도 조절 가능
3. 캐릭터 이동하기
https://blog.naver.com/gold_metal/221617701946
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
public float maxSpeed;
Rigidbody2D rigid;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
}
private void FixedUpdate()
{
//Move Speed
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
//Max Speed
if (rigid.velocity.x > maxSpeed)//Right
{
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
}
else if (rigid.velocity.x < maxSpeed*(-1)) //Left
{
rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
}
}
private void Update()
{
//Stop Speed
if(Input.GetButtonUp("Horizontal"))
{
rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.5f, rigid.velocity.y);
}
}
}
RigidBody에 force로 움직임 구현.
RigidBody->Freeze Rotate로 캐릭터 회전 막음
- 좌우 캐릭터 반전 : SpriteRenderer -> Flip<x/y>
//변수선언
SpriteRenderer spriteRenderer;
//Awake()
spriteRenderer = GetComponent<SpriteRenderer>();
//Update
//Direction Sprite
if (Input.GetButtonDown("Horizontal"))
{
spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
- 걸을 때 애니메이션 설정하기.
Animator창에서 Idle 마우스 우측-> MakeTransition, Walk 선택하여 연결.
Idle에서 다음 상태로 Walk를 설정함.
- Walk상태에 'Paramters'의 bool 형태의 'isWalk'변수 추가하기, 파라미터는 특정 상태가 되면 애니메이션이 변환됨을 의미하는 매개변수.
PlayerIdle->Walk 를 연결하는 연결선을 선택, Conditions에 추가한 매개변수를 추가한다.
isWalk가 true가 되었을 때 'Walk' 애니메이션이 재생됨을 의미.
- 마찬가지로 Walk에서 PlayerIdle상태로 변환되는 라인도 추가해준다.
아래와 같이 코드에 추가하면 된다.
Animator animator;
//Awake()
animator = GetComponent<Animator>();
//Update()
//Animation
if(Mathf.Abs(rigid.velocity.x) < 0.4)
{
animator.SetBool("isWalk", false);
}
else
{
animator.SetBool("isWalk", true);
}
4. 캐릭터 점프하기
public float jumpPower;
//Update
//Jump
if (Input.GetButtonDown("Jump"))
{
rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
}
* 중력값 조절
Edit->Project Settings -> Physics2D의 중력값(Gravity)을 조절 해도 되고,
캐릭터의 Rigidbody 2D의 Gravity Scale을 조절해도 됨.
- Gravity Scale : Object에 적용되는 중력값
- 마찬가지로 점프 애니메이션 만들어주기.
1) 스프라이트로 애니메이션 만들기
2) 애니메이터에서 상태 추가해주기
- 걷다가 뛰는경우, 가만히 있다 뛰는 경우 추가
- 점프에서 끝날 경우 원래 상태로 돌아가는 경우 추가
두 경우 isWalk, isJump state를 추가해서 관리.
**점프 후에 Idle상태로 돌리기
- Ray 기능을 활용해서 땅과 Ray가 충돌했을 경우 Idle로 돌린다.
FixedUpdate()함수에 추가
//Debugging ray
Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
//Ray Collider Check
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Platforms"));
if(rayHit.collider != null)
{
Debug.Log(rayHit.collider.name);
}
- Debug.DrawRay() : 디버깅용 레이 확인 가능
- RaycastHit2D : 실제 ray를 쏴서 출돌 검사.
마지막 인자 LayerMask.GetMask("마스크이름")을 넘겨주면, 설정한 레이어만 충돌을 검사한다.
- 오브젝트 선택후 우측, Inspector 위쪽에 Layers로 설정 가능
- 점프 후 추락시에만 raycast체크하기
//Ray Collider Check
if(rigid.velocity.y < 0)
{
//Debugging ray
Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Platforms"));
if (rayHit.collider != null)
{
if (rayHit.distance < 0.5f)
{
Debug.Log(rayHit.collider.name);
animator.SetBool("isJump", false);
}
}
}
- 무한 점프 막기 -> 점프중엔 점프 입력 막기
if (Input.GetButtonDown("Jump") && !animator.GetBool("isJump"))
{
rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
animator.SetBool("isJump", true);
}
=> 최종 코드
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
public float jumpPower;
public float maxSpeed;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator animator;
private void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
animator = GetComponent<Animator>();
}
private void FixedUpdate()
{
//Move Speed
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
//Max Speed
if (rigid.velocity.x > maxSpeed)//Right
{
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
}
else if (rigid.velocity.x < maxSpeed*(-1)) //Left
{
rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
}
//Ray Collider Check
if(rigid.velocity.y < 0)
{
//Debugging ray
Debug.DrawRay(rigid.position, Vector3.down, new Color(0, 1, 0));
RaycastHit2D rayHit = Physics2D.Raycast(rigid.position, Vector3.down, 1, LayerMask.GetMask("Platforms"));
if (rayHit.collider != null)
{
if (rayHit.distance < 0.5f)
{
Debug.Log(rayHit.collider.name);
animator.SetBool("isJump", false);
}
}
}
}
private void Update()
{
//Jump
if (Input.GetButtonDown("Jump") && !animator.GetBool("isJump"))
{
rigid.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
animator.SetBool("isJump", true);
}
//Stop Speed
if (Input.GetButtonUp("Horizontal"))
{
rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.5f, rigid.velocity.y);
}
//Direction Sprite
if (Input.GetButtonDown("Horizontal"))
{
spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
//Animation
if(Mathf.Abs(rigid.velocity.x) < 0.4)
{
animator.SetBool("isWalk", false);
}
else
{
animator.SetBool("isWalk", true);
}
}
}
최종 캐릭터 이동 실습
'Software Development > Unity' 카테고리의 다른 글
유니티 간보기 - 골드메탈 2D 따라하기_마지막 강의 (0) | 2022.02.05 |
---|---|
유니티 간보기 - 골드메탈 2D 따라하기_피격이벤트 (0) | 2022.02.05 |
유니티 간보기 - 골드메탈 2D 따라하기_몬스터기초 AI (0) | 2022.02.04 |
유니티 간보기 - 골드메탈 2D 따라하기_타일맵 (0) | 2022.02.04 |
유니티 기초 - 씬(Scene) 전환하기 (0) | 2022.02.04 |