Button을 SetActive하는 법을 잘 몰랐는데 블로그를 검색하다가 잘 알게되었다.
GameMain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//모든 게임씬 애들 관리
public class GameMain : MonoBehaviour
{
private BasketController basketController;
[SerializeField]
private List<GameObject> basketPrefabs;
private ItemGenerator itemGenerator;
private GameObject gameDirectorGo;
// Start is called before the first frame update
void Start()
{
this.gameDirectorGo = GameObject.Find("GameDirector");
GameDirector gameDirector = GetComponent<GameDirector>();
this.CreateBasket();
}
// Update is called once per frame
void Update()
{
}
private void CreateBasket()
{
GameObject prefab = this.basketPrefabs[InfoManager.instance.selectedBasketType];
GameObject basketGo = Instantiate(prefab);
basketGo.transform.position = Vector3.zero;
this.basketController = basketGo.GetComponent<BasketController>();
}
}
ItemGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemGenerator : MonoBehaviour
{
private float elasedTime; //경과 시간
private float spawnTime = 1f; // 1초에 한번씩 스폰
public GameObject applePrefab;
public GameObject bombPrefab;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//시간 재기
//변수에 Time.deltaTime더해라
this.elasedTime += Time.deltaTime;
//1초가 지났다면
if(this.elasedTime >= this.spawnTime)
{
//아이템을 생성
this.CreateItem();
//초기화
this.elasedTime = 0;
}
}
private void CreateItem()
{
//사과 또는 폭탄
int rand = Random.Range(1, 11); // 1 ~ 10
GameObject itemGo = null;
if (rand > 2) //3, 4, 5, 6, 7, 8, 9, 10
{
//사과
itemGo = Instantiate<GameObject>(this.applePrefab);
}
else //1, 2
{
//폭탄
itemGo = Instantiate<GameObject>(this.bombPrefab);
}
//위치 설정
//x: -1, 1 [좌 , 우]
//z: -1, 1 [위 아래]
int x = Random.Range(-1, 2); // -1, 0, 1
int z = Random.Range(-1, 2); // -1, 0, 2
//위치를 설정
itemGo.transform.position = new Vector3(x, 3.5f, z);
}
}
InfoManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//Monobehavior 상속받지 않고 InfoManager에 남겨둔다.
public class InfoManager
{
public static readonly InfoManager instance = new InfoManager();
public int selectedBasketType = -1; // 0 : Yellow, 1 : Red, 2 : Green
private InfoManager()
{
}
}
GameDirector
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameDirector : MonoBehaviour
{
[SerializeField]
private Text txtTime;
[SerializeField]
private Text txtScore;
private float time = 60.0f;
private int score = 0;
// Start is called before the first frame update
void Start()
{
//노란색
if (InfoManager.instance.selectedBasketType == 0)
{
time += 10;
}
GameObject txtTimeGo = GameObject.Find("txtTime");
this.txtTime = txtTimeGo.GetComponent<Text>();
GameObject txtScoreGo = GameObject.Find("txtScore");
this.txtScore = txtScoreGo.GetComponent<Text>();
this.UpdateScoreUI();
}
// Update is called once per frame
void Update()
{
this.time -= Time.deltaTime; // 매프레임마다 감소된 시간을 표시
this.txtTime.text = this.time.ToString("F1");
if(this.time == 0)
{
}
}
public void UpdateScoreUI()
{
this.txtScore.text = string.Format("{0} Point", score);
}
public void IncreaseScore(int score)
{
this.score += score;
}
public void DecreaseScore(int score)
{
this.score -= score;
}
}
LobbyMain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class LobbyMain : MonoBehaviour
{
[SerializeField]
private List<GameObject> baskets;
[SerializeField]
private Button btnGameStart;
// Start is called before the first frame update
void Start()
{
this.btnGameStart.onClick.AddListener(() => {
this.SceneChange();
});
}
// 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, 2f);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 1000f))
{
Debug.Log(hit.collider.gameObject.name);
GameObject foundBasketGo = this.baskets.Find(x => x == hit.collider.gameObject);
int selectedBasketType = this.baskets.IndexOf(foundBasketGo);
Debug.LogFormat("<color=yellow>selectedBasketType: {0}</color>", selectedBasketType);
InfoManager.instance.selectedBasketType = selectedBasketType;
foreach(var go in this.baskets)
{
if(go != foundBasketGo)
{
//선택 되지 않은 것들
go.SetActive(false); //비활성화
this.btnGameStart.gameObject.SetActive(true);
}
}
}
}
}
public void SceneChange()
{
SceneManager.LoadScene("AppleCatchScene");
}
}
BasketController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasketController : MonoBehaviour
{
private AudioSource audioSource;
[SerializeField]
private AudioClip bombSfx;
[SerializeField]
private AudioClip appleSfx;
[SerializeField]
private GameDirector gameDirector;
// Start is called before the first frame update
void Start()
{
GameObject gameDirectorGo = GameObject.Find("GameDirector");
this.gameDirector = gameDirectorGo.GetComponent<GameDirector>();
this.audioSource = this.GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
if(Input.GetMouseButtonDown(0))
{
//화면상의 좌표 Ray를 만들자
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//ray를 눈으로 확인
Debug.DrawRay(ray.origin, ray.direction * 100f, Color.green, 2f);
//ray와 collider의 충돌을 검사하는 메서드
RaycastHit hitData;
//충돌되었다면 true , 아니면 false
if(Physics.Raycast(ray, out hitData, 100f))
{
Debug.LogFormat("hit.point: {0}", hitData.point);
//바구니의 위치를 충돌한 지점으로 변경
//this.transform.position = hitData.point;
//x좌표와 z좌표를 반올림
float x = Mathf.RoundToInt(hitData.point.x);
float z = Mathf.RoundToInt(hitData.point.z);
//새로운 좌표를 만든 후 이동
this.transform.position = new Vector3(x, 0, z);
}
}
}
private void OnTriggerEnter(Collider other)
{
Debug.Log(other.tag);
if(other.tag == "apple")
{
//점수를 추가
Debug.Log("득점");
this.audioSource.PlayOneShot(this.appleSfx);
//빨간색
if(InfoManager.instance.selectedBasketType == 1)
{
this.gameDirector.IncreaseScore(110);
}
else
{
this.gameDirector.IncreaseScore(100);
}
this.gameDirector.UpdateScoreUI();
Destroy(other.gameObject); //사과 또는 폭탄을 제거
}
else if(other.tag == "bomb")
{
Debug.Log("감점");
this.audioSource.PlayOneShot(this.bombSfx);
if(InfoManager.instance.selectedBasketType == 2)
{
this.gameDirector.DecreaseScore(45);
}
else
{
this.gameDirector.DecreaseScore(50);
}
this.gameDirector.UpdateScoreUI();
Destroy(other.gameObject); //사과 또는 폭탄을 제거
}
}
}
ItemController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemController : MonoBehaviour
{
[SerializeField]
private float moveSpeed = 1f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//리지드바디가 없는 오브젝트의 이동
//this.transform.Translate(방향 * 속도 * 시간);
//기본이 로컬좌표로 이동
this.transform.Translate(Vector3.down * this.moveSpeed * Time.deltaTime);
if(this.transform.position.y <= 0)
{
Destroy(this.gameObject); // Destroy(this); 완전히 다른 의미. Component가 제거됌
}
}
}
Basket을 Prefab으로하니까 GameDirector스크립트가 들어가질 못했다. 그래서 동적으로 스크립트를 BasketController에다가 Find시켜줘서 GameDirector를 찾을 수 있게 만들 수 있다.
'유니티 기초' 카테고리의 다른 글
로비씬, 사과, 폭탄 - 추가사항 빼고 기본 [완성] (0) | 2023.08.07 |
---|---|
로비씬, 사과, 폭탄 - [게임종료구현, 종료 후 스코어 미구현] (0) | 2023.08.07 |
챕터 8 AppleCatch (0) | 2023.08.07 |
주말과제 (1) | 2023.08.06 |
3D 유니티 LookAt, 유니티 짱, Raycast, 클릭한 위치로 이동 (0) | 2023.08.04 |