Unity_3D Survival Game Development_8

💀LeeSY·2021년 4월 27일
0
  • 이번 포스트에서는 AI 리스폰, 웨폰매니저 구현에 대해 다룬다.
  • 또한 게임 소개를 위한 간략한 포스터 이미지를 소개한다.
  1. 처음부터 맵에 AI가 존재하는 것이 아니라 특정 위치에 접근하면 AI들이 자동으로 리스폰이 되는 시스템을 구현했다.
    • AI가 소환될 위치, 등록할 AI를 배열 및 List 형태로 선언하여 관리한다.
public class RespawnObj : MonoBehaviour
{
    // 오브젝트가 리스폰 될 위치들을 리스트를 통해 선언한다.
    List<Transform> spawnPos = new List<Transform>();

    // 몬스터는 여러마리, 여러 종류가 소환될 수 있으므로 배열로 선언
    GameObject[] monsters;
    
    // 리스폰할 몬스터 오브젝트를 인스펙터 창에서 지정
    public GameObject monPrefab;
   
    // 리스폰할 오브젝트 개수
    public int spawnNumber;

    int deadMonsters = 0;
    // Start is called before the first frame update
    void Start()
    {
        MakeSpawnPos();
    }

    void MakeSpawnPos()
    { 
        foreach(Transform pos in transform)
        {
            if(pos.tag == "Respawn") //pos는 오브젝트가 소환될 정확한 좌표값이다. 그 좌표값 개수를 Respawn태그로 지정한다.
            {
                spawnPos.Add(pos); //오브젝트 생성 위치 값 개수를 늘리기 위한 ADD() 사용
            }
        }
        if(spawnNumber > spawnPos.Count)
        {
            spawnNumber = spawnPos.Count;
        }

        monsters = new GameObject[spawnNumber];

        MakeMonsters();
    }

    void MakeMonsters()
    {
        for(int i=0; i<spawnNumber; i++)
        {
            GameObject mon = Instantiate(monPrefab, spawnPos[i].position, Quaternion.identity) as GameObject;
            mon.SetActive(false);

            monsters[i] = mon; // 스폰할 개수만큼 몬스터를 생성한다.
        }
    }

    void SpawnMonster()
    {
        for(int i=0; i<monsters.Length; i++)
        {
            monsters[i].SetActive(true);
        } // 리스폰 전에 보이지 않던 몬스터들이 리스폰 적용 후 맵에 나타난다.
    }

    private void OnTriggerEnter(Collider col)
    {
        if(col.gameObject.tag == "Player")
        {
            SpawnMonster();
            GetComponent<SphereCollider>().enabled = false;
        } // 플레이어가 일정 범위안에 들어오면 리스폰이 활성화된다.
    }
   
}


-> pos를 통해 오브젝트의 리스폰 위치를 지정한 상태 모습

  1. Weapon Manager_Dictionary : 플레이어가 무기를 여러가지 소유하고 있을 때, 원하는 무기를 키보드 또는 UI 버튼을 통해 전환하고 사용할 수 있도록 하는 시스템이다.
    • Dictionary : C#에서는 파이썬과 같이 key:value를 세트로 저장할 수 있는 연상 배열이다.
    • 선언 방식 : Dictionary<Key 타입, Value 타입> 변수명 = new Dictionary<Key 타입, Value 타입>()
//손이나 총으로 전환하는 시스템을 관리할 딕셔너리 선언
    private Dictionary<string, Gun> gunDictionary = new Dictionary<string, Gun>();
    private Dictionary<string, Hand> handDictionary = new Dictionary<string, Hand>();
  1. Weapon Manager_Source Code
void Start()
    {
        for (int i = 0; i < guns.Length; i++)
        {
            gunDictionary.Add(guns[i].gunName, guns[i]); 
            // gunDictionary에 새로운 gun 요소를 추가한다.
        }
        for (int i = 0; i < hands.Length; i++)
        {
            handDictionary.Add(hands[i].HandName, hands[i]);
            // gunDictionary에 새로운 hand 요소를 추가한다.
        }

        // gunDictionary.Add("AK47", guns[0]);
    }

    // Update is called once per frame
    void Update()
    {
        if(!isChangeWeapon)
        {
            if (Input.GetKeyDown(KeyCode.Alpha1))
                StartCoroutine(ChangeWeaponCoroutine("HAND", "맨손"));
            // 숫자 1번 누르면 맨손으로 교체
            else if (Input.GetKeyDown(KeyCode.Alpha2))
                StartCoroutine(ChangeWeaponCoroutine("GUN", "SubMachineGun1"));
            // 숫자 2번 누르면 총으로 교체
        }
    }

    public IEnumerator ChangeWeaponCoroutine(string _type,string _name)
    {
        isChangeWeapon = true;
        currentWeaponAnim.SetTrigger("Weapon_Out");
        // 무기를 꺼내는 동작 애니메이션 실행

        yield return new WaitForSeconds(changeWeaponDelayTime);
        // 행동 전환 간의 딜레이 시간 

        CancelPreWeaponAction();
        WeaponChange(_type, _name);

        yield return new WaitForSeconds(changeWeaponEndDelayTime);
        currentWeaponType = _type;
        isChangeWeapon = false;
    }

    private void CancelPreWeaponAction()
    {
        switch(currentWeaponType)
        {
            case "GUN":
                theGunController.CancelFineSight(); // 정조준 상태 해제
                theGunController.CancelReload(); // 재장전 상태 해제
                GunController.isActive = false;
                break;
            case "HAND":
                HandController.isActive = false;
                break;
        }
    }

    private void WeaponChange(string _type, string _name)
    {
        if(_type == "GUN")
            theGunController.GunChange(gunDictionary[_name]); 
            // 딕셔너리에 저장된 총을 불러온 뒤 GunChange의 인자값으로 받는다.
        else if(_type== "HAND")
            theHandController.HandChange(handDictionary[_name]);
            // 위와 같이 딕셔너리에 저장된 맨손을 불러온다.

    }

-> 맨손과 총 2가지 형태로 전환 가능하며, 이 기능을 게임 시나리오 구성 시 사용할 것이다.

profile
A little strange but passionate, sincere hard worker.

0개의 댓글