강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

soso03185님의 프로필 이미지
soso03185

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진

공격 #2

공격 판정이 잘 안됩니다

작성

·

620

1

공격 판정이 기사의 발을 클릭해야 공격이 들어갑니다 머리를 클릭하면 RUN상태로 부비부비를 하고 있어요 ㅜㅜ

코드는 강의 그대로 따라했습니다!

============================================

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.AI;

public class PlayerController : MonoBehaviour

{

    public enum PlayerState

    {

        Die,

        Idle,

        Moving,

        Skill,

    }

    int _mask = (1 << (int)Define.Layer.Ground) | (1 << (int)Define.Layer.Monster);

    PlayerStat _stat;

    Vector3 _destPos;

    GameObject _lockTarget;

    [SerializeField]

    PlayerState _state = PlayerState.Idle;

    public PlayerState State

    {

        get { return _state; }

        set

        {

            _state = value;

            Animator anim = GetComponent<Animator>();

            switch (_state)

            {

                case PlayerState.Die:

                    break;

                case PlayerState.Idle:

                    anim.CrossFade("WAIT00", 0.1f);

                    break;

                case PlayerState.Moving:

                    anim.CrossFade("RUN00_F", 0.1f);

                    break;

                case PlayerState.Skill:

                    anim.CrossFade("Attack1", 0.1f, -1, 0);

                    break;

            }

        }

    }

    void Start()

    {

        #region

        // Managers.Input.KeyAction -= OnKeyboard;

        // Managers.Input.KeyAction += OnKeyboard;

        #endregion

        _stat = gameObject.GetComponent<PlayerStat>();

        Managers.Input.MouseAction -= OnMouseEvent;

        Managers.Input.MouseAction += OnMouseEvent;

        Managers.UI.ShowSceneUI<UI_Inven>();

    }

    void UpdateDie()

    {

    }

    

    void UpdateMoving()

    {

        //몬스터가 내 사정거리보다 가까우면 공격

        if(_lockTarget != null)

        {

            float distance = (_destPos - transform.position).magnitude;

            if(distance <= 1)

            {

                State = PlayerState.Skill;

                return;

            }

        }

        //이동

        Vector3 dir = _destPos - transform.position;

        if (dir.magnitude < 0.1f)

        {

            State = PlayerState.Idle;

        }

        else

        {

            NavMeshAgent nma = gameObject.GetOrAddComponent<NavMeshAgent>();

            float moveDist = Mathf.Clamp(_stat.MoveSpeed * Time.deltaTime, 0, dir.magnitude);

            nma.Move(dir.normalized * moveDist);

            Debug.DrawRay(transform.position + Vector3.up * 0.5f , dir.normalized, Color.green);

            if(Physics.Raycast(transform.position + Vector3.up * 0.5f, dir, 1.0f, LayerMask.GetMask("Block")))

            {

                if (Input.GetMouseButton(0) == false)

                    State = PlayerState.Idle;

                return;

            }

            

            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime);

        }

    }

    void UpdateIdle()

    {

    }

     void UpdateSkill()

    {

        if(_lockTarget != null)

        {

            Vector3 dir = _lockTarget.transform.position - transform.position;

            Quaternion quat = Quaternion.LookRotation(dir);

            transform.rotation = Quaternion.Lerp(transform.rotation, quat, 20 + Time.deltaTime);

        }

    }

    void OnHitEvent()

    {

        Debug.Log("OnHitEvent");

        if(_stopSkill)

        {

            State = PlayerState.Idle;

        }

        else

        { 

            State = PlayerState.Skill;

        }

    }

    void Update()

    {

        switch (State)

        {

            case PlayerState.Die:

                UpdateDie();

                break;

            case PlayerState.Moving:

                UpdateMoving();

                break;

            case PlayerState.Idle:

                UpdateIdle();

                break;

            case PlayerState.Skill:

                UpdateSkill();

                break;

        }                

    }

    #region

    //void OnKeyboard()

    //{

    //    if (Input.GetKey(KeyCode.W))

    //    {

    //        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.forward), 0.2f);

    //        transform.position += Vector3.forward * Time.deltaTime * _speed;

    //    }

    //    if (Input.GetKey(KeyCode.S))

    //    {

    //        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.back), 0.2f);

    //        transform.position += Vector3.back * Time.deltaTime * _speed;

    //    }

    //    if (Input.GetKey(KeyCode.A))

    //    {

    //        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.left), 0.2f);

    //        transform.position += Vector3.left * Time.deltaTime * _speed;

    //    }

    //    if (Input.GetKey(KeyCode.D))

    //    {

    //        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), 0.2f);

    //        transform.position += Vector3.right * Time.deltaTime * _speed;

    //    }

    //    _moveToDest = false;

    //}

    #endregion

    bool _stopSkill = false;

    void OnMouseEvent(Define.MouseEvent evt)

    {

        switch (State)

        {

            case PlayerState.Idle:

                OnMouseEvent_IdleRun(evt);

                break;

            case PlayerState.Moving:

                OnMouseEvent_IdleRun(evt);

                break;

            case PlayerState.Skill:

                {

                    if(evt == Define.MouseEvent.PointerUp)                    

                        _stopSkill = true;                    

                }

                break;

        }

    }

    void OnMouseEvent_IdleRun(Define.MouseEvent evt)

    {

        RaycastHit hit;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        bool raycastHit = Physics.Raycast(ray, out hit, 100.0f, _mask);

        // Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);

        switch (evt)

        {

            case Define.MouseEvent.PointerDown:

                {

                    if (raycastHit)

                    {

                        _destPos = hit.point;

                        State = PlayerState.Moving;

                        _stopSkill = false;

                        if (hit.collider.gameObject.layer == (int)Define.Layer.Monster)

                            _lockTarget = hit.collider.gameObject;

                        else

                            _lockTarget = null;

                    }

                }

                break;

            case Define.MouseEvent.Press:

                {

                    if (_lockTarget == null && raycastHit)

                        _destPos = hit.point;

                }

                break;

            case Define.MouseEvent.PointerUp:

                _stopSkill = true;

                break;

        }

    }

}

퀴즈

48%나 틀려요. 한번 도전해보세요!

Unity 게임 개발 프레임워크에서 Manager를 사용하는 주된 목적은 무엇일까요?

특정 오브젝트의 애니메이션을 제어하기 위해서

자주 사용되는 기능이나 시스템을 중앙에서 관리하기 위해서

캐릭터의 스탯 값을 저장하기 위해서

게임 씬의 배경 음악을 재생하기 위해서

답변 5

5

Rookiss님의 프로필 이미지
Rookiss
지식공유자

확인해보니 _target의 y값이 높이 잡혀서 그런 것이네요.
거리 계산 공식에서 y값은 0 혹은 플레이어 높이로 강제로 세팅하도록 수정하면 되겠습니다.
디버깅 영상 메일로 회신 드리니 참고 바랍니다.

저도 _destPos.y = 0으로 하니까 문제가 해결되었는데

_destPos = 0으로 해서 문제가 해결이 된 이유가 혹시

_destPos가 현재 Vector3이니까

raycastHit이 된 오브젝트의 y축좌표를 0으로하면 머리꼭대기? 로 _destPos의 y축 좌표가 설정이 되니까(capsule collider의 좌표가 그냥 머리 꼭대기)

그래서 capsule collider어느 부분을 눌러도 

 

Updatemoving에서 인식이 다 되는 것인가요..??

Rookiss님의 프로필 이미지
Rookiss
지식공유자

네 맞습니다.

2

Rookiss님의 프로필 이미지
Rookiss
지식공유자

위 내용으로 확실히 알 수 없지만 '발'은 대상으로 찍히는 상황이라면
코드 문제가 아니라, 프리팹의 Collision 영역 문제일 확률이 높습니다.
몬스터의 Collider 범위를 살펴보시기 바랍니다.
그래도 해결이 안 되면 전체 프로젝트 압축 후
rookiss@naver.com로 보내주시기 바랍니다.

0

동일한 문제를 겪고 있었는데 해결됐습니다.

감사합니다

0

혹시 저도 같은문제가 발생해서 그런데
디버깅영상 부탁드려도 될까요? 
gugangmo59@naver.com 가 메일 주소입니다.

Rookiss님의 프로필 이미지
Rookiss
지식공유자

디버깅 영상은 이미 삭제해서 없습니다 OTL
위와 같은 코드 수정으로 해결이 안 되는지 확인 부탁드리고
원인 파악이 힘들면 rookiss@naver.com로 전체 프로젝트 압축해서 보내주시기 바랍니다.

0

soso03185님의 프로필 이미지
soso03185
질문자

디버깅영상까지 찍어주시고 정말 감사합니다.

덕분에 잘 해결되었어요!

soso03185님의 프로필 이미지
soso03185

작성한 질문수

질문하기