728x90

오늘은 어제에 이어서 캐릭터 구현을 해보려고 한다.

 

일단은 조이스틱 과 키보드 둘다 되게하고싶은데 키보드 먼저 구현을 해보려고한다.

 

나는 캐릭터가 조작키를 땠는데 미끄러지는 느낌을 좋아하지않아서 

 

GetAxisRaw 를 사용하는것을 좋아한다 

 

GetAxis 와 Raw 의 차이점은 Axis 는 약간 자동차 운전과같다고 보면되고 Raw는 테트리스같은 느낌이라고 생각하면된다.

 

Character 스크립트 추가후 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterManger : MonoBehaviour
{
    public float moveSpeed = 10f;
    Rigidbody body;
    Animator myanim;
    Vector3 movement;

     void Awake()
    {
        myanim = GetComponent<Animator>();  
        body = GetComponent<Rigidbody>();
       
    }
    void FixedUpdate()
    {


  
       
        move();

    }
    void move()
    {

        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
        movement.Set(h, 0, v);
       if(h ==0 && v == 0)
        {
            myanim.SetBool("IsMoving", false);
        }
       else
        {
            myanim.SetBool("IsMoving", true);
        }
        movement=movement.normalized*moveSpeed*Time.deltaTime;

        body.MovePosition(transform.position + movement);
    }

   
   
}

 

학원에서 알려준대로 만들려니까 너무 복잡해져서 인터넷에 쳐보니 좋은 자료들이 많아서 많이 읽어보고 그 중에 내가원하는 조작감이 뭘까 생각해서 코드를 짜면서 진행했고 이렇게 코드를 짜면 캐릭터가 이동된다.

 

코드는 골드메탈님 영상을 참고했다.

 

 

 

이제 캐릭터 회전을 구현해보려고한다.

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterManger : MonoBehaviour
{
    public float moveSpeed = 10f;
    public float rotationSpeed = 5f;
    Rigidbody body;
    Animator myanim;
    Vector3 movement;

     void Awake()
    {
        myanim = GetComponent<Animator>();  
        body = GetComponent<Rigidbody>();
       
    }
    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");



        move(h,v);
        turn(h, v);
    }
    void move(float h, float v)
    {

        
        movement.Set(h, 0, v);
       if(h ==0 && v == 0)
        {
            myanim.SetBool("IsMoving", false);
        }
       else
        {
            myanim.SetBool("IsMoving", true);
        }
        movement=movement.normalized*moveSpeed*Time.deltaTime;

        body.MovePosition(transform.position + movement);
    }

    void turn(float h, float v)
    {
        if (h == 0 && v == 0)
            return;
        Quaternion Rotation = Quaternion.LookRotation(movement);
        body.rotation = Quaternion.Slerp(body.rotation, Rotation,rotationSpeed*Time.deltaTime);
    }

   
   
}

회전까지 구현하고보니 raw를 하면 입력값이 적어도 일정거리를 이동하기때문에 불편한게있는거같아서 raw를빼려한다 .

 

카메라회전을 위해서 스크립트 작성후 아래 스크립트를 썼다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarmeraManger : MonoBehaviour
{
    GameObject player;
    public float x = 0f;
    public float y = 4f;
    public float z = -5f;
    Vector3 cameraPosition;

    private void Awake()
    {
        player = GameObject.FindWithTag("Player");
        
    }

    private void LateUpdate()
    {
        cameraPosition.x = player.transform.position.x + x;
        cameraPosition.y = player.transform.position.y + y;
        cameraPosition.z = player.transform.position.z + z;

        transform.position = cameraPosition;
    }
}

player 는 지금은 Archer 하나지만 나중에 추가로 구현하게될수있기때문에 tag 로 구분하여 받기로했다 왜냐면 하나만 생성되기때문에 

 

카메라에위치는 캐릭터포지션 + flot 값을 줬고 lateupdate를 쓴이유는 제일 마지막에 업데이트가 되기위해서이다.

 

-------D+7 여기까지 작성했는데 글쓰는걸 까먹고 너무졸려서 컴퓨터를 바로꺼버렸다.

 

 

 

이렇게보니 움직임이 너무어색하다 

 

캐릭터에 학원에서배운 STATE 상태로 구분짖는거를 하려고한다 .

 

 public enum State
    {
        CREATE, IDLE, BATTLE,DIE 
    }

캐릭터 스크립트 부분에 캐릭터 스테이트를 enum 으로 추가해준다 

 

그리고 state 는 항상 세트로 같이다니는 코드가있다 강사님이 말씀해주신건데

 

  void ChangeState(State s)
    {
        if (myState == s) return;
        myState = s;
        switch (myState)
        {
            case State.CREATE:
               
                break;
            case State.IDLE:
               
                break;
            case State.BATTLE:
             
                break;
          
            case State.DIE:
                break;
        }
    }
    
     protected void StateProcess()
    {
        switch (myState)
        {
            case State.CREATE:
                break;
            case State.IDLE:
                break;
            case State.BATTLE:
                break;
         
            case State.DIE:
                break;
        }
    }

뼈대는 이렇게 구성되고 

 

일단은 배틀상태일때 활을 꺼내는 애니메이션이 끝나는 동시에 손에 활이생기게 끔 하고

 

일반상태로 돌아갈때는 꽂는 애니메이션이 없어서 그냥 false 로 해주었고

 

그리고 활을 꺼낼동안에 움직이길레 움직임을 막기위해 애니메이션 파라메터 를 하나 추가해줘서 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EqipBow : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.SetBool("EqipBow", true);
    }

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.SetBool("EqipBow", false);
    }

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}

이런식으로 들어갈때 true 나올때 false 로 바뀌게끔하여 저 true false 를 이용하여 애니메이션 끝나는 타이밍에 다시 이동 할수있게끔 해주었다 코드를보면

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterManger : MonoBehaviour
{
    public enum State
    {
        CREATE, IDLE, BATTLE,DIE 
    }
    public State myState = State.CREATE;
    public GameObject Backbow;
    public GameObject Handbow;
    float moveSpeed = 6f;
    float rotationSpeed = 5f;
    Rigidbody body;
    Animator myanim;
    Vector3 movement;

     void Awake()
    {
        myanim = GetComponent<Animator>();  
        body = GetComponent<Rigidbody>();
       
    }
    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");



        move(h,v);
        turn(h, v);
        if(Input.GetMouseButtonUp(0))
        {
            ChangeState(State.BATTLE);
        }

        if (Input.GetMouseButton(1))
        {
            ChangeState(State.IDLE);
        }
    }
    void move(float h, float v)
    {

        
        movement.Set(h, 0, v);
       if(h ==0 && v == 0 )
        {
            myanim.SetBool("IsMoving", false);
        }
       else if( myanim.GetBool("EqipBow") != true)
        {
            myanim.SetBool("IsMoving", true);
        }
        if (myanim.GetBool("EqipBow") != true)
        {
            movement = movement.normalized * moveSpeed * Time.deltaTime;

            body.MovePosition(transform.position + movement);
        }
            
    }

    void turn(float h, float v)
    {
        if (h == 0 && v == 0 )
            return;
        else if(myanim.GetBool("EqipBow") != true)
        {
            Quaternion Rotation = Quaternion.LookRotation(movement);
            body.rotation = Quaternion.Slerp(body.rotation, Rotation, rotationSpeed * Time.deltaTime);
        }
        
    }

    void ChangeState(State s)
    {
        if (myState == s) return;
        myState = s;
        switch (myState)
        {
            case State.CREATE:
                Backbow.SetActive(true);
                Handbow.SetActive(false);
                break;
            case State.IDLE:
                myanim.SetTrigger("Idle");
                if(Backbow.activeSelf==false)
                    Backbow.SetActive(true);
                if (Handbow.activeSelf== true)
                    Handbow.SetActive(false);
                break;
            case State.BATTLE:
                moveSpeed = 3f;
                myanim.SetTrigger("Battle");
                Backbow.SetActive(false);
                Handbow.SetActive(true);
                break;
          
            case State.DIE:
                break;
        }
    }

    protected void StateProcess()
    {
        switch (myState)
        {
            case State.CREATE:
                break;
            case State.IDLE:
                break;
            case State.BATTLE:
                break;
         
            case State.DIE:
                break;
        }
    }

 

 

이런식으로 변경되었고

 

지금은 확인을 위해 

 

마우스 왼쪽 버튼 클릭시 배틀모드 오른쪽 클릭시 아이들 모드로 들어가게끔 설정해주었다.

 

 

이거는 나중에 주위에 타겟팅 된 적이있다면 배틀모드로 들어가게끔 해주면 될거같다.

 

 

 

 

 

카메라 이동을 하려는데 축이동을 하려고 빈게임 오브젝트를 만들고 거기안에 카메라를 넣고 오브젝트 각도를 조절하면 원래내가 생각했던거는 그걸 축이라생각해서  캐릭터 를 중심으로 넣고 카메라 를 회전하는데 지금 뭐때문인지 모르겠는데

 

카메라각도그대로가 회전되서 그거에 애먹고있다.

반응형