2 분 소요

걸을때, 뛸때 스피드 설정

    [SerializeField] float _moveSpeed;   //뛰는 스피드
    [SerializeField] float _walkSpeed;  //걷는 스피드
    float _Speed;       //최종 스피드

        if (Input.GetButtonDown("Fire2"))
        {
            RaycastHit hit;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(r, out hit))
            {
                _posTarget = hit.point;
                transform.LookAt(_posTarget);
                ChangedAction(eActionState.RUN);
            }
        }

       if (Vector3.Distance(transform.position, _posTarget) <= 0.1f)
        {
            ChangedAction(eActionState.IDLE);
        }
        transform.position = Vector3.MoveTowards(transform.position, _posTarget, _Speed*Time.deltaTime);  
    }

    void ChangedAction(eActionState state)
    {
        _stateAction = state;

        switch (state)                                  //애니메이션이 바뀌는 곳에서 속도를 변경 해주는게 직관적임
        {
            case eActionState.WALK:         //walk일때 최종스피드에다가 워크스피드를 넣어줌
                _Speed = _walkSpeed;
                break;
            case eActionState.RUN:
                _Speed = _moveSpeed;
                break;
        }
        
        _ctrlAni.SetInteger("AniState", (int)_stateAction);
    }

공격, 죽음 추가

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

public class ZombieController : MonoBehaviour
{
    public enum eActionState
    {
        IDLE              =0,
        WALK,
        RUN,
        ATTACK,
        HIT,
    }
    [SerializeField] float _moveSpeed;   //뛰는 스피드
    [SerializeField] float _walkSpeed;  //걷는 스피드
    eActionState _stateAction;
    Animator _ctrlAni;
    Vector3 _posTarget;
    float _Speed;       //최종 스피드
    bool _isDeath;   //플래그 (키고 끄고 할수있는 작용 
    bool _isAttack;
    

    private void Awake()
    {
        _isDeath = false;   //초기화
        _isAttack = false;  //초기화
       _ctrlAni = GetComponent<Animator>();
        _posTarget= transform.position;
    }
    void Start()
    {
    }

    void Update()
    {
        if (_isDeath)               //죽으면 아무것도 못하게 함
            return;

        if (Input.GetButtonDown("Fire1"))
        {
            RaycastHit hit;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            if(Physics.Raycast(r, out hit))
            {
                _posTarget= hit.point;
                transform.LookAt( _posTarget );
                ChangedAction(eActionState.WALK);
            }
        }

        if (Input.GetButtonDown("Fire2"))
        {
            RaycastHit hit;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(r, out hit))
            {
                _posTarget = hit.point;
                transform.LookAt(_posTarget);
                ChangedAction(eActionState.RUN);
            }
        }

        if (_isAttack)               //공격일때 이동하는것만 못하게 막아줌
            return;




        //transform.position = Vector3.Lerp(transform.position, _posTarget, Time.deltaTime);   //
        if (Vector3.Distance(transform.position, _posTarget) <= 0.1f)
        {
            ChangedAction(eActionState.IDLE);
        }
        transform.position = Vector3.MoveTowards(transform.position, _posTarget, _Speed*Time.deltaTime);  
    }


    void ChangedAction(eActionState state)
    {

        switch (state)                                  //애니메이션이 바뀌는 곳에서 속도를 변경 해주는게 직관적임
        {
            case eActionState.WALK:         //walk일때 최종스피드에다가 워크스피드를 넣어줌
                if(_stateAction != eActionState.ATTACK)   //상태가 공격일때는 WALK안되도록 설정
                {
                _Speed = _walkSpeed;
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                }
                break;
            case eActionState.RUN:
                _Speed = _moveSpeed;
                _ctrlAni.SetInteger("AniState", (int)_stateAction);  
                _stateAction = state;
                break;
            case eActionState.ATTACK:       //모든것이 변하는 곳에 공격할때는 isAttack을 킴
                if(_stateAction ==eActionState.RUN)  // 상태가 런일때만 공격할수있게 통일
                {
                    _isAttack= true;
                    _ctrlAni.SetInteger("AniState", (int)_stateAction);
                    _stateAction = state;

                }
                break;
            case eActionState.HIT:      //맞으면 isDeath를 킴
                _isDeath= true;
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                break;
            case eActionState.IDLE:
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                break;

        }
        
        _stateAction = state;
        _ctrlAni.SetInteger("AniState", (int)_stateAction);
    }
    private void OnGUI()
    {
        if (GUI.Button(new Rect(0, 0, 200, 80), "ATTACK"))
        {
            ChangedAction(eActionState.ATTACK);
        }

        if (GUI.Button(new Rect(0, 100, 200, 80), "DEAD"))
        {
            ChangedAction(eActionState.HIT);
        }
    }
}

Box Coliider 넣으면 모델의 위치(y)가 변함

→ Layer을 이용해서 원하는 값만 체크 할 수 있게 함

  • 좀비는 Enemy로 Layer 설정
  • Floor는 Floor로 Layer 설정
  • int mask = 1<<LayerMask.NameToLayer("Floor");
  • if(Physics.Raycast(r,out hit, Mathf.Infinity, mask)~
        if (Input.GetButtonDown("Fire1"))
        {
            RaycastHit hit;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            int mask = 1 << LayerMask.NameToLayer("Floor");    // 비트연산으로 인해, Floor의 Layer인 8번 Layer만 쓸게     
            if(Physics.Raycast(r, out hit, Mathf.Infinity, mask))
            {
                _posTarget= hit.point;
                transform.LookAt( _posTarget );
                ChangedAction(eActionState.WALK);
            }
        }

        if (Input.GetButtonDown("Fire2"))
        {
            RaycastHit hit;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            int mask = 1 << LayerMask.NameToLayer("Floor");    
            if (Physics.Raycast(r, out hit, Mathf.Infinity, mask))
                if (Physics.Raycast(r, out hit))
            {
                _posTarget = hit.point;
                transform.LookAt(_posTarget);
                ChangedAction(eActionState.RUN);
            }
        }

댓글남기기