SimpleRPG - GameScene에서 몬스터 사망시 아이템 획득 후 장착 > 포탈타고 이동 구현+fade in, out>씬전환
2023. 8. 13.

Hero, Monster 동적 생성으로 수정

+) 몬스터 별로 공격 받는 이펙트 다르게 할까해서 코드를 좀 수정했다.

create Empty한 후 각각 넣어준다.
각각의 아이템들은 ItemController로 관리된다.
CreateItem을해 몬스터가 죽으면 아이템을 생성하도록 구현
몬스터를 만들면 그룹화해 관리한다. 죽으면 리스트에서도 삭제
몬스터가 다 죽고나면 포탈을 생성한다. 포탈에 일정거리 이상 가까워지면 다음씬으로 넘어간다.
포탈생성함수, 다음씬으로 넘어가는 함수

 

 

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class HeroController : MonoBehaviour
{
    public enum eState
    {
        Idle, Run, Attack
    }
    public float radius = 1;
    public float Radius
    {
        get
        {
            return this.radius;
        }
    }
    public Transform WeaponTrans
    {
        get { return weaponTrans; }
    }
    public eState state;
    [SerializeField] private Transform swordTrans;
    private Transform weaponTrans;
    [SerializeField] private Transform shieldTrans;
    private MonsterController monsterController;
    private ItemController item;
    private ItemGenerator itemGenerator;
    private Coroutine waitRoutine;
    private Coroutine shieldRoutine;
    private GameObject target;//타겟 게임 오브젝트
    private Vector3 targetPosition;
    private float moveSpeed = 2f;
    private Animator anim;
    private Coroutine routine;
    private float impactTime = 0.399f;
    private GameObject swordGo;
    private GameObject shieldGo;
    // Start is called before the first frame update
    void Start()
    {
        this.monsterController = GameObject.FindObjectOfType<MonsterController>();
        this.itemGenerator = GameObject.FindObjectOfType<ItemGenerator>();
        this.target = monsterController.gameObject;
       // this.transform.position = targetPosition;
        this.anim = GetComponent<Animator>();
        this.weaponTrans = swordTrans;//weaponTrans를 검 위치로 초기화
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void Move(Vector3 targetPosition)
    {
        //타겟을 지움 
        this.monsterController = null;
        this.targetPosition = targetPosition;
        Debug.Log("Move");
        //이동시작
        if (this.routine != null)
        {
            //이미 코루틴이 실행중이다 -> 중지 
            this.StopCoroutine(this.routine);
        }
       this.routine = StartCoroutine(this.CoMove());//코루틴 시작, 변수에 넣어주는 것 잊지말자.
    }
    public void MoveToMonster(MonsterController target)
    {
        this.monsterController = target;        
        this.targetPosition = this.monsterController.transform.position;//이동할 목표 지점을 저장

        Debug.Log("MoveToMonster");
        // Debug.LogFormat("targetPosition: {0},{1}",targetPosition,this.target.gameObject.transform.position);
        //이동시작      
        if (this.routine != null)
        {
            //이미 코루틴이 실행중이다 -> 중지 
            this.StopCoroutine(this.routine);
        }
        this.routine = StartCoroutine(this.CoMove());
       // this.anim.SetInteger("State", 1);//Run Animation
    }
    private IEnumerator CoMove()
    {
        while (true)
        {
            this.transform.LookAt(this.targetPosition);//방향을 바라봄
            this.transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);//정면으로 이동
            this.PlayAnimation(eState.Run);//Run 애니메이션 실행
            float distance = Vector3.Distance(this.transform.position, this.targetPosition);
            //  Debug.Log(distance);
            if (this.monsterController != null)  //타겟이 있을 경우
            {//this.targetPosition은 Vector3라 null과 비교하면안된다. 주의.
                if (distance <= (1f+1f))
                {
                    this.PlayAnimation(HeroController.eState.Idle);
                    break;//break없으면 무한루프돼서 유니티 멈춘다.
                }
            }
            else//타겟이 없으면
            {
                // Debug.Log(distance);
                if (distance <= 0.1f)//** 0이 될수 없다 가까워질때 도착한것으로 판단 하자 
                {//도착
                    this.PlayAnimation(eState.Idle);//Idle 애니메이션 실행
                    break;//isMoveStart 같은 변수를 안쓸 수 있다.
                }
            }
            yield return null;//다음 프레임 시작
        }
        Debug.Log("<color=yellow>도착!</color>");
    }

    public void PlayAnimation(eState state)
    {
        if (this.state != state)//중복막기
        {

            Debug.LogFormat("Hero: {0} => {1}", this.state, state);
            this.state = state;
            this.anim.SetInteger("State", (int)state);//정수 -> enum

            switch (state)
            {
                case eState.Attack:
                    //이미 코루틴이 실행중이라면 중지
                    if (this.routine != null)
                    {
                        this.StopCoroutine(this.routine);
                    }
                    this.routine = this.StartCoroutine(this.WaitForCompleteAttackAnimation());
                    break;

            }
        }
        else
        {
            //Debug.LogFormat("{0}는 현재 상태와 동일한 상태입니다.", state);
        }

    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.radius);
    }

    public void Attack(MonsterController target)
    {
        Debug.Log("Attack!!");
        PlayAnimation(eState.Attack);

    }
    //코루틴 함수
    //IEnumerator 반환타입을 갖는 1개 이상의 yield return을 포함하는 함수
    private IEnumerator WaitForCompleteAttackAnimation()
    {//상태는 바로 변하지않는다. 다음 프레임에 변한다. 코루틴으로 확인해보자
        yield return null;//다음 프레임의 시작.yield return 위치에 주의.
        Debug.Log("공격 애니메이션이 끝날때까지 기다림");
        AnimatorStateInfo animStateInfo = this.anim.GetCurrentAnimatorStateInfo(0);
        bool isAttackState = animStateInfo.IsName("Attack01");//애니매이터의 애니메이션 이름
        Debug.LogFormat("isAttackState:{0}", isAttackState);
        if (isAttackState)
        {
            Debug.LogFormat("animatorStateInfo.Length:{0}", animStateInfo.length);
        }
        else
        {
            Debug.Log("attack state가 아닙니다.");
        }
        //yield return new WaitForSeconds(animStateInfo.length);
        yield return new WaitForSeconds(this.impactTime); //Impact 
        Debug.Log("<color=red>Impact</color>");
        //대상에게 피해를 입힘
        // this.target.state = MonsterController.eState.GetHit;
        this.monsterController.PlayAnimation(MonsterController.eState.GetHit);
        Debug.LogFormat("after target.state: {0}", this.monsterController.state);
        yield return new WaitForSeconds(animStateInfo.length - this.impactTime);    //0.72초만큼 기다림 
        this.monsterController.PlayAnimation(MonsterController.eState.Idle);
        //Idle애니메이션을 함 
        //this.anim.SetInteger("State", 0);
        this.PlayAnimation(eState.Idle);

    }
    private IEnumerator CoEquipSword()
    {
        yield return null;//다음 프레임
        Debug.LogFormat("[CoEquipSword] childCount:{0}", this.weaponTrans.childCount);
        this.EquipSword();

    }
    private IEnumerator CoEquipShield()
    {
        yield return null;//다음 프레임
        this.EquipShield();
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other != null)
        {//충돌하면
            if (other.tag == "Item")
            {
                Debug.Log("아이템과충돌!");
                Destroy(other.gameObject);

                Debug.LogFormat("=> {0}", this.weaponTrans.childCount);

                //this.onTriggerItem();

                item = other.gameObject.GetComponent<ItemController>();

                if (item != null)
                {
                    Debug.LogFormat("<color=red>ItemType: {0}</color>", item.ItemType);

                    if (item.ItemType == GameEnums.eItemType.Sword)
                    {
                        this.SwordTransform();//검 위치 받아옴
                                              // Debug.Log(this.weaponTrans.position);                           
                        this.RemoveEquippedItem();
                        if (this.waitRoutine != null)
                        {
                            this.StopCoroutine(this.waitRoutine);//이미 코루틴이면 실행 중지
                        }
                        this.waitRoutine = this.StartCoroutine(this.CoEquipSword());//코루틴 시작                           

                    }
                    else if (item.ItemType == GameEnums.eItemType.Shield)
                    {
                        this.ShieldTransform();//방패 위치 받아옴                        
                        this.RemoveEquippedItem();
                        if (this.shieldRoutine != null)
                        {
                            this.StopCoroutine(this.shieldRoutine);//이미 코루틴이면 실행 중지
                        }
                        this.shieldRoutine = this.StartCoroutine(this.CoEquipShield());//코루틴 시작                           

                    }
                }
            }
        }

    }
    public bool HasWeapon()
    {
        return this.weaponTrans.childCount > 0;
    }
    public Transform ShieldTransform()
    {
        this.weaponTrans = this.shieldTrans;
        return this.weaponTrans;
    }
    public Transform SwordTransform()
    {
        this.weaponTrans = this.swordTrans;
        return this.weaponTrans;
    }

    private void RemoveEquippedItem()
    {

        //자식이 있는가?
        Debug.LogFormat("자식의수: {0}", this.weaponTrans.childCount);
        if (this.weaponTrans.childCount == 0)
        {
            //자식이 없다 (착용중인 무기가 없다)
            Debug.Log("착용중인 무기가 없습니다.");
        }
        else
        {
            //자식이 있다 (착용중인 무기가 있다)                
            Transform child = this.weaponTrans.GetChild(0);   //첫번째 자식                                                                  //무기를 제거 
            Destroy(child.gameObject);//무기 제거
            Debug.LogFormat("childCount:{0}", this.weaponTrans.childCount);

        }
    }
    private void EquipSword()
    {

        Debug.Log("생성시 부모를 지정");
        //this.SwordTransform();
        bool hasWeapon = this.HasWeapon();
        if (!hasWeapon)
        {
            this.swordGo = this.itemGenerator.GenerateItem(GameEnums.eItemType.Sword, this.weaponTrans.position);
            //GenerateItem은 instantiate할 때 부모 설정 안된다.
            //만들어지고나서 부모 설정 
            this.swordGo.transform.SetParent(this.WeaponTrans);

            Debug.Log("Sword 장착");
        }
        else
        {
            Debug.Log("이미 착용중입니다.");
        }
    }

    private void EquipShield()
    {

        Debug.Log("생성시 부모를 지정");
        //this.SwordTransform();
        bool hasWeapon = this.HasWeapon();
        if (!hasWeapon)
        {
            this.shieldGo = this.itemGenerator.GenerateItem(GameEnums.eItemType.Shield, this.weaponTrans.position);
            //GenerateItem은 instantiate할 때 부모 설정 안된다.
            //만들어지고나서 부모 설정 
            this.shieldGo.transform.SetParent(this.WeaponTrans);
            this.shieldGo.transform.localPosition = Vector3.zero;
            // go.transform.localRotation = Quaternion.identity;//회전을 초기화
            this.shieldGo.transform.localRotation = Quaternion.Euler(new Vector3(-0.315f, -90, 0));
            Debug.Log("Shield 장착");
        }
        else
        {
            Debug.Log("이미 착용중입니다.");
        }
    }


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

public class HeroGenerator : MonoBehaviour
{
    [SerializeField] private List<GameObject> prefabList;//동적 배열: 컬렉션은 사용전 반드시 인스턴스화
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < this.prefabList.Count; i++)
        {
            GameObject prefab = this.prefabList[i];
            Debug.LogFormat("index: {0}, prefab: {1}", i, prefab);
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    public HeroController GenerateHero(GameEnums.ePlayerType playerType, Vector3 initPosition)
    {
        Debug.LogFormat("monstertype:{0}", playerType);
        int index = (int)playerType;//플레이어 타입 인덱스로 변경
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabList[index];

        GameObject go = Instantiate(prefab);//위치를 결정 하지 않은 상태 (프리팹의 설정된 위치에 생성됨)         
        go.transform.position = initPosition;//위치를 설정
        if (go.GetComponent<HeroController>() == null)
        {
            //동적으로 컴포넌트를 부착 할수 있음 
           HeroController controller = go.AddComponent<HeroController>();
        }
        return go.GetComponent<HeroController>();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using System;

public class MonsterController : MonoBehaviour
{
    public float radius =1f;
    public int hp=3;
    public enum eState
    {
        Idle, Run, GetHit, Die
    }
    public eState state;
    public float Radius
    {
        get
        {
            return this.radius;
        }
    }
    //public Action onHit;//using System작성하고 써야함
    public System.Action<GameEnums.eItemType> onDie; //대리자변수 선언 
    [SerializeField] private GameObject hitFxPrefab;
    [SerializeField] private GameEnums.eItemType rewardItemType;
    private Animator anim;
    // Start is called before the first frame update
    void Start()
    {
        this.anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void HitDamage()
    {       
        this.onHit();//대리자 사용
        if (hp <= 0) //hp 0 이하
        {
            this.Die();
        }
    }

    private void Die()
    {
        StartCoroutine(this.CoDie());
    }

    private IEnumerator CoDie()
    {
        // this.anim.SetInteger("State", 3);
        this.PlayAnimation(eState.Die);
        yield return new WaitForSeconds(2.0f);
        this.onDie(this.rewardItemType);   //대리자 호출 
                                           //죽으면 아이템 타입 리턴
    }
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.green;
        GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.radius);
    }
    public void PlayAnimation(eState state)
    {
        //state = eState.GetHit;
        if (this.state != state)
        {

            Debug.LogFormat("Monster: {0} => {1}", this.state, state);
            this.state = state;
            this.anim.SetInteger("State", (int)state);//정수 -> enum
            switch (state)
            {
                case eState.GetHit:
                    this.HitDamage();
                    break;
            }
        }

    }

    public void onHit()
    {
        hp -= 1;
        Debug.Log("이펙트 생성");
        Vector3 offset = new Vector3(0, 0.5f, 0);
        Vector3 tpos = this.gameObject.transform.position + offset;
        Debug.LogFormat("생성위치:{0}", tpos);
        //프리팹 인스턴스(복사본) 생성
        GameObject fxGo = Instantiate(this.hitFxPrefab);
        fxGo.transform.position = tpos;//위치 설정
        fxGo.GetComponent<ParticleSystem>().Play();//파티클 실행
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterGenerator : MonoBehaviour
{
    [SerializeField] private List<GameObject> prefabList;//동적 배열: 컬렉션은 사용전 반드시 인스턴스화
    // Start is called before the first frame update
    void Start()
    {
        for (int i = 0; i < this.prefabList.Count; i++)
        {
            GameObject prefab = this.prefabList[i];
            Debug.LogFormat("index: {0}, prefab: {1}", i, prefab);
        }
    }

    public MonsterController GenerateMonster(GameEnums.eMonsterType monsterType, Vector3 initPosition)
    {
        Debug.LogFormat("monstertype:{0}", monsterType);
        int index = (int)monsterType;//몬스터 타입 인덱스로 변경
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabList[index];

        GameObject go = Instantiate(prefab);//위치를 결정 하지 않은 상태 (프리팹의 설정된 위치에 생성됨)         
        go.transform.position = initPosition;//위치를 설정
        if (go.GetComponent<MonsterController>() == null)
        {
            //동적으로 컴포넌트를 부착 할수 있음 
            MonsterController controller = go.AddComponent<MonsterController>();
        }
        return go.GetComponent<MonsterController>();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameMain : MonoBehaviour
{
   
    private HeroController heroController;
    private MonsterController monsterController;
    private MonsterGenerator monsterGenerator;
    private HeroGenerator heroGenerator;
    [SerializeField]private ItemGenerator itemGenerator;
    GameObject go;
    private ItemController itemController;
    private float maxDistance = 100f;
    private List<MonsterController> monsterList = new List<MonsterController>();
    private List<ItemController> itemList = new List<ItemController>();
    [SerializeField] private GameObject portalPrefab;
    [SerializeField] private Image dim;
    private Transform nextScene;
    private Coroutine routine;
    private System.Action onFadeOutComplete;
    private float distance;
    private bool hasPortal = false;

    // Start is called before the first frame update
    void Start()
    {
        this.monsterController = GameObject.FindObjectOfType<MonsterController>();
        this.monsterGenerator = GameObject.FindObjectOfType<MonsterGenerator>();
        this.heroGenerator = GameObject.FindAnyObjectByType<HeroGenerator>();
        this.itemController = GameObject.FindObjectOfType<ItemController>();
        this.heroController = this.heroGenerator.GenerateHero(GameEnums.ePlayerType.DogWarrior, new Vector3(0, 0, 0));

        MonsterController turtleController = this.monsterGenerator.GenerateMonster(GameEnums.eMonsterType.Tutle, new Vector3(-3, 0, 0));
        turtleController.onDie = (rewardItemType) => {
            Debug.Log("거북이 죽음");
            var pos = turtleController.gameObject.transform.position;
            //Debug.Log(pos);
            this.monsterList.Remove(turtleController);
            Destroy(turtleController.gameObject);
            this.CreateItem(rewardItemType,pos);
        };


        MonsterController slimeController = this.monsterGenerator.GenerateMonster(GameEnums.eMonsterType.Slime, new Vector3(0, 0, 3));
        slimeController.onDie = (rewardItemType) =>
        {
            Debug.Log("슬라임 죽음");
            Vector3 pos = slimeController.gameObject.transform.position;
            this.monsterList.Remove(slimeController);
            Destroy(slimeController.gameObject);
            this.CreateItem(rewardItemType, pos);
        };

        //만들어진 개체들을 그룹화 관리 
        //배열, 컬렉션 
        //동적 배열 
        this.monsterList.Add(turtleController);
        this.monsterList.Add(slimeController);
        Debug.LogFormat("this.monsterList.Count: {0}", this.monsterList.Count);
        //리스트의 요소를 출력 
        foreach (MonsterController monster in this.monsterList)
        {
            Debug.LogFormat("monster: {0}", monster);
        }

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))//마우스 좌클릭시 
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Debug.DrawRay(ray.origin, ray.direction*100f, Color.red,3f);//ray 그리기
            RaycastHit hit;// Raycast에서 out 키워드 사용을 위한 변수 선언        
            if (Physics.Raycast(ray, out hit, maxDistance)) //Ray 충돌검사
            {
                if (hit.collider.tag == "Monster")//몬스터 클릭시
                {//태그를 통해 몬스터에 접근
                    Debug.LogFormat("Monster: {0}", hit.collider.tag);
                    //거리를 구한다.
                    Vector3 targetPosition = hit.collider.gameObject.transform.position;
                    Vector3 start = this.heroController.transform.position;
                    float distance = Vector3.Distance(start, targetPosition);
                    this.monsterController = hit.collider.gameObject.GetComponent<MonsterController>();
                    //각 반지름 더한거와 비교
                    float sumRadius = this.heroController.Radius + monsterController.Radius;
                    //Debug.Log(distance);
                    if (this.IsWithinRange(distance,sumRadius))//사거리 안에 들어옴 => attack
                    {
                        
                        Debug.Log("Attack");
                        //HeroController에게 공격을 명령
                        this.heroController.Attack(this.monsterController);
                    }
                    else//이동
                    {
                        this.heroController.MoveToMonster(monsterController);
                    }

                    

                }
                else if (hit.collider.tag == "Ground")
                {
                    Debug.Log(hit.point);
                    this.heroController.Move(hit.point);
                }

            }

           
        }
        if (monsterList.Count <= 0)
        {
            //Debug.LogFormat("monsterCount:{0}", monsterList.Count);
            if (this.hasPortal == false)
            {
                this.hasPortal = true;
                this.CreatePortal();//Portal 생성
                this.nextScene = this.portalPrefab.transform;
                if (this.routine != null)
                {
                    this.StopCoroutine(this.routine);//이미 코루틴이면 실행 중지
                }

                //이벤트 추가
                this.onFadeOutComplete = () =>//fadeout 끝나면
                {
                    SceneManager.LoadScene("Test_BossScene");
                    Debug.Log("Play Next Scene");
                };
                this.routine = StartCoroutine(this.CoNextScene());
            }

        }

    }

    private bool IsWithinRange(float distance, float radius)
    {
        return radius > distance;//true
    }

    private void CreateItem(GameEnums.eItemType itemType, Vector3 position)
    {
        Debug.LogFormat("<color=yellow>CreateItem: {0}</color>", itemType);
        //Debug.Log(itemGenerator.prefabList[0]);
        this.itemGenerator.GenerateItem(itemType, position);
    }

    private void CreatePortal()
    {
        //몬스터가 다 제거되면 포탈생성         
        Instantiate(this.portalPrefab);
        this.portalPrefab.transform.position = new Vector3(6, 0, 10);     
        this.hasPortal = true;
    }
    private IEnumerator CoNextScene()
    {
        Color color = this.dim.color;
        while (true)
        {
            //Debug.LogFormat("portal position: {0}", nextScene.position);
            //  Debug.LogFormat("hero position: {0}", this.heroController.gameObject.transform.position);
            this.distance = Vector3.Distance(this.heroController.gameObject.transform.position, nextScene.position);
            Debug.LogFormat("Portal distance: {0}", distance);
            if (distance != 0 && distance < 5f)
            {
                Debug.Log(distance);
                {
                    color.a += 0.01f;
                    this.dim.color = color;
                    Debug.Log(this.dim.color.a);
                    if (this.dim.color.a >= 1)
                    {
                        break;
                    }
                }
            }
            yield return null;
        }
        Debug.LogFormat("fadeout complete!");
        this.onFadeOutComplete();   //대리자 호출 

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

public class GameEnums
{
    public enum ePlayerType
    {
        DogWarrior
    }
  public enum eMonsterType
    {
        Tutle,Slime
    }

  public enum eItemType
    {
        Potion,Sword,Shield
    } 
}
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static GameEnums;

public class ItemGenerator : MonoBehaviour
{
    [SerializeField] private List<GameObject> prefabList;//동적 배열: 컬렉션은 사용전 반드시 인스턴스화
                                                         // Start is called before the first frame update


    public GameObject GenerateItem(GameEnums.eItemType itemType, Vector3 itemPosition)
    {
        //아이템 타입에 따라 어떤 프리팹으로 복사본(인스턴스)를 생성할지 결정
        //Debug.LogFormat("itemtype: {0}", itemType);
        int index = (int)itemType;//아이템 타입 인덱스로 변경
                                  //Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabList[index];

        GameObject go = Instantiate(prefab);//위치를 결정 하지 않은 상태 (프리팹의 설정된 위치에 생성됨)         
        go.transform.position = itemPosition;//위치를 설정

        return go;
    }

    public GameObject GetItem(GameEnums.eItemType itemType)
    {
        GameObject go = Instantiate(this.prefabList[(int)itemType]);
        return go;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemController : MonoBehaviour
{
    [SerializeField] GameEnums.eItemType itemType;
    public GameEnums.eItemType ItemType
    {
        get
        {
            Debug.LogFormat("itemController: {0}",this.itemType);
            return this.itemType;
        }
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
myoskin