이번에는 저번에 못했던 것들.

마우스떼면 중앙에 설치하기 + 길 또는 타워 위에 설치불가 + 타워설치시 맵에 기록을 구현했다.


전부 onMouseUp에서 마우스를 뗄때 여러가지를 체크해주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousepos.z = 1.0f;
 
// 마우스포지션 기준 2*2만큼 위치 표시
int mouseX = (int)(mousepos.x / 0.64f);
int mouseY = (int)(mousepos.y / 0.64f);
float mousefX = mousepos.x / 0.64f;
float mousefY = mousepos.y / 0.64f;
 
// x와 y 전부 +0.5해준이유는 격자 4개 중간에 설치하기 위해서. y축 + 0.1은 조금 더 위로 올린 것.
Vector3 Instantpos = Vector3.zero;
bool BuildAllow = true;
var tm = GameObject.FindGameObjectWithTag("InstallManager").GetComponent<TowerMaker>();
// 오른쪽
if (mousefX > mouseX + 0.5f)
{
    // 위
    if (mousefY > mouseY + 0.5f)
    {
        // 타워를 중앙에 설치하도록 위치설정
        Instantpos += new Vector3(((mouseX + 0.5f) + 0.5f) * 0.64f, ((mouseY + 0.5f) + 0.5f) * 0.64f + 0.1f);
        // 4칸중에 하나라도 null이면 타워건설안함
        if (tm.MakeMap[mouseY * 20 + mouseX] == 1 || tm.MakeMap[mouseY * 20 + mouseX + 1== 1
            || tm.MakeMap[(mouseY + 1* 20 + mouseX] == 1 || tm.MakeMap[(mouseY + 1* 20 + mouseX + 1== 1)
        {
            BuildAllow = false;
        }
        //전부 null이 아니면 배열의 값을 1로 만들어 길로 인식하게함.
        else
        {
            tm.MakeMap[mouseY * 20 + mouseX] = 1;
            tm.MakeMap[mouseY * 20 + mouseX + 1= 1;
            tm.MakeMap[(mouseY + 1* 20 + mouseX] = 1;
            tm.MakeMap[(mouseY + 1* 20 + mouseX + 1= 1;
            MapData.Instance.MakeSign();
        }
    }
    // 아래
    else if (mousefY<mouseY + 0.5f)
    {
        Instantpos += new Vector3(((mouseX + 0.5f) + 0.5f) * 0.64f, ((mouseY + 0.5f) - 0.5f) * 0.64f + 0.1f);
        // 4칸중에 하나라도 null이면 타워건설안함
        if (tm.MakeMap[mouseY * 20 + mouseX] == 1 || tm.MakeMap[mouseY * 20 + mouseX + 1== 1
            || tm.MakeMap[(mouseY - 1* 20 + mouseX] == 1 || tm.MakeMap[(mouseY - 1* 20 + mouseX + 1== 1)
        {
            BuildAllow = false;
        }
        //전부 null이 아니면 배열의 값을 1로 만들어 길로 인식하게함.
        else
        {
            tm.MakeMap[mouseY * 20 + mouseX] = 1;
            tm.MakeMap[mouseY * 20 + mouseX + 1= 1;
            tm.MakeMap[(mouseY - 1* 20 + mouseX] = 1;
            tm.MakeMap[(mouseY - 1* 20 + mouseX + 1= 1;
            MapData.Instance.MakeSign();
        }
    }
}
 
...
 
// 실제 타워 생성
if(BuildAllow)
    Instantiate(realTower, Instantpos, Quaternion.identity);
cs

마우스포지션은 이전하고 똑같이 받아와서 똑같은 방법으로 4가지 경우를 전부 체크한다.

같은작업의 반복이라서 코드는 2개만 올렸음.



마우스떼면 중앙에 설치

Instantpos라는 벡터를 만들어 실제설치할 위치를 표시된 4칸의 중간으로 옮겨주었다.

너무 정중앙에 있는것보다 살짝 위로 가는게 자연스러워 y축으로 0.1만큼의 수치를 옮겨줌.



길 또는 타워 위치에 설치불가

마우스 위치에서 표시된 4칸중 하나라도 막혀있으면 BuildAllow라는 변수를 false로 만들어

false면 실제 타워를 생성하지않도록 했다.



타워설치시 맵에 기록

위에서 4칸중 전부가 가능한 범위면 배열에 값을 체크해주고 미리생성해둔 격자를 새로 갱신해주었다.

처음에는 설치하는 프리팹의 스크립트에 격자를 생성했었는데 

그러다보니 격자가 프리팹마다 따로 생성되고 갱신이 바로바로 되지않아서 격자는 싱글톤으로 변경하였다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
// 싱글톤
public class MapData {
 
    private static MapData instance = null;
    private static readonly object padlock = new object();
    private Transform parent = null;
    public GameObject[] sign = new GameObject[260];
 
    public void setParent(Transform t)
    {
        parent = t;
    }
 
    private MapData()
    {
    }
 
    public void MakeSign()
    {
        // 격자 생성
        for (int i = 0; i < 260; i++)
        {
            if (sign[i] != null)
                GameObject.Destroy(sign[i]);
 
            // UI구간 1로 초기화(설치못하게)
            if (i < 40)
            {
                GameObject.FindGameObjectWithTag("InstallManager").GetComponent<TowerMaker>().MakeMap[i] = 1;
            }
 
            // 맵에 따라 설치가능위치표시 후 active false
            if (GameObject.FindGameObjectWithTag("InstallManager").GetComponent<TowerMaker>().MakeMap[i] == 1)
            {
                var no = Resources.Load("makeNo"typeof(GameObject)) as GameObject;
                sign[i] = GameObject.Instantiate(no, parent);
            }
            else
            {
                var yes = Resources.Load("makeYes"typeof(GameObject)) as GameObject;
                sign[i] = GameObject.Instantiate(yes, parent);
            }
            sign[i].transform.position = new Vector3(TileMaker.startX + i % 20 * 0.64f, TileMaker.startY + i / 20 * 0.64f);
            sign[i].SetActive(false);
        }
    }
 
    public static MapData Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new MapData();
                }
                return instance;
            }
        }
    }
}
cs

격자선언과 생성부분을 전부 싱글톤으로 옮겨줌.

이후 생성되는 오브젝트들을 한곳에서 관리하고싶어서 다른곳에 부모가 될 오브젝트를 생성하고 부모를 알려주었다.




그리고 설치시 타워 공격범위를 미리 표시하기위해 원모양의 Sprite를 만들었다.

Project뷰에서 Create -> Sprites -> Circle을 누르면 생성할 수 있다.

생성 후 프리팹화하여 스크립트에 달아주고 클릭시 생성 마우스 뗄때 삭제하게하여 설치과정에 범위가 보이게 하였다.



실행화면

td_towerdrag2.mp4



Posted by misty_
,