'Project > Skill Steal Girl' 카테고리의 다른 글
[SSG] 대화, 룰렛 수정 (0) | 2024.07.08 |
---|---|
[SSG] 룰렛을 돌려 나온 아이템 획득하기 (0) | 2024.07.03 |
[SSG] 대화창에 배경적용 시키기 (0) | 2024.06.30 |
[SSG] Dialog Canavs Btn Test (0) | 2024.06.23 |
[SSG] Dialog RnD (0) | 2024.06.15 |
[SSG] 대화, 룰렛 수정 (0) | 2024.07.08 |
---|---|
[SSG] 룰렛을 돌려 나온 아이템 획득하기 (0) | 2024.07.03 |
[SSG] 대화창에 배경적용 시키기 (0) | 2024.06.30 |
[SSG] Dialog Canavs Btn Test (0) | 2024.06.23 |
[SSG] Dialog RnD (0) | 2024.06.15 |
대화하는 인물과 대화를 케이스로 분류해놨는데
그에 맞춰 배경까지 연결
배경 리소스를 더 구하고
캐릭터가 각각 말할 때 DOTween을 이용하여 알파 값 처리할 필요가 있음
+ 대화하는 인물 연결 및 커멘터리(해설자 시점) 처리 필요
[SSG] 룰렛을 돌려 나온 아이템 획득하기 (0) | 2024.07.03 |
---|---|
[SSG] Dialog 캐릭터 등장 DOTween, 배경, 스테이지 전환 알림문구 적용 (0) | 2024.07.02 |
[SSG] Dialog Canavs Btn Test (0) | 2024.06.23 |
[SSG] Dialog RnD (0) | 2024.06.15 |
[SSG] 로비에서 변경한 소리를 다른 씬에도 저장시켜 적용하기 (0) | 2024.06.10 |
현재 룰렛은 8등분이 되어 있고
각각 360 / 8인 45도로 구성되어 있다.
그러므로 이 가운데 값은 22.5도이다.
룰렛을 개발자가 편하게 컨트롤 할 수 있도록 만들었다.
360도 * 횟수를 적용하여 여러번 돌아가고 거기에 지정한 extraAngle을 더해주면된다.
회전횟수를 선택할 수 있고 스탭을 조절함으로서 속도를 조절할 수 있다.
아래는 개발자들은 이미 사전에 클릭을 하면 알 수 있게 항목을 출력하도록 변경
나오는 것은 랜덤으로 변경
즉, 랜덤에 따라 특정 각도가 결정되고 그에 따라 개발자들은 출력결과를 미리 알수 있고,
유저들은 원하는 각도를 보게 되는 것이다.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.UI;
public class RouletteTest : MonoBehaviour
{
[SerializeField] private Button btnGetIem;
[SerializeField] private Roulette _roulette;
//[SerializeField] private float targetAngle = -22.5f; //클로버를 겨냥
private string[] itemNames = { "폭탄" , "기력회복", "폭탄", "체력회복", "폭탄", "금화획득","폭탄", "네잎클로버"};
private float[] targetAngles =
{
22.5f, 67.5f, 112.5f, 157.5f, 202.5f, 247.5f, 292.5f, 337.5f
};
void Start()
{
btnGetIem.onClick.AddListener(() =>
{
int idx = UnityEngine.Random.Range(0, 8); // 0 ~ 7
Debug.Log($"<color=yellow>{itemNames[idx]}</color>");
_roulette.StartRotate(targetAngles[idx]);
});
}
}
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.UI;
public class RouletteTest : MonoBehaviour
{
[SerializeField] private Button btnGetIem;
[SerializeField] private Roulette _roulette;
//[SerializeField] private float targetAngle = -22.5f; //클로버를 겨냥
private string[] itemNames = { "폭탄" , "기력회복", "폭탄", "체력회복", "폭탄", "금화획득","폭탄", "네잎클로버"};
private float[] targetAngles =
{
22.5f, 67.5f, 112.5f, 157.5f, 202.5f, 247.5f, 292.5f, 337.5f
};
void Start()
{
btnGetIem.onClick.AddListener(() =>
{
int idx = UnityEngine.Random.Range(0, 8); // 0 ~ 7
Debug.Log($"<color=yellow>{itemNames[idx]}</color>");
_roulette.StartRotate(targetAngles[idx]);
});
}
}
[Tip] 맥 SVN 설치 - snailSVN (0) | 2024.07.21 |
---|---|
[Tip] 텍스트 코루틴 애니메이션 (0) | 2024.07.16 |
[Tip] Mathf.DeltaAngle (0) | 2024.06.29 |
[Tip] Object.FindObjectOfType (0) | 2024.06.11 |
[Tip] RenderSettings (0) | 2024.06.05 |
https://docs.unity3d.com/ScriptReference/Mathf.DeltaAngle.html
Unity - Scripting API: Mathf.DeltaAngle
Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close
docs.unity3d.com
[Tip] 텍스트 코루틴 애니메이션 (0) | 2024.07.16 |
---|---|
[Tip]룰렛 원하는 곳에 위치 + 텍스트 출력 (0) | 2024.06.29 |
[Tip] Object.FindObjectOfType (0) | 2024.06.11 |
[Tip] RenderSettings (0) | 2024.06.05 |
[팁] Slider.onValueChanged (0) | 2024.06.05 |
현재 테스트 광고 단위를 사용하는데
배너의 크기를 조절하던 중 오류가 났다.
분명 커스터마이징이 가능한 줄 알았는데 애드몹에서 지정된 사이즈로만
변경 할 수 있던 것이다.
본 프로젝트에는 크기에 맞춤을 적용하였다.
https://developers.google.com/admob/unity/banner?hl=ko
배너 광고 | Unity | Google for Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 배너 광고 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 배너 보기는 화면 안의 한 지점을 차지하는
developers.google.com
using UnityEngine;
using GoogleMobileAds.Api;
using System;
using System.Drawing;
public class BannerManager : MonoBehaviour
{
public static BannerManager instance;
public static BannerManager Instance
{
get
{
// Singleton 패턴을 이용하여 단일 인스턴스 반환
if (instance == null)
{
instance = FindObjectOfType<BannerManager>();
if (instance == null)
{
GameObject adMobManagerGO = new GameObject();
instance = adMobManagerGO.AddComponent<BannerManager>();
adMobManagerGO.name = "AdMobManager";
DontDestroyOnLoad(adMobManagerGO);
}
}
return instance;
}
}
public string _adUnitId;
// 광고 뷰 객체
BannerView _bannerView;
public void Awake()
{
// 싱글톤 인스턴스 설정
if (instance == null)
{
instance = this as BannerManager;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
public void Start()
{
//// Google Mobile Ads SDK 초기화
MobileAds.Initialize((InitializationStatus initStatus) =>
{
// SDK 초기화 콜백
Debug.Log("Google Mobile Ads SDK initialized.");
// 광고 뷰 생성
//_bannerView = new BannerView(_adUnitId, AdSize.Banner, AdPosition.Bottom);
//AdSize adSize = new AdSize(350, 50);
//_bannerView = new BannerView(_adUnitId, adSize, AdPosition.Bottom);
CreateBannerView();
ListenToAdEvents();
});
//CreateBannerView();
#if UNITY_ANDROID
_adUnitId = "ca-app-pub-3940256099942544/6300978111"; // 안드로이드 테스트 광고 단위 ID
#elif UNITY_IPHONE
_adUnitId = "ca-app-pub-3940256099942544/2934735716"; // iOS 테스트 광고 단위 ID
#else
_adUnitId = "unused"; // 기타 플랫폼 또는 테스트에 사용되지 않는 경우
#endif
}
public void CreateBannerView()
{
Debug.Log("Creating banner view");
// 기존 배너 뷰가 있으면 제거
//if (_bannerView != null)
//{
// _bannerView.Destroy();
//}
// Use the AdSize argument to set a custom size for the ad.
AdSize adSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(AdSize.FullWidth);
//_bannerView = new BannerView(_adUnitId, adSize, AdPosition.Bottom);
_bannerView = new BannerView(_adUnitId, adSize, AdPosition.Bottom);
ListenToAdEvents();
}/// <summary>
/// Creates the banner view and loads a banner ad.
/// </summary>
public void LoadAd()
{
// create an instance of a banner view first.
if (_bannerView == null)
{
CreateBannerView();
}
// create our request used to load the ad.
var adRequest = new AdRequest();
// send the request to load the ad.
Debug.Log("Loading banner ad.");
_bannerView.LoadAd(adRequest);
}
/// <summary>
/// listen to events the banner view may raise.
/// </summary>
public void ListenToAdEvents()
{
// Raised when an ad is loaded into the banner view.
_bannerView.OnBannerAdLoaded += () =>
{
Debug.Log("Banner view loaded an ad with response : "
+ _bannerView.GetResponseInfo());
};
// Raised when an ad fails to load into the banner view.
_bannerView.OnBannerAdLoadFailed += (LoadAdError error) =>
{
Debug.LogError("Banner view failed to load an ad with error : "
+ error);
};
// Raised when the ad is estimated to have earned money.
_bannerView.OnAdPaid += (AdValue adValue) =>
{
Debug.Log(String.Format("Banner view paid {0} {1}.",
adValue.Value,
adValue.CurrencyCode));
};
// Raised when an impression is recorded for an ad.
_bannerView.OnAdImpressionRecorded += () =>
{
Debug.Log("Banner view recorded an impression.");
};
// Raised when a click is recorded for an ad.
_bannerView.OnAdClicked += () =>
{
Debug.Log("Banner view was clicked.");
};
// Raised when an ad opened full screen content.
_bannerView.OnAdFullScreenContentOpened += () =>
{
Debug.Log("Banner view full screen content opened.");
};
// Raised when the ad closed full screen content.
_bannerView.OnAdFullScreenContentClosed += () =>
{
Debug.Log("Banner view full screen content closed.");
};
}/// <summary>
/// Destroys the banner view.
/// </summary>
public void DestroyAd()
{
if (_bannerView != null)
{
Debug.Log("Destroying banner view.");
_bannerView.Destroy();
_bannerView = null;
}
}
}
using UnityEngine;
using Firebase.Analytics;
public class AdManager : MonoBehaviour
{
private static AdManager instance;
public static AdManager Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<AdManager>();
if (instance == null)
{
GameObject adManagerGO = new GameObject();
instance = adManagerGO.AddComponent<AdManager>();
adManagerGO.name = "AdManager";
DontDestroyOnLoad(adManagerGO);
}
}
return instance;
}
}
private void Awake()
{
if (instance == null)
{
instance = this as AdManager;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
public void Start()
{
// Initialize Firebase Analytics
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventAppOpen);
BannerManager.Instance.LoadAd();
}
public void ShowInterstitialAd()
{
// Show interstitial ad logic here
// For example, assuming _interstitialAd is an instance of your interstitial ad
// and it's shown successfully, log the event
LogInterstitialAdShownEvent();
}
private void LogInterstitialAdShownEvent()
{
// Log an event indicating the interstitial ad was shown
FirebaseAnalytics.LogEvent("interstitial_ad_shown");
}
}
플레이콘솔 리더보드에 점수 올리기 (0) | 2024.06.26 |
---|---|
2D 3Matchpuzzle - 매치 시 파괴 및 로드 + 힌트 (0) | 2024.05.20 |
2D 3Matchpuzzle - 블록 위치 찾기 테스트 (0) | 2024.05.16 |
2D 3Matchpuzzle - 빈공간 찾기 (0) | 2024.05.14 |
Download Python (0) | 2024.05.08 |
public void AddLeaderboard(int score)
{
PlayGamesPlatform.Instance.ReportScore(score, GPGSIds.leaderboard_highscore, (bool success) =>
{
if (success)
{
Debug.Log("리더보드에 점수가 성공적으로 추가되었습니다.");
}
else
{
Debug.Log("리더보드 점수 추가에 실패했습니다.");
}
});
}
IEnumerator CoStart()
{
Debug.Log("몬스터가 클릭됨");
anim.SetTrigger("Hit");
hp--;
currentScore++;
Debug.Log(currentScore);
UpdateScoreText();
if (hp <= 0)
{
anim.SetBool("Die", true);
monster.interactable = false;
restartBtn.gameObject.SetActive(true);
// 게임 종료 시 클릭 횟수 PlayerPrefs에 저장
PlayerPrefs.SetInt(PlayerPrefsKey, currentScore);
PlayerPrefs.Save();
GPGSManager.Instance.AddLeaderboard(currentScore);
GPGSManager.Instance.ShowLeaderBoard();
}
yield return null;
}
[애드몹] 배너 광고 붙이기 (0) | 2024.06.28 |
---|---|
2D 3Matchpuzzle - 매치 시 파괴 및 로드 + 힌트 (0) | 2024.05.20 |
2D 3Matchpuzzle - 블록 위치 찾기 테스트 (0) | 2024.05.16 |
2D 3Matchpuzzle - 빈공간 찾기 (0) | 2024.05.14 |
Download Python (0) | 2024.05.08 |
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
public class AtlasManager : MonoBehaviour
{
public static AtlasManager instance;
public SpriteAtlas blockAtlas;
//싱글톤
private void Awake()
{
//AtlasManager 클래스의 인스턴스를 instance에 할당
instance = this;
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.U2D;
using Random = UnityEngine.Random;
public class Test : MonoBehaviour
{
public Board board;
private void Start()
{
board.CreateBoard();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1);
RaycastHit2D raycastHit2D = Physics2D.Raycast(ray.origin, ray.direction);
if (raycastHit2D.collider != null)
{
Block block = raycastHit2D.collider.GetComponent<Block>();
Debug.Log($"[{block.row}, {block.col}] ({block.transform.position.x}, {block.transform.position.y}), {block.blockType}");
}
}
}
}
using Codice.Client.BaseCommands.Filters;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
public class BlockSwapWindow : EditorWindow
{
private int row1;
private int col1;
private int row2;
private int col2;
[MenuItem("Window/Block Swap Window")]
public static void ShowWindow()
{
GetWindow<BlockSwapWindow>("Block Swap Window");
}
private void OnGUI()
{
GUILayout.Label("Swap Blocks", EditorStyles.boldLabel);
row1 = EditorGUILayout.IntField("Row 1", row1);
col1 = EditorGUILayout.IntField("Column 1", col1);
row2 = EditorGUILayout.IntField("Row 2", row2);
col2 = EditorGUILayout.IntField("Column 2", col2);
//버튼 UI추가
if (GUILayout.Button("Swap"))
{
Board.instance.SwapBlocks(row1, col1, row2, col2);
Debug.Log($"Swapped blocks at [{row1}, {col1} ane [{row2}, {col2}]");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(Block))]
public class BlockEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Block block = target as Block;
if (GUILayout.Button("제거"))
{
Debug.Log($"[{block.row},{block.col}]을 제거 합니다.");
Board.instance.RemoveBlock(block.row, block.col);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;
public class Board : MonoBehaviour
{
public static Board instance;// 싱글톤
private Block[,] board; //2차원 배열이 Block들을 관리
public GameObject blockPrefab;
private int[] arrEmptySpaceCol;
public int totalHeight = 10;
public int height = 5;
public int width = 9;
private void Awake()
{
instance = this;
}
public void CreateBoard()
{
//크기가 9인 BlockType의 2차원 배열 만들기
board = new Block[totalHeight, width]; // 2차원 배열로 변경
//5행 9열의 Block타입의 2차원 배열 만들기
for (int i = 0; i < height; i++) //board.GetLength(0)
{
for (int j = 0; j < width; j++) //board.GetLength(1)
{
CreateBlock(i, j);
}
}
PrintBoard();
}
public void CreateBlock(int row, int col)
{
Vector2 pos = new Vector2(col, row);
Block.BlockType blockType = (Block.BlockType)Random.Range(0, 5);
GameObject blockGo = Instantiate(blockPrefab);
Block block = blockGo.GetComponent<Block>();
block.Init(blockType);
block.SetPosition(pos);
//배열의 요소에 블록 넣기
board[row, col] = block;
}
public void RemoveBlock(int row, int col)
{
Block block = board[row, col];
Destroy(block.gameObject); //게임 오브젝트 파괴
//배열의 요소를 비워줌
board[row, col] = null;
}
public void PrintBoard()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) //행
{
for (int j = 0; j < width; j++) //열
{
Block block = board[i, j];
string strElement = (block == null) ? "null" : block.blockType.ToString();
// 각 엘리먼트를 고정된 너비로 출력
sb.AppendFormat("[{0},{1}] = {2,-11}", i, j, strElement);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
public void FindEmptySpaceFromColumn()
{
arrEmptySpaceCol = new int[width]; //배열 초기화
for (int i = 0; i < width; i++) //열
{
int existBlockCnt = 0;
for (int j = 0; j < totalHeight; j++) //행
{
Block block = board[j, i];
if (block != null)
{
existBlockCnt++;
}
}
int emptySpace = height - existBlockCnt;
arrEmptySpaceCol[i] = emptySpace; // 배열의 인덱스(열)에 emptySpace(카운트)값 할당 => 각 열마다 빈공간의 개수
Debug.Log($"{i}열의 빈공간은 {emptySpace}개 입니다.");
}
}
public void CreateNewBlocks()
{
if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
{
Debug.Log("빈 공간이 없습니다.");
}
else
{
for (int i = 0; i < arrEmptySpaceCol.Length; i++)
{
int cnt = arrEmptySpaceCol[i];
if (cnt > 0)
{
Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
CreateBlockFromColumn(i, cnt);
}
}
}
arrEmptySpaceCol = null;
}
private void CreateBlockFromColumn(int col, int cnt)
{
int startRow = height; //행
for (int i = 0; i < cnt; i++)
{
//[7, col] -> [8, col] -> [9, col]
CreateBlock(startRow, col);
startRow++;
}
}
public void MoveAllBlocksInRow(int row)
{
if (row == 0)
{
Debug.Log("가장 아래 있는 행 입니다. (이동불가)");
return;
}
int numberOfBlocksToMove = 0;
for (int col = 0; col < width; col++)
{
int targetRow = row - 1;
Block fromBlock = board[row, col];
Block toBlock = board[targetRow, col];
string strFromBlock = (fromBlock == null) ? "비어있음" : fromBlock.ToString();
string strToBlock = (toBlock == null) ? "비어있음" : toBlock.ToString();
if (fromBlock != null && toBlock == null)
{
//이동가능
Debug.Log($"[{row},{col}] {strFromBlock} -> [{targetRow}, {col} {strToBlock}]으로 이동합니다");
numberOfBlocksToMove++;
}
else
{
//이동 불가능
}
}
if (numberOfBlocksToMove == 0)
{
Debug.Log($"{row} 행의 이동 블록이 업습니다.");
}
else
{
Debug.Log($"{row}행의 이동해야 할 블록이 {numberOfBlocksToMove}개 있습니다.");
}
}
public void SwapBlocks(int row1, int col1, int row2, int col2)
{
if (board[row1, col1] == null && board[row2, col2] == null)
{
Debug.LogError($"[{row1}, {col1}]와 [{row2}, {col2}]가 모두 비어 있습니다. (스왑 실패)");
return;
}
//위치 가져오기
Vector2 fromPos = Block.Index2Position(row1, col1);
Vector2 toPos = Block.Index2Position(row2, col2);
//데이터 변경
Block temp = board[row1, col1];
board[row1, col1] = board[row2, col2];
board[row2, col2] = temp;
//비주얼 이동
if (board[row1, col1] != null)
board[row1, col1].SetPosition(fromPos);
if (board[row2, col2] != null)
board[row2, col2].SetPosition(toPos);
Debug.Log($"Swapped blocks at [{row1}, {col1}] and [{row2}, {col2}]");
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;
public class Board : MonoBehaviour
{
public static Board instance;// 싱글톤
private Block[,] board; //2차원 배열이 Block들을 관리
public GameObject blockPrefab;
private int[] arrEmptySpaceCol;
public int totalHeight = 10;
public int height = 5;
public int width = 9;
private void Awake()
{
instance = this;
}
public void CreateBoard()
{
//크기가 9인 BlockType의 2차원 배열 만들기
board = new Block[totalHeight, width]; // 2차원 배열로 변경
//5행 9열의 Block타입의 2차원 배열 만들기
for (int i = 0; i < height; i++) //board.GetLength(0)
{
for (int j = 0; j < width; j++) //board.GetLength(1)
{
CreateBlock(i, j);
}
}
PrintBoard();
}
public void CreateBlock(int row, int col)
{
Vector2 pos = new Vector2(col, row);
Block.BlockType blockType = (Block.BlockType)Random.Range(0, 5);
GameObject blockGo = Instantiate(blockPrefab);
Block block = blockGo.GetComponent<Block>();
block.Init(blockType);
block.SetPosition(pos);
//배열의 요소에 블록 넣기
board[row, col] = block;
}
public void RemoveBlock(int row, int col)
{
Block block = board[row, col];
Destroy(block.gameObject); //게임 오브젝트 파괴
//배열의 요소를 비워줌
board[row, col] = null;
}
public void PrintBoard()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) //행
{
for (int j = 0; j < width; j++) //열
{
Block block = board[i, j];
string strElement = (block == null) ? "null" : block.blockType.ToString();
// 각 엘리먼트를 고정된 너비로 출력
sb.AppendFormat("[{0},{1}] = {2,-11}", i, j, strElement);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
public void FindEmptySpaceFromColumn()
{
arrEmptySpaceCol = new int[width]; //배열 초기화
for (int i = 0; i < width; i++) //열
{
int existBlockCnt = 0;
for (int j = 0; j < totalHeight; j++) //행
{
Block block = board[j, i];
if (block != null)
{
existBlockCnt++;
}
}
int emptySpace = height - existBlockCnt;
arrEmptySpaceCol[i] = emptySpace; // 배열의 인덱스(열)에 emptySpace(카운트)값 할당 => 각 열마다 빈공간의 개수
Debug.Log($"{i}열의 빈공간은 {emptySpace}개 입니다.");
}
}
public void CreateNewBlocks()
{
if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
{
Debug.Log("빈 공간이 없습니다.");
}
else
{
for (int i = 0; i < arrEmptySpaceCol.Length; i++)
{
int cnt = arrEmptySpaceCol[i];
if (cnt > 0)
{
Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
CreateBlockFromColumn(i, cnt);
}
}
}
arrEmptySpaceCol = null;
}
private void CreateBlockFromColumn(int col, int cnt)
{
int startRow = height; //행
for (int i = 0; i < cnt; i++)
{
//[7, col] -> [8, col] -> [9, col]
CreateBlock(startRow, col);
startRow++;
}
}
public void MoveAllBlocksInRow(int row)
{
if (row == 0)
{
Debug.Log("가장 아래 있는 행 입니다. (이동불가)");
return;
}
int numberOfBlocksToMove = 0;
for (int col = 0; col < width; col++)
{
int targetRow = row - 1;
Block fromBlock = board[row, col];
Block toBlock = board[targetRow, col];
string strFromBlock = (fromBlock == null) ? "비어있음" : fromBlock.ToString();
string strToBlock = (toBlock == null) ? "비어있음" : toBlock.ToString();
if (fromBlock != null && toBlock == null)
{
//이동가능
Debug.Log($"[{row},{col}] {strFromBlock} -> [{targetRow}, {col} {strToBlock}]으로 이동합니다");
numberOfBlocksToMove++;
}
else
{
//이동 불가능
}
}
if (numberOfBlocksToMove == 0)
{
Debug.Log($"{row} 행의 이동 블록이 업습니다.");
}
else
{
Debug.Log($"{row}행의 이동해야 할 블록이 {numberOfBlocksToMove}개 있습니다.");
}
}
public void SwapBlocks(int row1, int col1, int row2, int col2)
{
if (board[row1, col1] == null && board[row2, col2] == null)
{
Debug.LogError($"[{row1}, {col1}]와 [{row2}, {col2}]가 모두 비어 있습니다. (스왑 실패)");
return;
}
//위치 가져오기
Vector2 fromPos = Block.Index2Position(row1, col1);
Vector2 toPos = Block.Index2Position(row2, col2);
//데이터 변경
Block temp = board[row1, col1];
board[row1, col1] = board[row2, col2];
board[row2, col2] = temp;
//비주얼 이동
if (board[row1, col1] != null)
board[row1, col1].SetPosition(fromPos);
if (board[row2, col2] != null)
board[row2, col2].SetPosition(toPos);
Debug.Log($"Swapped blocks at [{row1}, {col1}] and [{row2}, {col2}]");
}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
public class Block : MonoBehaviour
{
public enum BlockType
{
Blue, Gray, Green, Pink, Yellow
}
public BlockType blockType;
public SpriteRenderer spriteRenderer;
public TMP_Text debugText;
public int row;
public int col;
public void Init(BlockType blockType)
{
this.blockType = blockType;
//이미지 변경
ChangeSprite(blockType);
}
public void ChangeSprite(BlockType blockType)
{
//블록의 이름을 넣어서 아틀라스에서 같은 이름인 sprite를 찾고 할당
Sprite sp =
AtlasManager.instance.blockAtlas.GetSprite(blockType.ToString());
spriteRenderer.sprite = sp;
}
public void SetPosition(Vector2 pos)
{
transform.position = pos;
var index = Position2Index(pos);
row = index.row;
col = index.col;
debugText.text = $"[{index.row}, {index.col}]";
}
// 위치와 벡터 좌표가 다르기에 서로 교환가능하게 만들어주는 메소드
public static (int row, int col) Position2Index(Vector2 pos)
{
return ((int)pos.y, (int)pos.x);
}
public static (int x, int y) Index2Position(Vector2 index)
{
return ((int)index.x, (int)index.y);
}
public static Vector2 Position2Index(int posX, int posY)
{
return new Vector2((int)posY, (int)posX);
}
public static Vector2 Index2Position(int row, int col)
{
return new Vector2((int)col, (int)row);
}
}
[3Match Puzzle] 스왑 메서드 만들기 (0) | 2024.06.20 |
---|---|
[3Match Puzzle] 스왑 Tool UI (0) | 2024.06.19 |
[3Match Puzzle] 각 행에 있는 모든 블록 내려보내기 버튼 생성 (0) | 2024.06.19 |
[3Match Puzzle] 각 열에 빈공간 찾기 로직 수 (0) | 2024.06.19 |
[3Match Puzzle] 빈공간에 해당하는 위치에 블록 생성하기 (0) | 2024.06.18 |
처음에 버튼을 클릭후 캔버스를 띄어주고
버튼이 사라져야 하는데
사라지지 않아 카메라의 렌더 타입을 Overlay -> base 바꾸니 해결되었다.
[SSG] Dialog 캐릭터 등장 DOTween, 배경, 스테이지 전환 알림문구 적용 (0) | 2024.07.02 |
---|---|
[SSG] 대화창에 배경적용 시키기 (0) | 2024.06.30 |
[SSG] Dialog RnD (0) | 2024.06.15 |
[SSG] 로비에서 변경한 소리를 다른 씬에도 저장시켜 적용하기 (0) | 2024.06.10 |
[SSG] 행동카드 도감에 있는 정보인지 아닌지 구별하여 출력 (0) | 2024.06.09 |
구글 콘솔에서 해당 탭을 추가한 후
PlayGamesPlatform.Instance.ShowLeaderboardUI();
PlayGamesPlatform.Instance.ShowAchievementsUI();
아직 진행중
위에있는 줄을 아래로 내려야 한다.
그때 위의 줄은 row 이고 즉, 빈공간은 targetrow가 되는데
그 row에 해당하는 각각의 block이 fromBlock 과 toBlock으로 나뉜다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Board))]
public class BoardEditor : Editor
{
private int currentRowIdx = 0;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Board board = target as Board;
if(GUILayout.Button("배열 요소 출력"))
{
board.PrintBoard();
}
GUILayout.Space(5);
if(GUILayout.Button("각 열에 빈공간 찾기"))
{
board.FindEmptySpaceFromColumn();
}
GUILayout.Space(5);
if (GUILayout.Button("새로운 블록들 생성하기"))
{
board.CreateNewBlocks();
}
GUILayout.Space(5);
if(GUILayout.Button($"현재 행 ({currentRowIdx}에 있는 모든 블록 내려보내기"))
{
Debug.Log($"{currentRowIdx}행에 있는 모든 블록을 내려 보냅니다.");
currentRowIdx++;
if(currentRowIdx > 9) /////////////////잘 봐야함
{
currentRowIdx = 0;
}
}
if(GUILayout.Button("리셋 행"))
{
currentRowIdx = 0;
}
GUILayout.Space(5);
if(GUILayout.Button("스왑 윈도우 열기"))
{
BlockSwapWindow.ShowWindow();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Random = UnityEngine.Random;
public class Board : MonoBehaviour
{
public static Board instance;// 싱글톤
private Block[,] board; //2차원 배열이 Block들을 관리
public GameObject blockPrefab;
private int[] arrEmptySpaceCol;
public int totalHeight = 10;
public int height = 5;
public int width = 9;
private void Awake()
{
instance = this;
}
public void CreateBoard()
{
//크기가 9인 BlockType의 2차원 배열 만들기
board = new Block[totalHeight, width]; // 2차원 배열로 변경
//5행 9열의 Block타입의 2차원 배열 만들기
for (int i = 0; i < height; i++) //board.GetLength(0)
{
for (int j = 0; j < width; j++) //board.GetLength(1)
{
CreateBlock(i, j);
}
}
PrintBoard();
}
public void CreateBlock(int row, int col)
{
Vector2 pos = new Vector2(col, row);
Block.BlockType blockType = (Block.BlockType)Random.Range(0, 5);
GameObject blockGo = Instantiate(blockPrefab);
Block block = blockGo.GetComponent<Block>();
block.Init(blockType);
block.SetPosition(pos);
//배열의 요소에 블록 넣기
board[row, col] = block;
}
public void RemoveBlock(int row, int col)
{
Block block = board[row, col];
Destroy(block.gameObject); //게임 오브젝트 파괴
//배열의 요소를 비워줌
board[row, col] = null;
}
public void PrintBoard()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < height; i++) //행
{
for (int j = 0; j < width; j++) //열
{
Block block = board[i, j];
string strElement = (block == null) ? "null" : block.blockType.ToString();
// 각 엘리먼트를 고정된 너비로 출력
sb.AppendFormat("[{0},{1}] = {2,-11}", i, j, strElement);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
public void FindEmptySpaceFromColumn()
{
arrEmptySpaceCol = new int[width]; //배열 초기화
for (int i = 0; i < width; i++) //열
{
int existBlockCnt = 0;
for (int j = 0; j < totalHeight; j++) //행
{
Block block = board[j, i];
if (block != null)
{
existBlockCnt++;
}
}
int emptySpace = height - existBlockCnt;
arrEmptySpaceCol[i] = emptySpace; // 배열의 인덱스(열)에 emptySpace(카운트)값 할당 => 각 열마다 빈공간의 개수
Debug.Log($"{i}열의 빈공간은 {emptySpace}개 입니다.");
}
}
public void CreateNewBlocks()
{
if (arrEmptySpaceCol == null || arrEmptySpaceCol.All(x => x == 0))
{
Debug.Log("빈 공간이 없습니다.");
}
else
{
for(int i = 0; i < arrEmptySpaceCol.Length; i++)
{
int cnt = arrEmptySpaceCol[i];
Debug.Log($"{i}열에 {cnt}만큼 블록 생성 필요");
CreateBlockFromColumn(i, cnt);
}
}
arrEmptySpaceCol = null;
}
private void CreateBlockFromColumn(int col, int cnt)
{
int startRow = height; //행
for (int i = 0; i < cnt; i++)
{
//[7, col] -> [8, col] -> [9, col]
CreateBlock(startRow, col);
startRow++;
}
}
public void MoveAllBlocksInRow(int row)
{
if (row == 0)
{
Debug.Log("가장 아래 있는 행 입니다. (이동불가)");
return;
}
int numberOfBlocksToMove = 0;
for (int col = 0; col < width; col++)
{
int targetRow = row - 1;
Block fromBlock = board[row, col];
Block toBlock = board[targetRow, col];
string strFromBlock = (fromBlock == null) ? "비어있음" : fromBlock.ToString();
string strToBlock = (toBlock == null) ? "비어있음" : toBlock.ToString();
if (fromBlock != null && toBlock == null)
{
//이동가능
Debug.Log($"[{row},{col}] {strFromBlock} -> [{targetRow}, {col} {strToBlock}]으로 이동합니다");
numberOfBlocksToMove++;
}
else
{
//이동 불가능
}
}
if(numberOfBlocksToMove == 0)
{
Debug.Log($"{row} 행의 이동 블록이 업습니다.");
}
else
{
Debug.Log($"{row}행의 이동해야 할 블록이 {numberOfBlocksToMove}개 있습니다.");
}
}
public void SwapBlocks(int row1, int col1, int row2, int col2)
{
if (board[row1, col1] == null && board[row2, col2] == null)
{
Debug.LogError($"[{row1}, {col1}]와 [{row2}, {col2}]가 모두 비어 있습니다. (스왑 실패)");
return;
}
//위치 가져오기
Vector2 fromPos = Block.Index2Position(row1, col1);
Vector2 toPos = Block.Index2Position(row2, col2);
//데이터 변경
Block temp = board[row1, col1];
board[row1, col1] = board[row2,col2];
board[row2, col2] = temp;
//비주얼 이동
if(board[row1, col1] != null)
board[row1, col1].SetPosition(fromPos);
if (board[row2, col2] != null)
board[row2,col2].SetPosition(toPos);
Debug.Log($"Swapped blocks at [{row1}, {col1}] and [{row2}, {col2}]");
}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
public class Block : MonoBehaviour
{
public enum BlockType
{
Blue, Gray, Green, Pink, Yellow
}
public BlockType blockType;
public SpriteRenderer spriteRenderer;
public TMP_Text debugText;
public int row;
public int col;
public void Init(BlockType blockType)
{
this.blockType = blockType;
//이미지 변경
ChangeSprite(blockType);
}
public void ChangeSprite(BlockType blockType)
{
//블록의 이름을 넣어서 아틀라스에서 같은 이름인 sprite를 찾고 할당
Sprite sp =
AtlasManager.instance.blockAtlas.GetSprite(blockType.ToString());
spriteRenderer.sprite = sp;
}
public void SetPosition(Vector2 pos)
{
transform.position = pos;
var index = Position2Index(pos);
row = index.row;
col = index.col;
debugText.text = $"[{index.row}, {index.col}]";
}
public static (int row, int col) Position2Index(Vector2 pos)
{
return ((int)pos.y, (int)pos.x);
}
public static (int x, int y) Index2Position(Vector2 index)
{
return ((int)index.x, (int)index.y);
}
public static Vector2 Index2Position(int row, int col)
{
return new Vector2((int)col, (int)row);
}
}
[3Match Puzzle]스왑 -> 빈공간 찾기 -> 생성하기 -> 이동하기 (0) | 2024.06.24 |
---|---|
[3Match Puzzle] 스왑 Tool UI (0) | 2024.06.19 |
[3Match Puzzle] 각 행에 있는 모든 블록 내려보내기 버튼 생성 (0) | 2024.06.19 |
[3Match Puzzle] 각 열에 빈공간 찾기 로직 수 (0) | 2024.06.19 |
[3Match Puzzle] 빈공간에 해당하는 위치에 블록 생성하기 (0) | 2024.06.18 |