카테고리 없음

[4Idle - Gazzlers] Wave 기능 구현 1 - 팝업 선택 후 총기 변경

meltingmelvin 2024. 1. 3. 17:53

먼저 GameScene에 웨이브 기능을 추가해주었다.

-웨이브가 끝났을 때 웨이브 별로 팝업이 뜨게 한다.

-이 팝업을 선택하고 나면 선택한 내용에 따라 게임의 기능이 변경되어야한다.

 

웨이브 팝업

https://made-myblog.tistory.com/74

 

Gazzlers 개발일지 - WAVE 이후 보상(아이템) 선택 구현

오늘 구현하고자 하는 부분 => WAVE 이후 아이템 선택 및 WAVE 시작 1. 아이템 구조 설정 2. json 파일 생성 (1) Reward 내용 - 적 타격시 총알 되받기 - 탄창 소진 시 자동충전 - 총 공격력 상승 - 기본 총의

made-myblog.tistory.com

-팀원이 테스트해준 팝업 선택을 이용해 GameScene에서 웨이브 지점 도달 시, 팝업이 형성되도록 수정해준다.

DataManager 수정

- DataManager를 수정해준다. 데이터 매니저를 통해 데이터를 관리한다.

main 수정

 

main 수

 

-기존의 coStartSpawnEnemy 호출부분을 주석처리해주고, CoCompleteWave내에서 호출하도록 수정해준다.

-CoCompleteWave는 웨이브 선택창이 평소에는 비활성화되어있다가 웨이브 끝나고 선택이 필요할때 나타나게 한다.

 

 

 

 

-PlayerCar의 자식으로 RewardGroup 오브젝트를 넣어준다.

 

-Reward의 자식으로 존재하는 object에 이벤트를 연결해준다.

 

 

-reward.cs, rewardGroupController.cs, rewardData.cs를 작성해준다.

 

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

public class Reward : MonoBehaviour
{
    [SerializeField] private TMP_Text textName;
    [SerializeField] private TMP_Text textDescription;
    [SerializeField] private GameObject rewardGo;
    private RewardData rewardData;
    public System.Action<RewardData> onWhenSelect;
    public System.Action onWhenUnselect;
    private Vector3 rewardGoLocalPos = Vector3.up * 0.25f;

    public void Init(System.Action<RewardData> onWhenSelect, System.Action onWhenUnselect)
    {
        this.onWhenSelect = onWhenSelect;
        this.onWhenUnselect = onWhenUnselect;
    }

    public void SetData(int id)
    {
        RewardData data = DataManager.Instance.GetRewardData(id);
        this.rewardData = data;
        this.textName.text = data.name;
        string description = string.Format(data.desc, data.value);
        this.textDescription.text = description;
    }

    public void OnWhenSelect()
    {
        Debug.LogFormat("{0} selected", this.rewardData.name);
        this.onWhenSelect(this.rewardData);
    }

    public void OnWhenUnselect()
    {
        Debug.LogFormat("{0} unselected", this.rewardData.name);
        this.onWhenUnselect();
        this.rewardGo.transform.localPosition = this.rewardGoLocalPos;
        this.rewardGo.transform.rotation = Quaternion.identity;
    }
}

 

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

public class RewardData
{
    public int id;
    public string name;
    public string desc;
    public float value;
    public string prefab_name;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;


public class RewardGroupController : MonoBehaviour
{
    [SerializeField] private Reward[] arrRewards;
    private List<int> listRewardDatasID = new List<int>();
    public System.Action<RewardData> onWhenSelect;
    public System.Action onWhenUnselect;

    public void Init()
    {
        List<RewardData> listRewardDatas = DataManager.Instance.GetRewardDatas();
        this.listRewardDatasID = (from RewardData data in listRewardDatas select data.id).ToList();
        foreach (var data in listRewardDatas)
        {
            Debug.LogFormat("id: {0}", data.id);
            Debug.LogFormat("name: {0}", data.name);
            Debug.LogFormat("desc: {0}", data.desc);
            Debug.LogFormat("value: {0}", data.value);
            Debug.LogFormat("prefab_name: {0}", data.prefab_name);
        }
        foreach (var reward in arrRewards)
        {
            reward.Init(this.onWhenSelect, this.onWhenUnselect);
        }
    }

    public void ShowRewards()
    {
        this.gameObject.SetActive(true);
        List<int> rewardID = this.listRewardDatasID.ToList();
        for (int i = 0; i < arrRewards.Length; i++)
        {
            int idx = Random.Range(0, rewardID.Count);
            Debug.LogFormat("<color=red>남은 리워드 개수: {0}</color>", rewardID.Count);
            int id = rewardID[idx];
            this.arrRewards[i].SetData(id);
            rewardID.Remove(id);
        }
    }

    public void HideRewards(int id)
    {
        if (id == 2002 || id == 2003 || id == 2004)
        {
            listRewardDatasID.Remove(id);
        }
        this.gameObject.SetActive(false);
    }
}

 

 

 

 

=> ChangeGun: 총을 두번째 총으로 변경한다.

-총을 변경해주기 위해서 rightHandController를 수정해 주었다.

rightHandController.cs 수정

-isSecondGun 이 True가 되면 총의 재질을 바꿔준다.

-update 문 내에서 OnChangeSecondGun은 한번만 호출하기위해 count라는 변수를 사용해주었다.

=> isSecondGun 이 true더라도 계속 호출되는것을 방지한다. count가 start할때는 0, 한번 호출한 후로는 1이기때문이다.

gameMain에 OnChangeSecondGun 작성

-총이 바뀌고 나면 main에 전달해 데이터값을 변경한다.

 

https://lj9369.tistory.com/130

 

Gazzlers R&D - 오른손 총 구현(미사일)

▼ 구현할 영상 https://www.youtube.com/watch?v=z2y_uP3i1YY ▼구현할 목록 - 오른쪽 IndexTrigger를 누르고 떼면 앞으로 미사일 총알이 발사되고 이펙트 생성하기 ▼구현 방법 - 다른 팀원(영원님)이 미리 만들

lj9369.tistory.com

-팀원분이 만들어주신 총2를 이용하여 스크립트를 수정해주었다.

-빈 오브젝트를 생성하고 MissileBulletGenerator 스크립트를 넣어준다.

- 총알이 발사되도록 하는 스크립트이다.

-할당된 프리팹에는 MissileBullet.cs가 부착되어있다.

MissileBullet.cs

-MissileBullet은 MissileBulletGenerator 오브젝트의 자식으로 생성되므로 이 오브젝트를 통해 총을 쏘는 손, 즉 RightHand에 접근할 수 있다. 프리팹에서 게임씬에 있는 오브젝트에 접근할 때는 부모자식관계를 이용해보자.

- 충돌 처리 시 충돌지점과 충돌한 오브젝트를 OnHitEnemy의 매개변수로 전달한다.

 

main 수정

-GameMain을 수정해 changeGun 창을 선택시 총이 바뀌도록 한다.

 

change gun 창 선택시 총2로 변경

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
using System.Linq;
using Newtonsoft.Json;
using System.IO;
public class GameMain : MonoBehaviour
    {
        [SerializeField] Canvas worldCanvas;
        [SerializeField] Canvas rightHandCanvas;
        [SerializeField] TextMeshProUGUI guideText;
        [SerializeField] GameObject uiHPBarPrefab;
        [SerializeField] GameObject uiDamageTextPrefab;
        [SerializeField] GameObject uiEnergyCellPrefab;
        [SerializeField] GameObject gunEnergyCellGo;
        [SerializeField] GameObject uiPlayerHpTextGo;
        [SerializeField] GameObject uiPlayerHpSliderGo;
        [SerializeField] GameObject uiPlayerScoreTextGo;
        [SerializeField] EnergyCellController energyCellForCharge;
        [SerializeField] RightHandController rightHand;
        [SerializeField] LeftHandController leftHand;
        [SerializeField] Transform uiEnergyCellTransform;
        [SerializeField] Transform worldUITransform;
        
        public bool isFirstHP = false;

        private GameObject hpBarUIGo;
        private GameObject damageTextUIGo;
        private GameObject energyTextUIGo;

        private Action<Enemy1Move> OnGenerateEnemy;

        private int currPlayerHp;
        private int currScore;
        private int currShiledGauge;
        private int currGunId;

        private string currGunType;
        private int currGunDamage;
        private int currGunEnergy;
        private int currGunMaxEnergy;
  
        private List<GameObject> enemyHpBarPools = new List<GameObject>();
        private List<GameObject> activeHPBar = new List<GameObject>();


    //----------------------------------SJY Map Main-----------------------------------------------------------
    [SerializeField] private MapController mapController;
    [SerializeField] private CamMove camMove;


    //----------------------------------SJY Enemy1Move Main-----------------------------------------------------------
    public enum eWave
    {
        WAVE1, WAVE2, WAVE3
    }
    private eWave wave;

    [SerializeField] private Transform[] arrTargetPos;
    private List<Enemy1Move> listEnemies = new List<Enemy1Move>();
    private List<bool> isTargeted = new List<bool>();
    private int EnemyCount = 2;

    private int[] maxWaveEnemyCount = new int[3] { 3, 6, 9 };
    private int remainEnemyCount;
    //----------------------------------SJY EnemyAttack-----------------------------------------------------------
    private float enemyAttackCoolTime = 4f;
    private float enemyAttackelapsedTime;
    private bool isEnemyAttack;
    private int enemyAttackIdx = 0;


    //----------------------------------SJY Reward-----------------------------------------------------------------
    [SerializeField] private RewardGroupController rewardGroupCtrl;
    [SerializeField] private GameObject waveCompleteEffectPrefab;
    [SerializeField] private GameObject waveCompletePhrasePrefab;
    private RewardData grabRewardData;
    private bool isGrabReward;
    public float maxUsingRewardTime = 3f;
    private float usingRewardElapsedTime;
    private Dictionary<int, int> dicGetRewards = new Dictionary<int, int>();

    private void Awake()
        {
           
        }
        // Start is called before the first frame update
        void Start()
        {
       // Debug.Log("Start");
            this.guideText.gameObject.SetActive(false);
            this.worldCanvas.transform.SetParent(this.worldUITransform);
            this.worldCanvas.transform.localPosition = Vector3.zero;
            this.worldCanvas.transform.localRotation = Quaternion.identity;

            this.energyTextUIGo = this.uiEnergyCellPrefab;
            this.rightHandCanvas.transform.SetParent(this.uiEnergyCellTransform);
            this.rightHandCanvas.transform.localPosition = Vector3.zero;
            this.rightHandCanvas.transform.localRotation = Quaternion.identity;

            DataManager.Instance.LoadPlayerDatas();
            DataManager.Instance.LoadGunrDatas();
            DataManager.Instance.LoadEnemyDatas();

            List<PlayerData> playerData = DataManager.Instance.GetPlayerDatas();
            List<GunData> gunData = DataManager.Instance.GetGunDatas();
            List<EnemyData> enemyData = DataManager.Instance.GetEnemyDatas();

        Debug.LogFormat("player Data Count: {0}",playerData.Count);
        for(int i = 0; i < playerData.Count; i++)
        {//get player data
            if (playerData[i].playerUserName == "Unknown")
            {
                Debug.Log("default user");
                this.currPlayerHp = playerData[i].playerHp;
                this.currScore = playerData[i].score;
                this.currShiledGauge = playerData[i].shiledGauge;
                this.currGunId = playerData[i].currGunId;
            }
        }

        this.uiPlayerHpSliderGo.GetComponent<Slider>().maxValue = this.currPlayerHp;
       // this.uiPlayerScoreTextGo.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currScore);
        //   var playerGunId = playerData[0].currGunId;

        Debug.LogFormat("Gun Data Count: {0}", gunData.Count);
        for (int i = 0; i < gunData.Count; i++)
            {
                if (this.currGunId == gunData[i].gunId)
                {//Find player's current gun's Data on GunData 
                    Debug.Log(gunData[i].gunType);
                    this.currGunType = gunData[i].gunType;
                    this.currGunDamage = gunData[i].gunDamage;
                    this.currGunEnergy = gunData[i].gunEnergyCell;
                    this.currGunMaxEnergy = gunData[i].gunEnergyCell;

                }
            }

        this.rightHand.OnChangeSecondGun = () => 
        {//change gun data
           
            for (int i = 0; i < gunData.Count; i++)
            {
                if (gunData[i].gunId == 1001)
                {//Find player's current gun's Data on GunData 
                    Debug.Log(gunData[i].gunType);
                    this.currGunType = gunData[i].gunType;
                    this.currGunDamage = gunData[i].gunDamage;
                    this.currGunEnergy = gunData[i].gunEnergyCell;
                    this.currGunMaxEnergy = gunData[i].gunEnergyCell;

                }
            }

        };
            this.enemyHpBarPool();

        

       

            this.damageTextUIGo = Instantiate(this.uiDamageTextPrefab, this.worldCanvas.transform);
            this.damageTextUIGo.SetActive(false);


       



        this.OnGenerateEnemy = (enemy) =>
        {
            var go = this.CreateHpBar(enemy.hpBarPoint.position);
            this.activeHPBar.Add(go);
            for (int j = 0; j < enemyData.Count; j++)
            {
                if (enemy.tag == enemyData[j].enemyType)
                {

                    Debug.Log(enemyData[j].enemyType);
                    var slider = go.GetComponent<Slider>();
                    slider.maxValue = enemyData[j].enemyHp;
                    Debug.Log(slider.maxValue);
                    slider.value = slider.maxValue;//reset slider value as full state
                                                   //this.listEnemies[j].currHP = (int)slider.value; //set EnemyHp
                                                   //Debug.Log(listEnemies[j].gameObject);
                    enemy.OnGetData(enemyData[j]);

                }


            }


        };
        this.rightHand.OnHitEnemy = (hitPos,hitObject) =>
            {
               // Debug.LogFormat("Hit Enemy! Point: {0}", hitPos);
                StartCoroutine(this.CoShowDamageText(hitPos));

                for (int i = 0; i < this.listEnemies.Count; i++)
                {
                    if (hitObject == this.listEnemies[i].gameObject)
                    {
                        Debug.LogFormat("Object: {0} , Damage : {1}",i,currGunDamage);
                        this.activeHPBar[i].GetComponent<Slider>().value -= currGunDamage;
                       
                        hitObject.GetComponent<Enemy1Move>().OnGetHit(currGunDamage);
                        if(this.activeHPBar[i].GetComponent<Slider>().value <= 0)
                        {
                            this.activeHPBar[i].SetActive(false);
                            this.activeHPBar.Remove(this.activeHPBar[i]);
                        }
                    }
            }
                
            };

        this.rightHand.OnShoot = () =>
        {
            this.currGunEnergy -= 1;
        };

        this.energyCellForCharge.OnCharge = () => {

            
            this.currGunEnergy = this.currGunMaxEnergy;//reset energyCell as full state
            this.gunEnergyCellGo.SetActive(true);
            StartCoroutine(this.CoResetEnergyCellItem());
        
        };

        this.leftHand.OnHeal = () =>
        {
            Debug.Log("Heal");
            this.currPlayerHp += 20;
        };
        //----------------------------------SJY Map Main-----------------------------------------------------------

        Vector3 camPos = Vector3.zero;
        this.mapController.onInformInitPos = (pos) =>
        {
            camPos = pos;
        };
        this.mapController.onInformRoute = (rail) =>
        {
            this.camMove.UpdateRoute(rail.GetRoute());
        };
        this.mapController.Init();
        this.camMove.Init(camPos);

           //----------------------------------SJY Enemy1Move Main-----------------------------------------------------------
         // EnemyPool.instance.LoadAll();

        for (int i = 0; i < arrTargetPos.Length; i++)
        {
            isTargeted.Add(false);
        }
        this.StartCoroutine(this.CoStartSpawnEnemy1());


        //----------------------------------SJY Reward---------------------------------------------------------------------
        DataManager.Instance.LoadRewardDatas();
        this.rewardGroupCtrl.onWhenSelect = (rewardData) =>
        {
            //Debug.LogFormat("<color=yellow>grab reward: {0}</color>", rewardData.name);
            this.grabRewardData = rewardData;
            this.isGrabReward = true;
        };
        this.rewardGroupCtrl.onWhenUnselect = () =>
        {
            //Debug.LogFormat("unhand reward");
            this.grabRewardData = null;
            this.isGrabReward = false;
        };

        this.rewardGroupCtrl.Init();
    }
    private IEnumerator CoResetEnergyCellItem()
    {
        this.energyCellForCharge.gameObject.SetActive(false);
        yield return new WaitForSeconds(2f);
       // Debug.Log("Rest Energy Item");
        this.energyCellForCharge.transform.SetParent(this.energyCellForCharge.energyCellOriginalPoint);
        this.energyCellForCharge.transform.localPosition = Vector3.zero;
        this.energyCellForCharge.transform.localRotation = Quaternion.identity;
        this.energyCellForCharge.gameObject.SetActive(true);
    }
        private void enemyHpBarPool()
        {
      
        for (int i = 0; i < this.EnemyCount; i++)
        {
                GameObject go = Instantiate(this.uiHPBarPrefab, this.worldCanvas.transform);
                go.SetActive(false);
                this.enemyHpBarPools.Add(go);
            }
        }
        private GameObject GetEnemyHpBarInPool()
        {
            foreach(GameObject hpBar in enemyHpBarPools)
            {
                if(hpBar.activeSelf == false)
                {
                    return hpBar;               
                }
            }
            return null;
        }
        private GameObject CreateHpBar(Vector3 position)
        {
            GameObject go = this.GetEnemyHpBarInPool();
            go.transform.position = position;
            go.SetActive(true);
            return go;
        }
      
        private IEnumerator CoShowDamageText(Vector3 UIPos)
        {
            this.damageTextUIGo.transform.position = UIPos;
            this.damageTextUIGo.SetActive(true);

            var text = this.damageTextUIGo.GetComponent<TextMeshProUGUI>();
            text.text = string.Format("{0}",this.currGunDamage);
            yield return new WaitForSeconds(0.3f);
            this.damageTextUIGo.SetActive(false);
        }
        // Update is called once per frame
        void Update()
        {
        //enemy 공격 구현=======================================================================================
        if (this.listEnemies.Count > 0 && !isEnemyAttack)
        {
            this.enemyAttackelapsedTime += Time.deltaTime;
            if (this.enemyAttackelapsedTime > this.enemyAttackCoolTime)
            {
                this.listEnemies[(enemyAttackIdx++ % this.listEnemies.Count)].AttackPlayer();
                this.isEnemyAttack = true;
            }
        }
        else
        {
            this.enemyAttackelapsedTime = 0f;
            this.isEnemyAttack = false;
        }
        //=======================================================================================
        //-------------------------------------SJY Reward------------------------------------------------------
        if (isGrabReward)
        {
            if (OVRInput.Get(OVRInput.Button.PrimaryIndexTrigger, OVRInput.Controller.LTouch))
            {
                this.usingRewardElapsedTime += Time.deltaTime;
                if (this.usingRewardElapsedTime > maxUsingRewardTime)
                {
                    this.UseReward();
                }
            }
            else
            {
                this.usingRewardElapsedTime = 0f;
            }
        }
        //------------------------------------------------------------------------------------------------------

        if (activeHPBar.Count != 0)
        {
            for (int i = 0; i < this.listEnemies.Count; i++)
            {
                //Debug.LogFormat("{0}, {1}", this.activeHPBar[i], this.listEnemies[i]);
                this.activeHPBar[i].transform.position = this.listEnemies[i].hpBarPoint.position;

            }
        }
        //change energyCell UI's text
        this.energyTextUIGo.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currGunEnergy);

        //change player HP UI
        this.uiPlayerHpTextGo.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currPlayerHp);
        this.uiPlayerHpSliderGo.GetComponent<Slider>().value = this.currPlayerHp;
        //change player's score
        this.uiPlayerScoreTextGo.GetComponent<TextMeshProUGUI>().text = string.Format("{0}", this.currScore);


        this.rightHand.isAttack = true;
        if(this.currGunEnergy <= 0)
        {
            this.gunEnergyCellGo.SetActive(false);
            this.rightHand.isAttack = false;
        }

        if (isFirstHP)
        {
            this.guideText.gameObject.SetActive(true);
            this.guideText.text = "물약을 잡아 HP를 회복하세요.";
        }


    }
    //Methods
    //----------------------------------SJY Enemy1Move Main-----------------------------------------------------------

    private IEnumerator CoStartSpawnEnemy1()
    {
        this.remainEnemyCount = maxWaveEnemyCount[(int)this.wave];
        for (int i = 0; i < this.EnemyCount; i++)
        {
            yield return new WaitForSeconds(5f);
            this.SpawnEnemy1();          
        }
    }

    private void SpawnEnemy1()
    {
        float x = UnityEngine.Random.Range(-3f, 3f);
        float z = UnityEngine.Random.Range(10f, 15f);
        while (true)
        {
            int layer = 1 << 3 | 1 << 6 | 1 << 7;
            //Debug.Log(layer.ToBinaryString());
            //Debug.Log(enemy.gameObject.layer.ToString());
            Collider[] hit = new Collider[10];
            int num = Physics.OverlapSphereNonAlloc(this.arrTargetPos[2].position + Vector3.right * x
                + Vector3.forward * z, 2f, hit, layer);
            if (num == 0)
                break;
            x = UnityEngine.Random.Range(-3f, 3f);
            z = UnityEngine.Random.Range(10f, 20f);
        }

        Vector3 pos = this.arrTargetPos[2].position + Vector3.right * x + Vector3.forward * z;
        int idx = 0;
        int number = UnityEngine.Random.Range(0, 10);
        switch (this.wave)
        {
            case eWave.WAVE1:
                idx = (int)EnemyMove.eEnemyType.Enemy1;
                break;
            case eWave.WAVE2:
                if (number < 3)
                {
                    idx= (int)EnemyMove.eEnemyType.Enemy1;
                }
                else
                    idx=(int)EnemyMove.eEnemyType.Enemy2;
                break;
            case eWave.WAVE3:
                if (number < 2)
                {
                    idx = (int)EnemyMove.eEnemyType.Enemy1;
                }
                else if (number < 4)
                {
                    idx = (int)EnemyMove.eEnemyType.Enemy2;
                }
                else
                {
                    idx = (int)EnemyMove.eEnemyType.Enemy3;
                }
                break;
        }

        GameObject enemyGo = EnemyPoolManager.instance.EnableEnemy(idx);
        Enemy1Move enemy = enemyGo.GetComponent<Enemy1Move>();
        enemy.Init(pos);
        listEnemies.Add(enemy);
        enemy.onChangeTarget = (idx) =>
        {
            Debug.Log("target change!");
            Debug.LogFormat("<color=yellow>{0} preTargetPos: {1}</color>", enemy.name, arrTargetPos[idx]);
            this.SetTargetPos(enemy);
            this.isTargeted[idx] = false;
        };
        enemy.onDieEnemy = (enemy) =>
        {
            this.remainEnemyCount--;
            listEnemies.Remove(enemy);
            this.currScore += 10;
            this.isTargeted[enemy.target.Key] = false;
            EnemyPoolManager.instance.DisableEnemy(enemy.gameObject);
            if (this.remainEnemyCount >= this.EnemyCount)
            {
                Invoke("SpawnEnemy1", 1f);
            }
            else
            {
                if (this.remainEnemyCount == 0)
                {
                    //Debug.LogFormat("{0} completed", this.wave.ToString());
                    if (this.wave == eWave.WAVE3) return;
                    //this.wave++;
                    //this.StartCoroutine(CoStartSpawnEnemy1());

                    //this.rewardGroupCtrl.ShowRewards();
                    this.StartCoroutine(this.CoCompleteWave());
                }
            }
        };
        //enemy Attack 추가부분================================================================================================
        enemy.onAttackPlayer = () =>
        {
            int damage = DataManager.Instance.GetEnemyData(enemy.tag).enemyDamage;
            Debug.LogFormat("player get {0} damage / current Player's HP: {1}", damage, this.currPlayerHp);
            this.currPlayerHp -= damage;
            
        };

        enemy.onCompleteAttack = () =>
        {
            Debug.Log("enemy attack complete");
            this.isEnemyAttack = false;
            this.enemyAttackelapsedTime = 0f;
        };
        //====================================================================================================================


        this.SetTargetPos(enemy);
        this.OnGenerateEnemy(enemy);
    }

    private void SetTargetPos(Enemy1Move enemy)
    {
        List<int> listIndex = new List<int>();
        for (int i = 0; i < this.isTargeted.Count; i++)
        {
            if (!isTargeted[i])
            {
                listIndex.Add(i);
            }
        }
        int rand = UnityEngine.Random.Range(0, listIndex.Count);
        int idx = listIndex[rand];
        enemy.UpdateTargetPos(idx, this.arrTargetPos[idx]);
        this.isTargeted[idx] = true;
        Debug.LogFormat("<color=magenta>{0} curTargetPos: {1}</color>", enemy.name, arrTargetPos[idx]);
    }

    //---------------------------------------------SJY Reward-------------------------------------------------------

    private IEnumerator CoCompleteWave()
    {
        yield return new WaitForSeconds(1f);
        GameObject effectGo = Instantiate(this.waveCompleteEffectPrefab, this.arrTargetPos[2].position + Vector3.forward * 10f, Quaternion.identity);
        yield return new WaitForSeconds(4f);
        GameObject phraseGo = Instantiate(this.waveCompletePhrasePrefab, effectGo.transform.position + Vector3.up * 1f, Quaternion.identity);
        yield return new WaitForSeconds(2f);
        TMP_Text phrase = phraseGo.GetComponentInChildren<TMP_Text>();
        //Debug.LogFormat("<color=cyan>phrase: {0}</color>", phrase);
        while (true)
        {
            phrase.alpha -= 0.1f;
            yield return null;
            if (phrase.alpha <= 0)
                break;
        }
        //yield return new WaitForSeconds(7f);
        Destroy(effectGo);
        Destroy(phraseGo);
        yield return null;
        this.rewardGroupCtrl.ShowRewards();
    }
    private void UseReward()
    {
        int id = this.grabRewardData.id;
        switch (id)
        {
            case 2000:
                Debug.LogFormat("damage({0}) up", this.grabRewardData.value);
                break;
            case 2001:
                Debug.LogFormat("maxHp({0}) up", this.grabRewardData.value);
                break;
            case 2002:
                Debug.LogFormat("autoCharging1");
                break;
            case 2003:
                Debug.LogFormat("autoCharging2");
                break;
            case 2004:
                Debug.LogFormat("change gun");
                this.rightHand.isSecondGun = true;
                break;
            case 2005:
                Debug.LogFormat("scope({0}) expands", this.grabRewardData.value);
                break;
        }
        if (this.dicGetRewards.ContainsKey(id))
            this.dicGetRewards[id]++;
        else
            this.dicGetRewards.Add(id, 1);
        foreach (var keyvalue in this.dicGetRewards)
        {
            Debug.LogFormat("<color=green>id: {0} count: {1}</color>", keyvalue.Key, keyvalue.Value);
        }
        this.rewardGroupCtrl.HideRewards(id);
        this.wave++;
        this.StartCoroutine(CoStartSpawnEnemy1());
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

    public class RightHandController : MonoBehaviour
    {
        public System.Action<Vector3, GameObject> OnHitEnemy;
        public System.Action OnShoot;
        public System.Action shoot;
        public System.Action OnChangeSecondGun;
        
        [SerializeField] Transform shootTrans;
        [SerializeField] Transform shootDistance;
        [SerializeField] GameObject gunLaserGo;
        [SerializeField] GameObject impactEffectGo;
        [SerializeField] GameObject gunGo;
        [SerializeField] Material[] mat;
        private GameObject gunLaserBeamGo;
        private GameObject laserImpactGo;
        private int count = 0;
         public bool isAttack = false;
        public bool isSecondGun = false;
    // --------------------------------------Second Gun LJE------------------------------------------
        [SerializeField] private GameObject shootEffectGo;
        [SerializeField] private Transform effectTrans;
        [SerializeField] private GameObject fireMuzzleEffect;


    // Start is called before the first frame update
    void Start()
        {

        //this.gunLaserBeamGo = Instantiate<GameObject>(this.gunLaserGo);
            this.gunLaserBeamGo = this.gunLaserGo;
            this.laserImpactGo = Instantiate<GameObject>(this.impactEffectGo);
            this.gunLaserBeamGo.SetActive(false);
            this.laserImpactGo.SetActive(false);


        // --------------------------------------Second Gun LJE------------------------------------------
            this.shootEffectGo = Instantiate<GameObject>(shootEffectGo);
            this.shootEffectGo.SetActive(false);
            this.fireMuzzleEffect = Instantiate<GameObject>(fireMuzzleEffect);
            this.fireMuzzleEffect.SetActive(false);

    }

        // Update is called once per frame
        void Update()
        {
       
        if (this.isSecondGun && count==0)
        {
           // Debug.Log("Gun Changed. Second Gun is Activated");
            var mat = this.gunGo.GetComponentInChildren<MeshRenderer>();
            mat.material = this.mat[0];
            this.OnChangeSecondGun();
            count=1;
        }

        if (isAttack)
        {
            this.gunLaserBeamGo.transform.position = this.shootTrans.position;

            if (OVRInput.GetDown(OVRInput.Button.SecondaryIndexTrigger))
            {
                //Debug.Log("right Hand Index Trigger");
                if (this.isSecondGun)
                {
                    Debug.Log("Gun Changed. Second Gun is Activated");
                    //var mat = this.gunGo.GetComponentInChildren<MeshRenderer>();
                    //mat.material = this.mat[0];
                    this.StartCoroutine(CoShootEffect());
                    this.StartCoroutine(CoFireEffect());
                    this.shoot();
                }
                else
                {
                    StartCoroutine(this.CoLaserBeam());
                    StartCoroutine(this.CoCheckImpact());
                }
               

                this.OnShoot();//use gun Energy
            }



        }
        }

        private IEnumerator CoLaserBeam()
        {
            //this.gunLaserBeamGo.transform.position = this.shootTrans.position;
            this.gunLaserBeamGo.SetActive(true);
            this.gunLaserBeamGo.transform.LookAt(this.shootDistance.position);//hit nothing



            yield return new WaitForSeconds(0.2f);
            this.gunLaserBeamGo.SetActive(false);
            this.laserImpactGo.SetActive(false);
        }
        private IEnumerator CoCheckImpact()
        {
            //-----------------------------check impact---------------------------------------


            Ray ray = new Ray(this.shootTrans.position, this.gunLaserBeamGo.transform.forward);
            Debug.DrawRay(ray.origin, ray.direction * 20f, Color.red, 0.3f);
            var layerMask = 3 << LayerMask.NameToLayer("Monster");
            RaycastHit hit;

            if (Physics.Raycast(ray.origin, ray.direction, out hit, 20.0f))
            {
                // Debug.Log("Hit Monster!!");
                if (!hit.collider.gameObject.CompareTag("Vehicle")&& !hit.collider.gameObject.CompareTag("Player"))
                { this.CreateImpactEffect(hit.point); }

                if (hit.collider.gameObject.CompareTag("Enemy1")|| hit.collider.gameObject.CompareTag("Enemy2")|| hit.collider.gameObject.CompareTag("Enemy3"))
                {
                    Debug.Log("Enemy");
                    this.OnHitEnemy(hit.point, hit.collider.gameObject);
                }
                var particleSys = this.gunLaserBeamGo.GetComponent<ParticleSystemRenderer>();
                particleSys.lengthScale = hit.distance;
            }
        else
        {
            var particleSys = this.gunLaserBeamGo.GetComponent<ParticleSystemRenderer>();
            particleSys.lengthScale = 12f;
        }
            //-----------------------------------------------------------------------------------
            yield return null;
        }
        private void CreateImpactEffect(Vector3 pos)
        {
            this.laserImpactGo.transform.position = pos;
            this.laserImpactGo.SetActive(true);
        }
    IEnumerator CoShootEffect()
    {
        this.shootEffectGo.transform.position = this.effectTrans.position;
        this.shootEffectGo.SetActive(true);
        yield return new WaitForSeconds(0.5f);
        this.shootEffectGo.SetActive(false);
    }

    IEnumerator CoFireEffect()
    {
        this.fireMuzzleEffect.transform.position = this.effectTrans.position;
        this.fireMuzzleEffect.SetActive(true);
        yield return new WaitForSeconds(0.3f);
        this.fireMuzzleEffect.SetActive(false);
    }
}