using GUPS.AntiCheat.Protected; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; public class Game_Lucky : MonoBehaviour { public LuckyGameCupCounter m_LuckyGameCupCounter; public Game_Lucky_Result m_Game_Lucky_Result; public Image i_girl, i_girlsd, i_refillbtn; public GameObject[] gos_boobs; public TextMeshProUGUI[] texts; // 0 시간, 1 획득 재화, 2 컵안 오브젝트 갯수, 3 리필 횟수, 4 리필 갯수 public GameObject go_dropobj; // 떨어질 공 prefab public Transform tf_cup; // 컵 (움직이고 회전하는 부분) public Transform tf_cupin; // 컵 안 (공들이 들어가는 위치 부모) public Transform tf_fallobjs; // 컵 안에서 밖으로 떨어지는 공들의 부모 public Transform tf_refillobjs; // 리필 공들 List list_dropobj = new List(); public List list_randomblock; // 회전 관련 변수 private bool isRotating = false; private float targetZ = -150f; private float originalZ = 0f; private float rotateSpeed = 150f; // 초당 몇 도 회전할지 float Cup_minX, Cup_maxX; [SerializeField] private float cupMargin = 128.5f; // 간격 bool bRotCup = false, updateTime = false, isRefill = false; ProtectedFloat m_Time; ProtectedInt32 _get; public int m_Amount { get { return _get; } set { _get = value; _get.Obfuscate(); } } ProtectedInt32 _bb; public int m_BubbleAmount { get { return _bb; } set { _bb = value; _bb.Obfuscate(); } } ProtectedInt32 TotalBubbleAmount = 50, m_RefillCount = 0; int CupInAmount = 0; // 컵 안에 있는 오브젝트 갯수 AsyncOperationHandle m_Handle, m_HandleSD; int curGirl; private void Awake() { // 화면 좌표 (0,0) → 월드 좌표 Vector3 leftWorld = Camera.main.ScreenToWorldPoint( new Vector3(0 + cupMargin, Screen.height / 2f, Camera.main.nearClipPlane)); // 화면 좌표 (Screen.width,0) → 월드 좌표 Vector3 rightWorld = Camera.main.ScreenToWorldPoint( new Vector3(Screen.width - cupMargin, Screen.height / 2f, Camera.main.nearClipPlane)); Cup_minX = leftWorld.x; Cup_maxX = rightWorld.x; var refill = table_GlobalValue.Ins.Get_Int("LuckyGame_RefillAmount") << 1; for (int i = 0; i < refill; i++) { var obj = DSUtil.Get_Clone(go_dropobj, tf_refillobjs); obj.gameObject.SetActive(false); } texts[4].text = $"x{table_GlobalValue.Ins.Get_Int("LuckyGame_RefillAmount")}"; } public void Set() { gameObject.SetActive(true); SoundInfo.Ins.Play_BGM(eBGM.b007_LuckyGame); m_LuckyGameCupCounter.Set(count => { texts[2].text = count.ToString(); }); m_Game_Lucky_Result.gameObject.SetActive(false); ADInfo.Ins.Set_Banner(false); isRefill = bRotCup = false; curGirl = Random.Range(1, 9); i_girl.enabled = false; AddrResourceMgr.Ins.LoadObject($"Girl_LuckyGame/{curGirl}.png", handle => { m_Handle = handle; i_girl.enabled = true; i_girl.sprite = handle.Result; }); i_girlsd.enabled = false; AddrResourceMgr.Ins.LoadObject($"Girl_Game/{curGirl}sd.png", handle => { m_HandleSD = handle; i_girlsd.enabled = true; i_girlsd.sprite = handle.Result; }); m_RefillCount = SaveMgr.Ins.Get_LuckyGameRefill(); m_RefillCount.Obfuscate(); DSUtil.InActivateGameObjects(gos_boobs, curGirl - 1); // tf_cup 초기화 tf_cup.localPosition = Vector3.zero; tf_cup.rotation = Quaternion.Euler(0, 0, 0); originalZ = tf_cup.eulerAngles.z; // list_dropobj.Count 가 0 이면 50개 생성해서 tf_cupin 안에 넣기 if (list_dropobj.Count == 0) { TotalBubbleAmount.Obfuscate(); for (int i = 0; i < TotalBubbleAmount; i++) { GameObject obj = Instantiate(go_dropobj, tf_cupin); obj.transform.localPosition = Get_CupInLocalPos(); list_dropobj.Add(obj); } } if (list_dropobj.Count > TotalBubbleAmount) { var moveCount = list_dropobj.Count - TotalBubbleAmount; for (int i = 0; i < moveCount; i++) { list_dropobj[0].transform.SetParent(tf_refillobjs); list_dropobj[0].gameObject.SetActive(false); list_dropobj.RemoveAt(0); } } StartCoroutine(Co_Block()); Set_Ball(); Init_game(); Set_Texts(); } void Set_Ball() { CupInAmount = TotalBubbleAmount; texts[2].text = CupInAmount.ToString(); list_dropobj.ForEach(f => f.GetComponent().Init(Get_CupInLocalPos(), tf_cupin, tf_fallobjs)); // 컵 안에서 시작 //list_dropobj.ForEach(f => f.GetComponent().gravityScale = Random.Range(0.01f, 0.3f)); } void Init_game() { updateTime = true; m_Time = 30f; m_Time.Obfuscate(); m_Amount = 0; m_BubbleAmount = 0; } void Set_Texts() { texts[0].text = m_Time.Value.ToString("N0"); texts[1].text = m_Amount.ToString(); i_refillbtn.sprite = UIAtlasMgr.Ins.Get_Sprite(m_RefillCount > 0 ? "refill btn_lucky mini game" : "refill btn lock_lucky mini game"); texts[3].text = m_RefillCount.ToString(); } public void Add_Amount(int amout) { m_Amount += amout; Set_Texts(); ++m_BubbleAmount; if (m_BubbleAmount >= list_dropobj.Count) GameOver(); } void GameOver() { StartCoroutine(Co_GameOver()); } IEnumerator Co_GameOver() { updateTime = false; list_dropobj.ForEach(f => f.GetComponent().StopObj()); yield return new WaitForSecondsRealtime(0.5f); m_Game_Lucky_Result.Set(m_Amount); StopAllCoroutines(); } public void ReleaseImage() { AddrResourceMgr.Ins.Relese(m_Handle); i_girl.sprite = null; AddrResourceMgr.Ins.Relese(m_HandleSD); i_girlsd.sprite = null; gameObject.SetActive(false); } Vector3 Get_CupInLocalPos(float addy = 0f) { return new Vector3(Random.Range(-50f, 50f), Random.Range(-50f, 50f) + addy, 0f); } public void OnMyDrag() { if (!bRotCup) { Vector3 mousePos = Input.mousePosition; Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, Camera.main.nearClipPlane)); // 컵의 x 위치를 화면 경계 안으로 Clamp Vector3 cupPos = tf_cup.position; cupPos.x = Mathf.Clamp(worldPos.x, Cup_minX, Cup_maxX); tf_cup.position = cupPos; } } public void OnClick_Screen() { if (bRotCup) { return; } bRotCup = true; // 마우스/터치 입력 위치 → 월드 좌표 변환 Vector3 mousePos = Input.mousePosition; Vector3 worldPos = Camera.main.ScreenToWorldPoint(mousePos); // tf_cup을 터치한 위치의 x 값만 받아서 거기에 위치시킴 Vector3 cupPos = tf_cup.position; cupPos.x = Mathf.Clamp(worldPos.x, Cup_minX, Cup_maxX); tf_cup.position = cupPos; // 회전 시작 (목표: -150도) targetZ = -150f; isRotating = true; SoundInfo.Ins.Play_OneShot((eSound)Random.Range(14, 16)); } public void OnPointerDown() { isRotating = true; } public void OnPointerUp() { isRotating = false; } private void Update() { if (isRefill) return; float currentZ = tf_cup.eulerAngles.z; if (currentZ > 180f) currentZ -= 360f; // -180~180 범위 보정 if (isRotating) { // 목표 각도로 이동 float newZ = Mathf.MoveTowards(currentZ, targetZ, rotateSpeed * Time.deltaTime); tf_cup.rotation = Quaternion.Euler(0, 0, newZ); } else { // 손을 뗐을 때 원래 각도로 복귀 float newZ = Mathf.MoveTowards(currentZ, originalZ, rotateSpeed * Time.deltaTime); tf_cup.rotation = Quaternion.Euler(0, 0, newZ); } if (updateTime && m_Time > 0f) { m_Time -= Time.deltaTime; Set_Texts(); if (m_Time <= 0f) GameOver(); } } IEnumerator Co_Block() { list_randomblock.ForEach(f => f.Init()); LuckyRandomBlock PreBlock = null; while (true) { for (int i = 0; i < list_randomblock.Count; i++) { if (!list_randomblock[i].IsMoving() && (PreBlock == null || PreBlock.IsCrossTwoThirds())) { PreBlock = list_randomblock[i]; PreBlock.Move(); } } yield return null; } } public void OnClick_Refill() { if (m_RefillCount > 0) { --m_RefillCount; m_RefillCount.Obfuscate(); Set_Texts(); StartCoroutine(Co_Refill()); } } IEnumerator Co_Refill() { isRefill = true; tf_cup.rotation = Quaternion.Euler(0, 0, 0); for (int i = 0; i < table_GlobalValue.Ins.Get_Int("LuckyGame_RefillAmount"); i++) { for (int j = 0; j < tf_refillobjs.childCount; j++) { var child = tf_refillobjs.GetChild(j); if (!child.gameObject.activeInHierarchy) { list_dropobj.Add(child.gameObject); child.GetComponent().Init(Get_CupInLocalPos(100f), tf_cupin, tf_fallobjs); yield return new WaitForSeconds(0.5f); break; } } } isRefill = false; } }