728x90

오늘은 간단하게 확인만하기위해 몬스터 피격을 살펴보려고한다.

 

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

public class Arrow : MonoBehaviour
{
    public GameObject arrow;
    public Transform StartArrowPos;
    public int Damage;
    public float speed = 15f;
    public GameObject Target;
   
    // Start is called before the first frame update
    void Start()
    {
      

        Target = GameObject.Find("Archer").GetComponent<CharacterManger>().myTarget;//타겟 = 캐릭터의타겟 
    }

    // Update is called once per frame
    void Update()
    {
      
            
            if(Target!=null)
            {
                transform.position = Vector3.Lerp(transform.position, Target.transform.position, 3f);//타겟의 거리까지 1초만에 날아가게 

            }
       
        
    }
    private void OnTriggerEnter(Collider other)//무언가에 닿앗을때 호출
    {
        if (other.gameObject.layer.Equals(LayerMask.NameToLayer("Monster"))) // 닿은 오브젝트 이름이 Monster일때
        {

            Destroy(this.gameObject); // 화살 삭제
            Debug.Log("Hit"); // 디버그용 
        }
    }
    
  
}

화살에는 이런식으로 추가해주고

 

 

큐브에 몬스터 스크립트 할당후 

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

public class Monster : MonoBehaviour
{
    public int maxHp;
    public int curHp;
    Material myMaterial;

    private void Awake()
    {
        myMaterial = GetComponent<MeshRenderer>().material; // 색깔 변경하려면 meshrenderer 에 material을 갖고있어야 변경가능.
    }
    private void OnTriggerEnter(Collider other)//트리거엔터가 발동될때 
    {
        if (other.gameObject.layer.Equals(LayerMask.NameToLayer("Arrow")))//엔터한 트리거에 레이어 이름이 Arrow 일때 
        {
            Arrow arrow = other.GetComponent<Arrow>(); // Arrow 를 GetComponet 하고 
            curHp -= arrow.Damage;// 현재 hp 에서 arrow 데미지를 빼주고 
            StartCoroutine( OnDamage()); // ondamage 코루틴 시작 
        }
        


    }
    IEnumerator OnDamage() // ondamage코루틴 
    {

        myMaterial.color = Color.red; // 몬스터 색깔 빨강으로 변경 
        yield return new WaitForSeconds(0.2f); // 0.2 초 기다린뒤 
        if(curHp>0)// 현재 hp 가 0보다크다면 
        {
            myMaterial.color = new Color(1, 1, 1); //원래색깔로 
        }
        if (curHp <= 0)//현재 hp 가 0보다 작다면
        {
            StartCoroutine(Disapearing()); // Disapearing 코루틴 시작
        }

    }
    IEnumerator Disapearing()//Disapearing 코루틴
    {
        myMaterial.color = Color.grey;// 몬스터 색깔 회색으로 변경
        yield return new WaitForSeconds(1.0f); // 1초뒤
       
        float dist = 1.0f; //1.0f 만큼 내려가게하려고 dist 설정
        while (dist > 0.0f)// dist 가 0보다 작아질때까지 무한루프
        {
            float delta = Time.deltaTime * 0.5f; 
            this.transform.Translate(-Vector3.up * delta); // 초당 0.5f 씩 떨어지게 
            dist -= delta; // dist 에서 빼준다 delta 만큼 
            yield return null;
        }
        Destroy(this.gameObject);// while 문 끝난후 몬스터 삭제 
    }
}

 

 

추가해주면 

 

 

이런식으로 작동된다

 

이제 몬스터를 피격하면 타겟이 고정되게 변경해주려고한다 .

IEnumerator OnDamage() // ondamage코루틴 
    {

        myMaterial.color = Color.red; // 몬스터 색깔 빨강으로 변경 
        yield return new WaitForSeconds(0.2f); // 0.2 초 기다린뒤 
        if(curHp>0)// 현재 hp 가 0보다크다면 
        {
            myMaterial.color = new Color(1, 1, 1); //원래색깔로 
            CharacterManger characterManger = GameObject.Find("Archer").GetComponent<CharacterManger>();
            characterManger.fixTarget = true; //만약 맞았는데 현재 hp 가 0보다크면  타겟 고정을 위해 스탑 코루틴 켜줄 bool 조정 
        }
        if (curHp <= 0)//현재 hp 가 0보다 작다면
        {
            StartCoroutine(Disapearing()); // Disapearing 코루틴 시작
            CharacterManger characterManger = GameObject.Find("Archer").GetComponent<CharacterManger>();
            characterManger.fixTarget = false;// 만약 맞았는데 현재 hp 가 0보다작거나 같다면 타겟 세팅을 위해 스타트 코루틴 켜줄 bool 조정 
        }

    }

몬스터 코드에서 컬러다음 두줄을 추가해주고 

 

캐릭터 매니저 스크립트에서

 

 public bool fixTarget; //불값을 이용해 타겟고정할예정 
 
   if (myState==State.BATTLE)
        {
            if(fixTarget==false)// 스타트코루틴
            {
                StartCoroutine(SetTartget());
            }
           else // 스탑코루틴 
            {
                StopCoroutine(SetTartget());
            }
        }

bool 값 추가후 코루틴 스타트 할때와 스탑할때 추가해준다.

 

이렇게하게되면 몬스터가 죽을때까지 고정된다. 

 

 

 

 

이제는 몬스터 ai를 구현하려고한다 

캐릭터와 같이 state 상태로 할예정이며

 

몬스터 에셋밑 애니메이션을 구해야한다 .

 

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

public class Monster : MonoBehaviour
{
    public enum State
    {
        CREATE, IDLE, BATTLE, DIE,ROAMING
    }
    public State myState = State.CREATE;
    public int maxHp;
    public int curHp;
    public int Damage;
    public Renderer myrenderer;
    public Animator myanim;

    private void Awake()
    {
        ChangeState(State.IDLE);
       
    }
    private void OnTriggerEnter(Collider other)//트리거엔터가 발동될때 
    {
        if (other.gameObject.layer.Equals(LayerMask.NameToLayer("Arrow")))//엔터한 트리거에 레이어 이름이 Arrow 일때 
        {
           
            Arrow arrow = other.GetComponent<Arrow>(); // Arrow 를 GetComponet 하고 
            curHp -= arrow.Damage;// 현재 hp 에서 arrow 데미지를 빼주고 
            StartCoroutine(OnDamage()); // ondamage 코루틴 시작 
            ChangeState(State.BATTLE); // 맞게되면 Battle 상태로 변경 
            myanim.SetTrigger("Damage");// 맞게되면 내 애니메이션 데미지 실행 
        }
        


    }
    IEnumerator OnDamage() // ondamage코루틴 
    {

        myrenderer.material.color= Color.red; // 몬스터 색깔 빨강으로 변경 
        yield return new WaitForSeconds(0.2f); // 0.2 초 기다린뒤 
        if(curHp>0)// 현재 hp 가 0보다크다면 
        {
            myrenderer.material.color = new Color(1, 1, 1); //원래색깔로 
            CharacterManger characterManger = GameObject.Find("Archer").GetComponent<CharacterManger>();
            characterManger.fixTarget = true; //만약 맞았는데 현재 hp 가 0보다크면  타겟 고정을 위해 스탑 코루틴 켜줄 bool 조정 
        }
        if (curHp <= 0)//현재 hp 가 0보다 작다면
        {
            ChangeState(State.DIE);
        }

    }
    IEnumerator Disapearing()//Disapearing 코루틴
    {
        
        myrenderer.material.color = Color.grey;// 몬스터 색깔 회색으로 변경
        yield return new WaitForSeconds(1.0f); // 1초뒤
       
        float dist = 1.0f; //1.0f 만큼 내려가게하려고 dist 설정
        while (dist > 0.0f)// dist 가 0보다 작아질때까지 무한루프
        {
            float delta = Time.deltaTime * 0.5f; 
            this.transform.Translate(-Vector3.up * delta); // 초당 0.5f 씩 떨어지게 
            dist -= delta; // dist 에서 빼준다 delta 만큼 
            yield return null;
        }
        Destroy(this.gameObject);// while 문 끝난후 몬스터 삭제 
    }

    void ChangeState(State s) // State 변경 
    {

        if (myState == s) return; // 지금 내 state 가 입력받은 state 와 같다면 return 
        myState = s; // 아니라면 내 state 에 입력받은 s 대입 

        switch(myState)
        {
            case State.CREATE:
                break;
            case State.IDLE:
                break;
            case State.ROAMING:
                break;
            case State.BATTLE:
                break;
            case State.DIE: // die 상태로돌입하면 
               
                myanim.SetTrigger("Dead"); // Dead 트리거 작동으로 Dead 애니메이션 나오고 
                StartCoroutine(Disapearing()); // Disapearing 코루틴 시작
                CharacterManger characterManger = GameObject.Find("Archer").GetComponent<CharacterManger>();
                characterManger.fixTarget = false;// 만약 맞았는데 현재 hp 가 0보다작거나 같다면 타겟 세팅을 위해 스타트 코루틴 켜줄 bool 조정 
                break;

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

        }
    }

}

 

 

일단은 몬스터 코드는 위에 처럼 수정하였고 

 

 

그리고 캐릭터도 조금 수정해주었다

 

원래는 캐릭의 시야각을 통해 몬스터 판별을 하려했는데

 

모바일 게임느낌을 원하는거라 오딘같은 게임도 뒤쪽 몬스터 까지 판별해서 제일 가까운 몬스터를 맞추기때문에 코드를 수정했다.

 

그리고 시야각을 계산하는 방법을 알았으니 그걸로 공부는 된거같아서 조금더 간단하게 바꾸기 위해 코드를 수정했다.

  public IEnumerator SetTartget()
    {
      
        Targets.Clear(); //배열에 계속쌓이는걸 방지하려고 클리어 하고 받기 
       targetIndistance = Physics.OverlapSphere(transform.position, distance, targetmask); // 내위치 중점, distance=사거리 구체반경,target마스크찾기위한거

        for (int i = 0; i < targetIndistance.Length; i++) //내사거리안에 몬스터만큼 돌려주려고 한거 
        {
            Transform target = targetIndistance[i].transform; //몬스터위치 

            Targets.Add(target.transform.gameObject);


        }

 

 

 

 

이런식으로 작동하게되고

 

내일은 몬스터 로밍상태구현 , 배틀상태일때 따라오게끔 하는걸 구현하려한다.

 

그러면 일단 몬스터 1마리는 구현이 끝나고.

 

시간이 남는다면 맵까지 구현해볼 예정이다. 

반응형