사용한 함수 : Stack, LineRenderer
https://learn.microsoft.com/ko-kr/dotnet/api/system.collections.stack?view=net-7.0
https://docs.unity3d.com/ScriptReference/LineRenderer.html
목표 & 할일
알게된 점
LineRenderer라는 Component를 통해
이 Line Effect 오브젝트에
TestLine 스크립트를 넣어서 선을 그리는 Scripts 작동을 하게 한다.
TestLine은 Play, Stop, Init 메서드를 가지고있다.
Play = LineRenderer를 활성화하고 positionCount를 정해줘서 SetPosition으로 target을 생성해줬다.
Stop = LineRenderer를 비활성화해주고 Init메서드를 불러온다
Init = Stop 됐을 때 가지고있는 SetPosition을 초기화 시켜주는 메서드다.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class TestLine : MonoBehaviour
{
private LineRenderer lineRenderer;
private int idx = 0;
private void Awake()
{
this.lineRenderer = GetComponent<LineRenderer>();
this.lineRenderer.enabled = false;
}
public void Play(TestSaveLocation target)
{
this.lineRenderer.enabled = true;
this.lineRenderer.positionCount = idx + 1; // 1
this.lineRenderer.SetPosition(idx, target.transform.position); // 0번 , target 생성
idx++; // idx = 1;
}
public void Stop()
{
this.lineRenderer.enabled = false;
this.Init();
}
public void Init()
{
//Play의 target.position과 idx를 초기화해줘야할듯
for(int i = 0; i < idx; i++)
{
this.lineRenderer.SetPosition(i, Vector3.zero);
}
idx = 0;
//this.stackBlock.Clear();
}
}
수정 전
아예 다른 블럭들을 이어도 삭제가 되게 일단 만들었다.
이 때는 Stack으로 마우스 드래그할 때 받지않았고, 그냥 GameObject를 인식해서 해주는 역할로 해주었다.
그래서 Stack으로 바꾸고자하고 코드를 완전 많이 수정하였다.
수정 후
Stack구조로 바꿔주었다.
Stack 구조로 바꾸고 나서 MouseButton이 클릭하고있는 상태일 때 좌표와 내가 무슨 색을 고르고있는지
Debug.Log로 찍게 만들었다.
어려웠고 알게된 점
stackBlock.Count != 0
이걸로 스택이 있는지 없는지 구별하게 만들었는데
처음에는 if(stackBlock == null) 로 해봤는데 그거는 에러가 나서 안되고
찾아보니까 Count라는 스택 속성이 있어서 사용하게 되었다.
if (stackBlock.Peek().type == this.location.type)
이 부분도 조금 애먹었던 곳이다. Push를 먼저 해줘서 그 후에 if문으로 검사하다보니까 음.. 계속 location.type과 Peek().type이 같은데 어떻게 구별을 해줘야할까.. 고민하다가 Push 위치를 바꿔 주어서 해결했다.
Push 부분을
이렇게 만들어줘서 Peek().type 과 location.type이
즉, 마우스 선택한 gameObject의 type과 전의 type이 다르게 만들어줬다.
스크립트
TestMain - 일단 잡다하게 적었는데 마우스가 클릭하고있을 때 Stack 추가를 한다거나 선을 긋고, 블록 저장,
Count (gameObject가 하나 있으면 true로 되서 한개의 gameObject만 저장해놓는 bool)
이 정도 구성을 하고있다.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.GraphicsBuffer;
public class TestMain : MonoBehaviour
{
[SerializeField]
private GameObject wallPrefab;
[SerializeField]
private GameObject blockPrefab;
[SerializeField]
private Transform boardTr;
private TestBlock testBlock;
private TestSaveLocation location;
[SerializeField]
private TestLine testLine;
[SerializeField]
private float raycastDistance = 1f;
private int[,] str =
{
{0, 4, 4, 2, 4, 1, 0},
{0, 4, 5, 1, 1, 2, 0},
{0, 5, 5, 4, 3, 2, 0},
{0, 1, 1, 2, 3, 2, 0},
{0, 1, 3, 3, 5, 5, 0},
{0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0}
};
private List<GameObject> listBlock = new List<GameObject>();
private Stack<TestSaveLocation> stackBlock = new Stack<TestSaveLocation>();
private bool IsCount = false;
private List<bool> listCount = new List<bool>();
// Start is called before the first frame update
void Start()
{
int maxRow = 7;
int maxCol = 7;
this.testBlock = new TestBlock(maxRow, maxCol);
for (int row = 0; row < maxRow; row++)
{
for (int col = 0; col < maxCol; col++)
{
switch (str[row, col])
{
case 0:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.wallPrefab, this.boardTr, TestBlock.eBlockType.WALL);
break;
case 1:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.RED);
break;
case 2:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.BLUE);
break;
case 3:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.GREEN);
break;
case 4:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.YELLOW);
break;
case 5:
testBlock.Move(row, col);
testBlock.InstantiateObj(this.blockPrefab, this.boardTr, TestBlock.eBlockType.PURPLE);
break;
}
}
}
}
private void Update()
{
if (Input.GetMouseButton(0))
{
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero, raycastDistance);
//마우스 왼쪽 버튼을 누르고 있을 때
//1. 인식 [좌표 출력]
if (hit == false)
{
//gameObject bool로 Count하기
if (IsCount == true)
{
this.IsCount = false;
}
return;
}
else // hit == true
{
//블럭일 때
if (hit.collider.CompareTag("Block"))
{
//gameObject Count 세기
if (IsCount == false)
{
this.location = hit.collider.gameObject.GetComponent<TestSaveLocation>();
//좌표찍기
this.location.PutLocation();
//블럭 색 별로 인식하기
GameObject blockGo = hit.collider.gameObject;
//스텍이 0개인지 아닌지 [다른 블록 넘어가지 않기]
if (stackBlock.Count != 0)
{
//스택이 1개 이상일 때
if (stackBlock.Peek().type == this.location.type) // type이 같을 때
{
//블록 저장, 선긋기, 스택저장, Count 저장
this.SaveBlock(blockGo);
this.testLine.Play(this.location);
this.stackBlock.Push(this.location);
this.listCount.Add(this.IsCount);
Debug.LogFormat("{0} : Peek", this.stackBlock.Peek().type);
}
}
else
{
//0개라면, 블록 저장, 선긋기, 스택저장, Count 저장
Debug.Log("아직 스택이 없습니다.");
this.SaveBlock(blockGo);
this.testLine.Play(this.location);
this.stackBlock.Push(this.location);
this.listCount.Add(this.IsCount);
}
this.IsCount = true;
}
}
}
}
else if (Input.GetMouseButtonUp(0)) // 마우스버튼을 뗐을 때
{
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);
if (hit == false)
{
return;
}
else
{
//listCount가 2개라면 Destroy 안하고 다시 listCount 0으로 초기화시키기
if (this.listCount.Count >= 3)
{
//3개 이상이라면
this.DestroyBlock();
this.testLine.Stop();
this.listCount.Clear();
this.stackBlock.Clear();
IsCount = false;
}
else if (this.listCount.Count <= 2)
{
//2개 이하라면
this.testLine.Stop();
this.listCount.Clear();
this.listBlock.Clear();
this.stackBlock.Clear();
Debug.Log(listCount.Count);
IsCount = false;
}
}
}
}
//블럭 저장하는거
public void SaveBlock(GameObject blockGo)
{
this.listBlock.Add(blockGo);
Debug.Log(this.listBlock.Count);
}
public void DestroyBlock()
{
for (int i = 0; i < listBlock.Count; i++)
{
//만약 100개를 찍었다. Destroy를 했다 -> 0번 부터 100개까지 Destroy 시킨다.
Destroy(this.listBlock[i]);
}
this.listBlock.Clear();
}
}
TestSaveLocation - row, col, type 값을 저장해놓고 그 정보를 내보내거나 저장해놓는 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestSaveLocation : MonoBehaviour
{
public int row;
public int col;
public TestBlock.eBlockType type;
public void GetLocation(int row, int col, TestBlock.eBlockType type)
{
this.row = row;
this.col = col;
this.type = type;
Debug.LogFormat("<color=yellow>({0},{1}) = {2}</color>", row, col, type);
}
public void PutLocation()
{
Debug.LogFormat($"<color={type.ToString()}>({row},{col}) = {type}</color>");
}
}
TestBlock
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestBlock : MonoBehaviour
{
private int nRow;
private int nCol;
private int m_nRow;
private int m_nCol;
private eBlockType[,] str;
public eBlockType[,] Str
{
get { return this.str; }
}
public enum eBlockType
{
WALL = 0,
RED = 1,
BLUE = 2,
GREEN = 3,
YELLOW = 4,
PURPLE = 5,
}
private eBlockType m_BlockType;
public eBlockType blockType
{
get { return this.m_BlockType; }
}
public TestBlock(int maxRow, int maxCol)
{
this.m_nRow = maxRow;
this.m_nCol = maxCol;
//배열 방 크기 만들기
str = new eBlockType[maxRow, maxCol];
}
public void InstantiateObj(GameObject objPrefab, Transform boardTr, eBlockType type)
{
GameObject obj = Instantiate(objPrefab, boardTr);
obj.transform.position = boardTr.position + new Vector3(nCol, nRow);
SpriteRenderer objSp = obj.GetComponent<SpriteRenderer>();
objSp.sprite = Resources.Load<Sprite>($"Test/{type}");
this.m_BlockType = type;
Str[nRow, nCol] = this.m_BlockType;
TestSaveLocation location = obj.GetComponent<TestSaveLocation>();
location.GetLocation(nRow, nCol, Str[nRow, nCol]);
Debug.LogFormat("({0},{1}) = {2}", nRow, nCol, Str[nRow, nCol]);
}
public void Move(int row, int col)
{
this.nRow = row;
this.nCol = col;
}
}
'워리어 콤보 모작 개발일지' 카테고리의 다른 글
워리어콤보 모작 개발일지 - 블럭 되돌아갈 때 선그리기, 되돌아갈 때 블럭 2개 이하면 삭제 안되게하기, 되돌아갈 때 prev 위치 정해줘서 블럭 3개 이상이면 삭제시키기 (1) | 2023.09.20 |
---|---|
워리어콤보 개발일지 - 뒤로 갈 때 "일치함" 콘솔창에 띄우기 (0) | 2023.09.19 |
워리어콤보 개발일지 - Block 삭제하기 (0) | 2023.09.17 |
워리어콤보 개발일지 - Block 인식하기 (0) | 2023.09.16 |
워리어콤보 개발일지 - 좌표찍기 (0) | 2023.09.16 |