반응형

0

 

플레이어를 이동 시키기 위해서 InputManager 스크립트를 수정 하겠습니다

InputManager 스크립트를 엽니다

 

 

 

 

 

 

 

//InputManager 스크립트 수정

 

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

public class InputManager : MonoBehaviour
{

    GameObject player;
    // Start is called before the first frame update
    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
    }

    void CheckClick()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //카메라로부터 화면사의 좌표를 관통하는 가상의 선(레이)을 생성해서 리턴해 주는 함수
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;

            //Physics.Raycast(래이 타입 변수, out 레이캐스트 히트 타입변수) : 
            //가상의 레이저선(래이)이 충돌체와 충돌하면, true(참) 값을 리턴하면서 동시에 레이캐스트 히트 변수에 충돌 대상의 정보를 담아 주는 함수           
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.collider.gameObject.name == "Terrain")
                {
                    // player.transform.position = hit.point;

                    //마우스 클릭 지점의 좌표를 플레이어가 전달받은뒤,상태를 이동상태로 바뀜
                    player.GetComponent<PlayerFSM>().MoveTo(hit.point);                

                 }
            }
        }

    }
    // Update is called once per frame
    void Update()
    {
        CheckClick();
    }
}

 

 

 

 

 

 

 

 

 

PlayerFSM 스크립트를 선택하고 스크립트를 엽니다

그리고 수정합니다

 

 

//PlayerFSM 스크립트 수정

 

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

public class PlayerFSM : MonoBehaviour
{    
    public enum State
    {
        Idle,
        Move,
        Attack,
        AttackWait,
        Dead
    }
    //idle 상태를 기본 상태로 지정
    public State currentState = State.Idle;

    //마우수 클릭 지점,플레이어가 이동할 목적지의 좌표를 저장할 예정
    Vector3 curTargetPos;

    public float rotAnglePerSecond = 360f; //1초에 플레이어의 방향을 360도 회전한다

    public float moveSpeed = 2f; //초당 2미터의 속도로 이동

    PlayerAni myAni;


    void Start()
    {
        myAni = GetComponent<PlayerAni>();
        //  myAni.ChangeAni(PlayerAni.ANI_WALK);

        ChangeState(State.Idle, PlayerAni.ANI_IDLE);
    }


    void ChangeState(State newState, int aniNumber)
    {
        if (currentState == newState)
        {
            return;
        }

        myAni.ChangeAni(aniNumber);
        currentState = newState;
    }

    //캐릭터의 상태가 바뀌면 어떤 일이 일어날지 를 미리 정의
    void UpdateState()
    {
        switch (currentState)
        {
            case State.Idle:
                break;
            case State.Move:
                TurnToDestination();
                MoveToDestination();
                break;
            case State.Attack:
                break;
            case State.AttackWait:
                break;
            case State.Dead:
                break;
            default:
                break;
        }

    }

    //MoveTo(캐릭터가 이동할 목표 지점의 좌표)
   public void MoveTo(Vector3 tPos)
    {
        curTargetPos = tPos;
        ChangeState(State.Move, PlayerAni.ANI_WALK);
    }

    void TurnToDestination()
    {
        // Quaternion lookRotation(회전할 목표 방향) : 목표 방향은 목적지 위치에서 자신의 위치를 빼면 구함
        Quaternion lookRotation = Quaternion.LookRotation(curTargetPos - transform.position);

        //Quaternion.RotateTowards(현재의 rotation값, 최종목표rotation 값, 최대 회전각)
        transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, Time.deltaTime * rotAnglePerSecond);
    }

    void MoveToDestination()
    {
        //Vector3.MoveTowards(시작지점, 목표지점,최대이동거리)
        transform.position = Vector3.MoveTowards(transform.position, curTargetPos,moveSpeed * Time.deltaTime);


        //플레이어의 위치와 목표지점의 위치가 같으면, 상태를 Idle 상태로 바꾸라는 명령
        if (transform.position == curTargetPos)
        {
            ChangeState(State.Idle, PlayerAni.ANI_IDLE);
        }
    }
    void Update()
    {
        UpdateState();
    }
}

 

 

 

 

 

 

스크립트를 수정하고 플레이 버튼을 눌러서 플레이어가 마우스 클릭지점으로 이동하는지 확인 합니다

 

 

0

 

반응형
반응형

이제 애니메이터 컨트롤러에 등록한 애니메이션들을 스크립트로 컨트롤 하겠습니다

Scripts 폴더안에 PlayerAni 스크립트를 만듭니다

 

Player를 선택하고 PlayerAni 스크립트를 붙힘니다

 

PlayerAni.cs 에서 만든 함수를 PlayerFSM 에서 활용해 보도록 하겠습니다

 

 

 

 

 

 

//PlayerFSM 스크립트 작성

 

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

public class PlayerFSM : MonoBehaviour 
{ 
   
    public enum State 
    { 
        Idle, 
        Move, 
        Attack, 
        AttackWait, 
        Dead 
    } 
    //idle 상태를 기본 상태로 지정 
    public State currentState = State.Idle; 

    PlayerAni myAni; 


    void Start() 
    { 
        myAni = GetComponent<PlayerAni>(); 
        //  myAni.ChangeAni(PlayerAni.ANI_WALK); 

        ChangeState(State.Idle, PlayerAni.ANI_IDLE); 
    } 

    void ChangeState(State newState, int aniNumber) 
    { 
        if (currentState == newState) 
        { 
            return; 
        } 

        myAni.ChangeAni(aniNumber); 
        currentState = newState; 
    } 

    //캐릭터의 상태가 바뀌면 어떤 일이 일어날지 를 미리 정의 
    void UpdateState() 
    { 
        switch (currentState) 
        { 
            case State.Idle: 
                break; 
            case State.Move: 
                break; 
            case State.Attack: 
                break; 
            case State.AttackWait: 
                break; 
            case State.Dead: 
                break; 
            default: 
                break; 
        } 

    } 
    // Update is called once per frame 
    void Update() 
    { 
        UpdateState(); 
    } 
}

 

 

 

//PlayerAni 스크립트 작성

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

public class PlayerAni : MonoBehaviour 
{ 
    // 애니메이터 컨트롤러의 전이 관계에서 설정한 번호에 맞춤니다 
    public const int ANI_IDLE = 0; 
    public const int ANI_WALK = 1; 
    public const int ANI_ATTACK = 2; 
    public const int ANI_ATKIDLE = 3; 
    public const int ANI_DIE = 4; 

    Animator anim; 
    void Start() 
    { 
        anim = GetComponent<Animator>(); 
    } 

    //애니메이션 번호를 입력 받아서 플레이어의 애니메이션을 해당되는 애니메이션으로 바꿔주는 함수 
    public void ChangeAni(int aniNumber) 
    { 
        anim.SetInteger("aniName", aniNumber); 
    } 
    // Update is called once per frame 
    void Update() 
    { 
         
    } 
}

 

 

스크립트를 작성하고 게임을 실행시키면 플레이어가 Idle 상태로 됩니다

 

0

반응형
반응형

 

Scrips 폴더 안에 PlayerFSM 스크립트를 만듭니다

 

 

PlayerFSM 스크립트를 Player 오브젝트에 붙입니다

 

 

그리고 Asset Store에 들어가서 찾기 에서 HQ Fighting Animation을 찾아 임포트 합니다

 

 

임포트 파일 중에서 아래 사진 세 개의 파일만 선택하고 임포트 합니다

 

 

 

 

 

 

그리고 임포트 한 파일을 선택하여 inspector에서 Rig에서 Animation Type을 Hunanoid로 바꾸고 Apply 누릅니다

 

그리고 Animation으로 들어가서 Bake into Pose를 체크합니다

 

 

 

 

 

 

그리고 PlayerControl에서 등록한 WAIT00의 이름을 idle로 바꿉니다

 

그리고 Assets/unity-chan!/Unity-chan! Model/Art/Animations/WALK00_F을 드래그하여 
Animator에 올려놓습니다

이름을 walk로 바꿉니다

 

 

Parameters에 있는 + 버튼을 눌러서 int를 추가하고 이름을 aniName을 등록합니다 

 

idle   ->  walk 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고 

Conditions에서 aniName , Eqals , 1을 선택한다

 

 

 

 

 

idle  <-  walk 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고 

Conditions에서 aniName , Eqals , 0을 선택한다

 

 

 

Assets/FightingUnityChan_FreeAsset/FightingUnityChan_FreeAsset/Animations/FUCM_04_0001_RHiKick에서 Hikick을 드래그 하여  Animator에 올려놓고 이름을 attack으로 한다 

 

walk ->  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고 

Conditions에서 aniName , Eqals , 2를 선택한다

 

 

 

 

walk <-  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고 

Conditions에서 aniName , Eqals , 1을 선택한다

 

Assets/FightingUnityChan_FreeAsset/FightingUnityChan_FreeAsset/Animations/FUCM05_0000_Idle에서 Idle을 선택하여 Animator에 드래그하고 이름을 attackidle로 바꿉니다

 

 

 

 

 

attackidle <-  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하지 말고

Conditions에서 aniName , Eqals , 3을 선택한다

Has Exit Time을 체크 해제하지 않으면 상태가 바뀌었을 때 애니메이션이 즉각적으로 바뀌지 않고,
기존 애니메이션이 다 플레이된 다음에야 바뀌게 됩니다

 

attackidle -> attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 2를 선택한다

 

idle <-  attackidle 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 0을 선택한다

 

 

 

 

 

idle ->  attackidle 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 3을 선택한다

 

walk <-  attackidle 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 1을 선택한다

 

idle <-  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 0을 선택한다

 

idle ->  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 2를 선택한다

 

 

 

 

 

Assets/FightingUnityChan_FreeAsset/FightingUnityChan_FreeAsset/Animations/FUCM02_0025_MYA_TF_DOWN에서 DamageDown을 드래그해서  Animator에 놓고 이름을 die 한다

 

die <-  attack 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 4를 선택한다

 

die <-  attackidle 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 4를 선택한다

 

die <-  idle 사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 4를 선택한다

 

 

 

 

 

die <-  walk사이에  Make Transition을 연결하고 화살표를 선택하여 Has Exit Time을 체크 해제하고

Conditions에서 aniName , Eqals , 4를 선택한다

 

Player의 Animator 등록을 완료하였습니다 

반응형
반응형

 

유니티 Hierarchy에 빈 오브젝트를 만들고 이름을 InputManager 라 합니다

InputManager 만들기

 

 

폴더를 하나 생성하여 이름을 Scripts라고 합니다

Scripts폴더생성

Scripts폴더 안에 InputManager 새 스크립트를 생성하고 스크립트를 드래그하여 InputManager 오브젝트에 붙입니다

 

 

 

 

InputManager Scripts 작성

 

아래와 같이 스크립트를 작성합니다

 

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

public class InputManager : MonoBehaviour 
{ 

    GameObject player; 
    // Start is called before the first frame update 
    void Start() 
    { 
        player = GameObject.FindGameObjectWithTag("Player"); 
    } 

    void CheckClick() 
    { 
        if (Input.GetMouseButtonDown(0)) 
        { 
            //카메라로부터 화면사의 좌표를 관통하는 가상의 선(레이)을 생성해서 리턴해 주는 함수 
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 

            RaycastHit hit; 

            //Physics.Raycast(래이 타입 변수, out 레이 캐스트 히트 타입변수) :  
            //가상의 레이저선(래이)이 충돌체와 충돌하면, true(참) 값을 리턴하면서 동시에 레이캐스트 히트 변수에 충            돌 대상의 정보를 담아 주는 함수    

     
            if (Physics.Raycast(ray, out hit)) 
            { 
                if (hit.collider.gameObject.name == "Terrain") 
                { 
                    player.transform.position = hit.point; 
                } 
            } 
        } 

    } 
    // Update is called once per frame 
    void Update() 
    { 
        CheckClick(); 
    } 
}

 

 

 

 

아래 동영상과 같이 동작하면 정상작동입니다

 

 

반응형
반응형

 

window -> Asset Store를 들어갑니다

 

window -> Asset Store

 

Asset Store에서 unity-chan을 입력하고 찾기 버튼을 누릅니다

Asset Store -> unity-chan

 

 

임포트 합니다

import

 

 

 

 

전체 파일 임포트

 

 

 

 

 

 

 

 

project 안에 unity-chan! 폴더가 생성된 것을 확인할 수 있습니다

unity-chan! 폴더 생성

 

 

Models 안에 있는 unity chan 오브젝트를 드래그하여 Hierarchy에 올려놓습니다 

 

 

캐릭터 의 모습

 

 

 

 

 

 

 

 

카메라를 캐릭터 중심에 잡아놓고 GameObject -> Align with View를 클릭합니다 

GameObject -> Align with View 

 

 

unity chan 오브젝트를 선택하고 Inspector 창에 이름과 tag를 Player라고 바꿉니다 

 

 

Project Assets에 새폴더를 만들고 이름을 Animator 라합니다

Animator 폴더 생성

 

Animator 폴더를 선택하고 Assets - > Animator Controller를 클릭합니다

 

 

Animatro Controller 이름을 PlayerControl 라고 바꿉니다

PlayerControl 생성

 

 

PlayerControl를 두 번 클릭하여 들어가면 나오는 화면

 

unity-chan! -> Unity-cha! Model -> Art -> Animations의 폴더를 들어가서 unitychan_WAIT00 -> WAIT00을 드래그하여 그림과 같이 올려놓습니다

 

 

 

 

 

 

 

 

그리고 그림과 같이 Player를 선택하고  PlayerCotrol을 드래그해서 Player의 Inspector에서 Animator에 드래그하여 올려놓습니다 

그리고 플레이 버튼을 누르면 Player 가 기본 동작으로 Idle  하는 모습을 볼 수 있습니다

 

반응형

+ Recent posts