728x90
반응형

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

 

반응형
728x90
반응형

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

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

반응형
728x90
반응형

 

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 등록을 완료하였습니다 

반응형
728x90
반응형

 

유니티 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(); 
    } 
}

 

 

 

 

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

 

 

반응형
728x90
반응형

 

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