유니티:캐릭터 이동

학교의 모든 지식. SMwiki
Sam (토론 | 기여)님의 2021년 8월 12일 (목) 22:55 판 (→‎점프)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)
둘러보기로 이동 검색으로 이동

틀:유니티

  1. 유니티:개요
  2. 유니티:기본 조작
    1. 유니티:에셋스토어
  3. 유니티:카메라
  4. 유니티:오브젝트
    1. 유니티:데이터 입력받기
    2. 유니티:오브젝트 이동(오브젝트 조작)
    3. 유니티:힘으로 오브젝트 이동
    4. 유니티:충돌 이벤트
    5. 유니티:오브젝트 작성 tip
    6. 유니티:프리팹
  5. 유니티:코딩기초
    1. 유니티:C sharp 코딩 편의기능
    2. 유니티:MonoBehaviour
    3. 유니티:이벤트 메서드
    4. 유니티:컴포넌트 조작하기
  6. 유니티:UI
  7. 유니티:게임 내 화면
  8. 유니티:플레이어
    1. 유니티:모델
    2. 유니티:캐릭터 이동
    3. 유니티:애니메이션
    4. 유니티:주인공 시점
  9. 유니티:맵
    1. 유니티:투명한 벽 만들기
    2. 유니티:내비게이션
  10. 유니티:씬
  11. 유니티:몬스터
  12. 유니티:아이템
  13. 유니티:음향
    1. 유니티:배경음
    2. 유니티:효과음
  14. 유니티:빌드
  15. 유니티:VR
    1. 유니티:VR:UI
    2. 유니티:VR:VR로 변환
  16. 유니티:팁

개요

스크립트를 만든다.

public변수로 두면 인스펙터에서 편집할 수 있다.

public  class Move : MonoBehaviour{
    public float maxSpeed;
    Rigidbody rigid;
    
    void FixedUpdate(){
        float h=Input.GetAxisRaw("Horizontal");
        rigid.AddForce(벡터, 모드)
        if(rigid.velocity.x > masSpeed)//우측에 대한 스피드.
            rigid.velocity=new Vector3(masSpeed, rigid.velocity.y);
        else if(rigid.velocity.x < masSpeed*(-1))//좌측에 대한 스피드
        ...

일반적으로 타이밍이 중요한 단발적인 키 입력은 Update에서 다룬다.(프레임이 더 촘촘해)

현실적인 움직임.

rigidbody에서 Linear Drag는 공기저항의 역할을 한다.(접촉하지 않을 때의 저항)


이동

벡터

이동을 구현하기 위해선 Rigidbody의 Velocity에 변화를 주어야 한다. 이는 Vector3 형태이기에 그 형태에 맞는 값을 지정해주어야 한다.

코드구현

public  class PalyerMove : MonoBehaviour{
    public Rigidbody playerRigidbody;  // 플레이어의 물리.
    public float playerSpeed;  // 이동속도.

이동을 구현하기 위해 Rigidbody의 addForce를 사용하거나 Velocity를 사용하는데, addForce는 힘을 가하기 때문에 관성의 영향을 그대로 받고, Velocity는 속력을 즉각 반영한다는 특징이 있다.

코드구현이 끝난 후

Rigidbody를 public으로 지정한 경우, 인스펙터 창에 나타난 PlayerRigidbody에 컴포넌트를 드래그&드롭 해주어 물리를 적용한다.

애니메이션 조작

방향에 따라 캐릭터가 바라보는 곳을 바꾸게끔 만들어야 한다.


점프

단발적인 조작이기에, Update에 두는 편이 좋다. 아래와 같은 형식으로 코딩한다.

오디오 컴포넌트에 오디오 소스 따위를 넣어주는 작업, 애니메이션 작업 등은 이미 마쳤다고 가정한다.

privarte Rigidbody playerRigidbody;  // 컴포넌트를 받을 변수를 만들어둔다.
private Animator animator;  // 애니메이터를 받을 변수를 만들어둔다.
private AudioSource playerAudio;  // 재생할 오디오를 받을 변수.
private int jumpCount = 0;  // 점프 횟수를 기록하기 위한 변수.
public int jumpForce;  // 점프력을 기록하기 위한 변수.
private bool isGrounded = false;  // 땅에 접해있는가 여부를 결정하는 변수
public AudioClip 사용할 오디오 클립;  // 나중에 사용할 오디오클립을 담아둬서 바꾸어 사용할 수 있다.

private void Start() {
    playerRigidbody = GetComponent<Rigidbody>();  // 플레이어의 리지드바디를 가져온다.
    animator = GetComponent<Animator>();  // 애니메이터를 가져온다.
    playerAudio = GetComponent<AudioSource>();  // 오디오소스를 가져온다.
    }

private void Update() {
    if(Input.GetButtonDown("Jump")  && jumpCount<2 ) { // 점프키를 받고, 점프가 2회 이하이면,
        jumpCount++;  // 점프횟수를 추가하고..
        playerRigidbody.velocity = Vector3.zero;  // 속도를 0으로 만든다.(게임을 위한 장치)
        playerRigidbody.AddForce(new Vector3(0,jumpForce,0));  // 점프력을 더한다.
        playerAudio.Play();  // 효과음을 실행한다.
        }
    // 점프 도중에 버튼을 떼면 점프를 낮게 하는 걸 구현하고자 할 때 다음의 조건문을 넣는다.
    else if (Input.GetButtonUp("Jump")  && playerRigidbody.velocity.y>0)  // 점프 도중에 버튼을 떼면..
        {  // 위로 향하는 속도가 있을 때에만 속력을 줄인다.
        playerRigidbody.velocity = playerRigidbody.velocity*0.5f  // 현재 속도를 반으로 줄인다.
        }
    }

private void OnTriggerEnter(Collider other) {  // 땅에 닿았을 때를 구현한 것.
    if (other.tag  == "Ground")  // 땅에 닿았을 때..
        {
        if (other.contacts[0].normal.y > 0.7f) {  // 혹은, 무언가와의 접촉이 y값이 0.7 이상 되게끔 이루어졌을 때.
            isGrounded = true;  // 땅에 닿았음을 알려주고..
            jumpCount = 0;  // 점프횟수를 초기화한다.
            animator.SetBool("애니매개변수값", isGrounded);  // 애니메이션 매개변수에 바닥판정을 전달한다.
            }
        }
    }
    
private void OnCollisionExit(Collider other) {  // 땅에서 떨어졌을 때를 구현한 것.
    isGrounded = false;
    animator.SetBool("애니매개변수값", isGrounded);  // 애니메이션 매개변수에 바닥판정을 전달한다.
    }

점프에 해당하는 애니메이션도 넣어주어야 할 것이다.

점프의 끝

점프가 끝나고 애니메이션을 끝내주고 기본적인 Idle상태로 돌려주어야 한다. 일반적으로 onCollisionOn을 사용하지만, 레이캐스트도 가능하다.

void FixedUpdate()
    //시작점, 방향, 레이의 색을 정해준다.(없어도 됨. 보기 쉽게 만들어준 것일 뿐)
    Debug.DrawRay(rigid.position, Vector3.down, new Collor(색값)); //에디터 상에서만 Ray를 그려주는 함수이다.
    
    //해당 거리 안에 들어오면 collider에 내용물이 담긴다.
    RaycastHit rayHit=Physics.Raycast(rigid.position, Vector3.down, 거리, LayerMask.Getmast("Floor"));
        //그러나, 레이는 한 오브젝트에 맞으면 관통이 안된다.
        //이 문제를 해결하기 위해 레이어를 이용한다. Floor 등의 이름으로 레이어를 만든다.
        //마지막 인자는 닿은 레이어를 반환한다는 의미이다.
    if(rayHit.collider != null){
        if(rayHIt.distance <길이f){
            애니메이션객체명.SetBool("애니매개변수", false); //땅에 닿았으니 점프관련 변수를 바꿔준다.
        }

캐릭터가 아래로 내려올 때에만 레이를 쏘게끔 만들어도 괜찮겠다. if(rigid.velocity.y<0) 등으로.


무한 점프 막기

점프가 무한정 되는 상황을 막기 위해 다른 처리가 더 필요해진다.

맨 위의 Input 부분에 if의 조건으로 && !애니객체.GetBool("애니매개변수") 를 넣어주어 점프상태가 아님을 파악하여 점프키를 먹도록 하는 게 좋겠다.