ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 AOS게임 만들기 -아이템과 상점 구매/판매
    유니티 2022. 7. 5. 00:11

    저희가 처음 생성한 terrain은 너무 큰것같아 우선 더작게만들어봅시다. 100/100으로 만들겠습니다.

    블루팀 위치는 5/0/95

    레드팀 위치는 95/0/5

    player는 50/0/50

    enemy_moving_points는 50/0/50

    으로 하겠습니다.

    테스트하기위해 작게만든 맵

    그리고 전에 만든 Stats 스크립트를 편집해보겠습니다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    
    public class Stats : MonoBehaviour
    {   
        #region 체력관련 변수
        public float hp;public float maxHp;
        public float mp;public float maxMp;
        #endregion
        #region 공격관련 변수
        public float atk;public float atk_speed;public float atk_range;
        #endregion
        #region 방어관련 변수
        public float def;
        #endregion
        #region 이동관련 변수
        public float spd;
        #endregion
        #region 팀관련 변수
        public float team;
        #endregion
        #region 골드관련 변수
        public float gold;public float kill_gold;
        #endregion
        #region 오브젝트관련 변수
        public NavMeshAgent agent;
        #endregion
    
        #region 아이템관련 변수
        public GameObject[] item_equip;
        #endregion
    
        
        void Start()
        {
            agent=this.gameObject.GetComponent<NavMeshAgent>();
            hp = maxHp;
            mp = maxMp;
            item_equip = new GameObject[6];//6개의 아이템장착창을 만듬
    
        }
        public void TakeDamage(float damage)
        {
            hp -= damage;//hp값을 입력받은 값으로 빼줌
        }
        public void get_gold(float got_gold)//처치한 상대의 kill_gold값을 받아서 골드를 얻음
        {
            gold += got_gold;
        }
        public void get_item(int item_index){
            if(item_equip[0]==null){//아이템장착창 1번에 아이템이 비어있으면
                // item_equip[0] = item_index;
            }
            else{//비어있지 않으면
                if(item_equip[1]==null){//아이템장착창 2번에 아이템이있는지 확인
                // item_equip[1] = item_index;
                }
                else{
                    if(item_equip[2]==null){
                    // item_equip[2] = item_index;
                    }
                    else{//비어있지 않으면
                        if(item_equip[3]==null){
                        // item_equip[3] = item_index;
                        }
                        else{//비어있지 않으면
                            if(item_equip[4]==null){
                            // item_equip[4] = item_index;
                            }
                            else{//비어있지 않으면
                                if(item_equip[5]==null){
                                // item_equip[5] = item_index;
                                }else{
                                    Debug.Log("아이템창이 가득찼습니다.");
                                }
                            }
                        }
                    }
                }
            }
        }
        void Update()
        {   
            //속도동기화
            agent.speed = spd;//최고속력
            agent.acceleration=spd; //가속도
            if (hp <= 0) //체력이 0이하면 죽음
            {
                Destroy(this.gameObject);
            }
        }
    }

    이번에 추가한 코드는 아이템을 얻었을때

    아이템창이 비어있는곳이 있다면 1번창부터 6번창까지 획득하는 것을 만든것입니다.

    전에 만든 상점에 스크롤뷰를 추가해줍시다.

    이런식으로 가로 방향의 스크롤바를 삭제하고 세로방향을 살짝 늘려주세요.

    생성된 스크롤뷰의 스크롤 리엑트 컴포넌트의 가로를 해제해주세요

     

    그리고 shop 오브젝트에 이미지하나를 만들어 주시고 소지금 위쪽에 위치시켜줍시다.

    이제 아이템을 저위에 올려놔야겟죠?

    아이템을 우선 만들어 봅시다.

    아이템의 역활은 공격력상승,체력상승등 이 잇지요?

    이런 수치를 저장하기위해서 여러방법이 있습니다 그러나 저는

    ScriptableObject를 이용해 아이템의 수치를 저장해주겠습니다.

    아이템을 만들기위해서 

    스크립트하나를 생성해줍시다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [CreateAssetMenu(fileName = "item_Data", menuName = "Scriptable Object/item_Data", order = int.MaxValue)]
    //생성메뉴바에 item_Data라는 scriptableobject를 생성하는 메뉴를 생성
    public class item_data : ScriptableObject
    {
        [SerializeField]
        private int idx;//아이템의 인덱스
        public int IDX { get { return idx; } }
        [SerializeField]
        private string item_name;//아이템이름
        public string Item_name { get { return item_name; } }
        [SerializeField]
        private int price;//가격
        public int Price { get { return price; } }
        [SerializeField]
        private int hp;//체력
        public int Hp { get { return hp; } }
        [SerializeField]
        private int damage;//데미지
        public int Damage { get { return damage; } }
        [SerializeField]
        private float moveSpeed;//이동속도
        public float MoveSpeed { get { return moveSpeed; } }
        [SerializeField]
        private float attackSpeed;//공격속도
        public float AttackSpeed { get { return attackSpeed; } }
    }

     

    이스크립트를 만들어준뒤 컴파일이 완료되면 

    이렇게 생성 탭에 item_Data를 생성할수 있게 됩니다.

    생성해봅시다.

    저는 미리 여러개 만들어놨습니다.

    처음생성한 item_Data는 아무것도 입력되어있지않은 상태입니다.

    1번아이템부터 7번아이템까지 마음대로 생성해보세요!

    저는 롱소드,롱롱소드...롱롱롱롱롱롱롱소드 를 만들었습니다.

    idx는 아이템의 번호입니다. eg(0~6)

    Item_name은 아이템의 이름(롱소드,롱롱소드,마법지팡이 등)

    price는 가격(100,200,300,등)

    HP는 체력

    Damage는 공격력

    Move Speed는 속도

    attack speed는 공격속도입니다.

    위의 값을 직접 만들어보세요

     

    컨트롤+D키로 프로젝트의 파일을 복제할 수 있습니다.

    총7개를 복제한뒤 파일이름을 Item_name과 같이 맞춰주세요 이후에 이미지를 불러올때 사용할 것입니다.

     

    저희는 총 7개의 아이템을 만들어볼겁니다.

     

    아무 이미지나 총7개를 만들어주세요 직접 그리신파일도 상관없습니다

    .저는 롤의 롱소드를 가지고왔습니다.

     

    그후 유니티 에셋 리소스 폴더(전에만든 프리팹이있는곳)에 드래그해서 넣어주시면 이미지파일이 옮겨집니다.

    이이미지 파일은 바로사용할수 없고 스프라이트로 바꿔주어야합니다.

    이렇게 스프라이트로 변경해주면 UI에서도 사용할 수 있는 이미지가 됩니다.

    이 이미지 또한 이름을 Item_name와 똑같이맞추어주세요.

    자 이제 사전준비가 끝낫으니 

    코드를 짤 시간입니다.

    UI->shop에 이 스크립트를 작성합니다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    
    public class shop : MonoBehaviour
    {   public Text got_gold;
        public Text sel_item_price;
        public Image sel_item_image;
        [SerializeField]
        private List<item_data> item_data_list;
        public GameObject shopPanel; // 아이템목록을 보여주는 패널
        void Start()//씬이 시작될떄 호출
        {   
            
    
    
            int j=0;//가로줄
            int k=0;//세로줄
            int galo=5;//가로줄
            //아이템 리스트 만큼 객체생성
            for(int i = 0; 2*k < item_data_list.Count; i++)//아이템갯수만큼 생성  //item_data_list.Count=3임 (현재) 아이템 카운트가 만약 10개라면 그리고 가로줄에 2개 한다면  1 2 1 2 1 2 1 2 총 5줄
            {   
                for(j=0;j<galo;j++)//가로줄
                {
                GameObject item = Instantiate(Resources.Load<GameObject>("item"));
                item.GetComponent<item_data_update>().I_D = item_data_list[j+k*galo];
                item.transform.SetParent(shopPanel.transform);
                item.transform.localScale = new Vector3(0.4f,0.4f,0.4f);
                item.transform.localPosition = new Vector3(-130+60*j, -60 * k, 0);//간격 생성
                item.GetComponent<item_data_update>().item_data = item_data_list[j+k*galo];
                }
                k++;
            }
            this.gameObject.SetActive(false);//씬이호출될때 표시되지않게함
        }
    
    }

    이렇게 지정해줍니다.

    그후 프리팹을 하나 만들어줍시다.

    버튼하나를 만들어 프리팹화 시킨후 이 프리팹에 스크립트를 하나 추가하겠습니다.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class item_data_update : MonoBehaviour
    {
        [SerializeField]
        public GameObject shop;//상위부모 오브젝트
        public item_data I_D;
        public Button button;
        public Text text;
        private float x;
        private float y;
        private float z;
    
    
        public item_data item_data { set { I_D = value; } }
        void Start(){
            shop=this.transform.parent.parent.parent.parent.gameObject;
            this.GetComponent<Image>().sprite = Resources.Load<Sprite>(I_D.Item_name);
            this.GetComponent<Button>().onClick.AddListener(printitem_info);
            this.GetComponentInChildren<Text>().text = I_D.Item_name;
            x=this.gameObject.transform.position.x;
            y=this.gameObject.transform.position.y;
            z=this.gameObject.transform.position.z;
            this.transform.position= new Vector3(x,y-30,z);//아이템의 위치가 콘텐츠의 천장에 닿은부분을 뺴주기위해 넣음
        }
        public void printitem_info(){
        shop.GetComponent<shop>().sel_item_image.sprite = Resources.Load<Sprite>(I_D.Item_name);//아이템 이미지를 출력
        shop.GetComponent<shop>().sel_item_price.text="price:"+I_D.Price.ToString();//아이템의 가격을 출력
        }
    }

    자이렇게 하시면 게임을 시작하면 아래그림처럼 아이템의 버튼이 생성됩니다.

    아이템을 만들고 띄워줫을떄의 모습입니다.

     

    이제 상점의 모습을 좀더 자유롭게 꾸며줍니다.

    저는 투명하게 만들어보았습니다.

    이것을 만들어봅시다.

    비어있는 이미지하나에 버튼을 6개 만들어줍니다 

    그후 image에 

     player_item_icon_set이라는 스크립트를 추가해줍시다.

    최종적으로는 판매와 플레이어 아이템창에 UI까지 모두 변경해주는 코드를 작성하게됩니다. stats와 player_item_icon_set을 추가작성해줍시다

    그전에 GameManger 라는 빈 오브젝트를 하나만들고 Player_set 스크립트와 Item_set스크립트를 만들어주세요

    이후 스크립트를 넣어주면 리스트를 생성할 수 있게됩니다.

    Player_set 코드

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class player_set : MonoBehaviour
    {
        public GameObject player;
        
        public Camera cam;
        public GameObject shop;
    
    }

    Item_set 코드

    using System.Collections.Generic;
    using UnityEngine;
    public class item_set : MonoBehaviour
    {
     public List<item_data> item_data_list;
    }

    누르면 없음이 나오는데 이를 하나하나 지정해주세요!

    player_item_icon_set 코드

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    public class player_item_icon_set : MonoBehaviour //아이템칸에 아이템 이미지만 띄워주는 코드이다.
    {
        public GameObject gamemanger;
        public GameObject player;
        public List<Button> item_button;
        private List<item_data> item_data_list;
        void Start()
        {
            item_data_list = gamemanger.GetComponent<item_set>().item_data_list;//item_set에서 item_data_list를 찾아서 item_data_list에 저장
            
        }
        void Update()
        {
            if(item_button[0].GetComponent<Image>().sprite.name=="UISP"){ //아이템칸 1번에 아이템이 없으면 UISP = 기본 이미지 
            if(player.GetComponent<Stats>().item_equip[0]!=0){ //아이템칸 1번에 아이템이 없으면
                item_button[0].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[0]-1].Item_name);
                //아이템1번칸의 IDX값을 토대로 item의 이름을 통해 스프라이트를 설정해줍니다.
            }}
            else{//아이템칸 1번에 아이템이 있으면
                if(item_button[1].GetComponent<Image>().sprite.name=="UISP"){//다음칸도 똑같이 실행
                if(player.GetComponent<Stats>().item_equip[1]!=0){
                    item_button[1].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[1]-1].Item_name);
                    }}else{
                        if(item_button[2].GetComponent<Image>().sprite.name=="UISP"){
                        if(player.GetComponent<Stats>().item_equip[2]!=0){
                        item_button[2].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[2]-1].Item_name);
                        }}else{
                            if(item_button[3].GetComponent<Image>().sprite.name=="UISP"){
                            if(player.GetComponent<Stats>().item_equip[3]!=0){
                            item_button[3].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[3]-1].Item_name);
                            }}else{
                                if(item_button[4].GetComponent<Image>().sprite.name=="UISP"){
                                if(player.GetComponent<Stats>().item_equip[4]!=0){
                                item_button[4].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[4]-1].Item_name);
                                }}else{
                                    if(item_button[5].GetComponent<Image>().sprite.name=="UISP"){
                                    if(player.GetComponent<Stats>().item_equip[5]!=0){
                                    item_button[5].GetComponent<Image>().sprite = Resources.Load<Sprite>(item_data_list[player.GetComponent<Stats>().item_equip[5]-1].Item_name);
                                    }}
                                    }
                                }
                            }
                        }
                } 
        }
        public void sell_item_icon(int x){
                item_button[x].GetComponent<Image>().sprite = Resources.Load<Sprite>("UISP");
        }
    }

    stats코드

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    using UnityEngine.UI;
    
    public class Stats : MonoBehaviour
    {   
        public GameObject gamemanger;
        #region 체력관련 변수
        public float hp;public float maxHp;
        public float mp;public float maxMp;
        #endregion
        #region 공격관련 변수
        public float atk;public float atk_speed;public float atk_range;
        #endregion
        #region 방어관련 변수
        public float def;
        #endregion
        #region 이동관련 변수
        public float spd;
        #endregion
        #region 팀관련 변수
        public float team;
        #endregion
        #region 골드관련 변수
        public float gold;public float kill_gold;
        #endregion
        #region 오브젝트관련 변수
        public NavMeshAgent agent;
        #endregion
    
        #region 아이템관련 변수
        public int[] item_equip;
        #endregion
    
        public Image item_icon;
        
        void Start()
        {   gamemanger= GameObject.Find("GameManger");
            agent=this.gameObject.GetComponent<NavMeshAgent>();
            hp = maxHp;
            mp = maxMp;
            item_equip = new int[6];//6개의 아이템장착창을 만듬
    
        }
        public void TakeDamage(float damage)
        {
            hp -= damage;//hp값을 입력받은 값으로 빼줌
        }
        public void get_gold(float got_gold)//처치한 상대의 kill_gold값을 받아서 골드를 얻음
        {
            gold += got_gold;
        }
        public void get_item(int item_index){
            if(item_equip[0]==0){//아이템장착창 1번에 아이템이 비어있으면
                item_equip[0] = item_index;
            }
            else{//비어있지 않으면
                if(item_equip[1]==0){//아이템장착창 2번에 아이템이있는지 확인
                item_equip[1] = item_index;
                }
                else{
                    if(item_equip[2]==0){
                    item_equip[2] = item_index;
                    }
                    else{//비어있지 않으면
                        if(item_equip[3]==0){
                        item_equip[3] = item_index;
                        }
                        else{//비어있지 않으면
                            if(item_equip[4]==0){
                            item_equip[4] = item_index;
                            }
                            else{//비어있지 않으면
                                if(item_equip[5]==0){
                                item_equip[5] = item_index;
                                }else{
                                    Debug.Log("아이템창이 가득찼습니다.");
                                }
                            }
                        }
                    }
                }
            }
        }
        public void sell_item_player(int idx){
            if(item_equip[0]==idx){
                item_equip[0]=0; 
                item_icon.GetComponent<player_item_icon_set>().sell_item_icon(0);
            }
            else{
                if(item_equip[1]==idx){
                    item_equip[1]=0;
                    item_icon.GetComponent<player_item_icon_set>().sell_item_icon(1);
                }
                else{
                    if(item_equip[2]==idx){
                        item_equip[2]=0;
                        item_icon.GetComponent<player_item_icon_set>().sell_item_icon(2);
                    }
                    else{
                        if(item_equip[3]==idx){
                            item_equip[3]=0;
                            item_icon.GetComponent<player_item_icon_set>().sell_item_icon(3);
                        }
                        else{
                            if(item_equip[4]==idx){
                                item_equip[4]=0;
                                item_icon.GetComponent<player_item_icon_set>().sell_item_icon(4);
                            }
                            else{
                                if(item_equip[5]==idx){
                                    item_equip[5]=0;
                                    item_icon.GetComponent<player_item_icon_set>().sell_item_icon(5);
                                }
                            }
                        }
                    }
                }
            }
        }
        void Update()
        {   
            //속도동기화
            agent.speed = spd;//최고속력
            agent.acceleration=spd; //가속도
            if (hp <= 0) //체력이 0이하면 죽음
            {
                Destroy(this.gameObject);
            }
            gold=gold+Time.deltaTime*10;
            gamemanger.GetComponent<player_set>().shop.GetComponent<shop>().got_gold.text="소지금 : "+gold;
    
        }
    }

    shop 코드

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    
    public class shop : MonoBehaviour
    {   public GameObject gamemanger;
        public GameObject player;
        public Text got_gold;
        public float gold;
        public float sel_price;
        public Text sel_item_price;
        public Image sel_item_image;
        public GameObject seleceted_item;
        private List<item_data> item_data_list;
        public GameObject shopPanel; // 아이템목록을 보여주는 패널
        public Button buy_btn;
        public Button sell_btn;
        public Image item_icon; 
        void Start()//씬이 시작될떄 호출
        {   
            buy_btn.GetComponent<Button>().onClick.AddListener(buy_item);
            sell_btn.GetComponent<Button>().onClick.AddListener(sell_item);
            item_data_list=gamemanger.GetComponent<item_set>().item_data_list;
            int j=0;//가로줄
            int k=0;//세로줄
            int galo=5;//가로줄
            //아이템 리스트 만큼 객체생성
            for(int i = 0; 2*k < item_data_list.Count; i++)//아이템갯수만큼 생성  //item_data_list.Count=3임 (현재) 아이템 카운트가 만약 10개라면 그리고 가로줄에 2개 한다면  1 2 1 2 1 2 1 2 총 5줄
            {   
                for(j=0;j<galo;j++)//가로줄
                {
                GameObject item = Instantiate(Resources.Load<GameObject>("item"));
                item.GetComponent<item_data_update>().I_D = item_data_list[j+k*galo];
                item.transform.SetParent(shopPanel.transform);
                item.transform.localScale = new Vector3(0.4f,0.4f,0.4f);
                item.transform.localPosition = new Vector3(-130+60*j, -60 * k, 0);//간격 생성
                item.GetComponent<item_data_update>().item_data = item_data_list[j+k*galo];
                }
                k++;
            }
            this.gameObject.SetActive(false);//씬이호출될때 표시되지않게함
        }
            public void buy_item(){
                sel_price= seleceted_item.GetComponent<item_data_update>().I_D.Price;
            if(sel_price<gold){
                    player.GetComponent<Stats>().gold=gold-sel_price;
                    player.GetComponent<Stats>().get_item(seleceted_item.GetComponent<item_data_update>().I_D.IDX);
            }
            else{
                Debug.Log("골드가 부족합니다.");
            }
            }
            public void sell_item(){
              //find item in player's inventory
                player.GetComponent<Stats>().sell_item_player(seleceted_item.GetComponent<item_data_update>().I_D.IDX);
                player.GetComponent<Stats>().gold+=sel_price/80;
    
            }
        void Update(){ 
            gold=player.GetComponent<Stats>().gold;
        }       
    }

     

     

     

     

    구매와 판매가 가능한모습을 볼 수 있습니다.

    댓글

Designed by Tistory.