GameManagerEditor.cs 소스입니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GameManager))]
public class GameManagerEditor : Editor
{
GameManager GM;
void OnEnable()
{
GM = target as GameManager;
GM.EditorRepaint += Repaint;
}
void OnDisable()
{
GM.EditorRepaint -= Repaint;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
GUILayout.Space(20);
EditorGUILayout.LabelField("Array");
for (int i = 9; i >= 0; i--)
{
GUILayout.BeginHorizontal();
for (int j = 0; j < 10; j++)
GM.Array[j, i] = EditorGUILayout.IntField(GM.Array[j, i], GUILayout.Width(30));
GUILayout.EndHorizontal();
}
}
}
CellScript.cs 소스입니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class CellScript : MonoBehaviour
{
public int colorIndex;
public Vector3[] ShapePos;
GameManager GM;
Vector3 BlockPos, pos;
void Start()
{
BlockPos = transform.parent.position;
GM = GameObject.FindWithTag("GameManager").GetComponent<GameManager>();
ShapePos = new Vector3[transform.childCount];
for (int i = 0; i < transform.childCount; i++)
ShapePos[i] = transform.GetChild(i).localPosition;
}
IEnumerator FollowMouse()
{
while (true)
{
yield return null;
transform.position = Vector3.Lerp(transform.position, pos + new Vector3(0, 1, 0), Time.deltaTime * 30);
}
}
void OnMouseDown()
{
transform.DOScale(1, 0.2f);
StartCoroutine("FollowMouse");
}
void OnMouseDrag()
{
pos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
}
void OnMouseUp()
{
StopCoroutine("FollowMouse");
transform.DOScale(0.6f, 0.2f);
transform.DOMove(BlockPos, 0.2f);
Vector3 lastPos = pos + new Vector3(0, 1, 0);
lastPos.x = Mathf.RoundToInt(lastPos.x);
lastPos.y = Mathf.RoundToInt(lastPos.y);
GM.BlockInput(this ,colorIndex, lastPos, ShapePos);
}
public void ForceDestroy()
{
DOTween.KillAll();
Destroy(gameObject);
}
}
GameManager.cs 소스입니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class GameManager : MonoBehaviour
{
const int SIZE = 10;
public Color[] ShapeColors;
public GameObject[] Cells;
public int[,] Array = new int[SIZE, SIZE];
public GameObject[] Shapes;
public Transform[] BlockPos;
public TextMesh ScoreTextMesh;
public event System.Action EditorRepaint = () => { };
int score;
void Start()
{
StartCoroutine(SpawnBlocks());
}
IEnumerator SpawnBlocks()
{
for (int i = 0; i < BlockPos.Length; i++)
{
yield return new WaitForSeconds(0.08f);
Transform CurShape = Instantiate(Shapes[Random.Range(0, Shapes.Length)],
//Transform CurShape = Instantiate(Shapes[0],
//Transform CurShape = Instantiate(Shapes[8],
BlockPos[i].position + new Vector3(10, 0, 0), Quaternion.identity).transform;
CurShape.SetParent(BlockPos[i]);
CurShape.DOMove(BlockPos[i].position, 0.4f);
}
yield return null;
if (!AvailCheck()) Die();
}
GameObject GetCell(int x, int y)
{
return Cells[y * SIZE + x];
}
bool InRange(int x, int y)
{
if (x < 0 || y < 0 || x >= SIZE || y >= SIZE) return false;
return true;
}
bool Possible(int x, int y)
{
if (Array[x, y] != 0) return false;
return true;
}
public void BlockInput(CellScript cellScript, int colorIndex, Vector3 lastPos, Vector3[] ShapePos)
{
for (int i = 0; i < ShapePos.Length; i++)
{
Vector3 SumPos = ShapePos[i] + lastPos;
if (!InRange((int)SumPos.x, (int)SumPos.y)) return;
if (!Possible((int)SumPos.x, (int)SumPos.y)) return;
}
for (int i = 0; i < ShapePos.Length; i++)
{
Vector3 SumPos = ShapePos[i] + lastPos;
Array[(int)SumPos.x, (int)SumPos.y] = colorIndex;
GetCell((int)SumPos.x, (int)SumPos.y).GetComponent<SpriteRenderer>().color = ShapeColors[colorIndex];
}
cellScript.ForceDestroy();
LineLogic(ShapePos.Length);
Invoke("EndTurn", 0.07f);
EditorRepaint();
}
void LineLogic(int shapePosLength)
{
// 가로세로
int oneLine = 0;
for (int i = 0; i < SIZE; i++)
{
int horizontalCount = 0;
int verticalCount = 0;
for (int j = 0; j < SIZE; j++)
{
if (Array[j, i] != 0) ++horizontalCount;
if (Array[i, j] != 0) ++verticalCount;
}
if (horizontalCount == 10)
{
++oneLine;
for (int j = 0; j < SIZE; j++) Array[j, i] = -1;
}
if (verticalCount == 10)
{
++oneLine;
for (int j = 0; j < SIZE; j++) Array[i, j] = -1;
}
}
// 파괴
for (int i = 0; i < SIZE; i++)
for (int j = 0; j < SIZE; j++)
if (Array[i, j] == -1)
{
Array[i, j] = 0;
GameObject CurCell = GetCell(i, j);
var doScale = CurCell.transform.DOScale(Vector3.zero, 0.2f);
doScale.OnComplete(() =>
{
CurCell.GetComponent<SpriteRenderer>().color = ShapeColors[0];
CurCell.transform.localScale = new Vector3(0.28f, 0.28f, 1);
});
}
// 점수
score += oneLine * 10 + shapePosLength;
}
bool Putable(Vector3[] ShapePos)
{
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
int count = 0;
for (int k = 0; k < ShapePos.Length; k++)
{
Vector3 CurShapePos = ShapePos[k] + new Vector3(i, j, 0);
if (!InRange((int)CurShapePos.x, (int)CurShapePos.y)) break;
if (!Possible((int)CurShapePos.x, (int)CurShapePos.y)) break;
++count;
}
if (count == ShapePos.Length) return true;
}
}
return false;
}
bool AvailCheck()
{
int count = 0;
for (int i = 0; i < BlockPos.Length; i++)
{
if (BlockPos[i].childCount != 0)
{
count++;
if (Putable(BlockPos[i].GetComponentInChildren<CellScript>().ShapePos)) return true; // 가능한 블럭
}
}
return count == 0;
}
void EndTurn()
{
ScoreTextMesh.text = score.ToString();
if (!AvailCheck()) { Die(); return; }
int count = 0;
for (int i = 0; i < BlockPos.Length; i++)
if (BlockPos[i].childCount != 0) ++count;
if (count == 0) StartCoroutine(SpawnBlocks());
}
void Die()
{
print("죽음");
}
}