원하는 타워를 원하는 위치로 드래그하여 설치하게 만들어봤다.


우선 타워설치매니저를 만들어 TowerMaker라는 스크립트를 만들어 넣어주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TowerMaker : MonoBehaviour {
 
    public GameObject SplashTower = null;
    public GameObject ThunderTower = null;
 
    public int[] MakeMap = new int[260];
    // Use this for initialization
    void Start()
    {
        Vector3 basicpos = new Vector3(6.7f, 0.7f, 0);
        Instantiate(SplashTower, basicpos, Quaternion.identity);
        Instantiate(ThunderTower, basicpos + new Vector3(1.0f, 0.0f), Quaternion.identity);
 
        MakeMap = GameObject.FindGameObjectWithTag("TileManager").GetComponent<MakePath>().map;
    }
 
    // Update is called once per frame
    void Update () {
        
    }
}
cs

여기에는 공격을 하지않는 설치용 타워프리팹이 들어간다.





해당 프리팹에는 설치위치를 미리 보여줄 반투명한 프리팹과 실제 설치될 프리팹이 들어간다.

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class TowerMakeClick : MonoBehaviour {
 
    private bool isclicked = false;
 
    public GameObject alpha150 = null;
    private GameObject createalpha = null;
    public GameObject realTower = null;
 
    // Use this for initialization
    void Start () {
        isclicked = false;
    }
    
    // Update is called once per frame
    void Update () {
        
    }
 
    private void OnMouseDown()
    {
        isclicked = true;
        createalpha = Instantiate(alpha150, transform);
        Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mousepos.z = 1.0f;
        createalpha.transform.position = mousepos;
    }
 
    private void OnMouseDrag()
    {
        if (isclicked == true)
        {
            // 마우스따라 반투명 캐릭터가 움직임
            Vector3 mousepos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousepos.z = 1.0f;
            createalpha.transform.position = mousepos;
        }
    }
 
    private void OnMouseUp()
    {
        isclicked = false;
        Instantiate(realTower, createalpha.transform.position, Quaternion.identity);
        Destroy(createalpha);
    }
}
 
cs

그리고 Collider를 넣어주어 마우스관련함수들이 동작하도록 하였다.

콜라이더가 없으니까 OnMouseDown등의 마우스 관련함수들이 동작하지 않는걸보니 이것도 충돌체크를 하는듯.



마우스를 누르면(onMousedown) 반투명한 프리팹을 마우스의 위치로 생성한다.

z축은 카메라의 포인트를 받아오므로 -10이되어서 1로 변경해주었다.

드래그하면(onMouseDrag) 생성했던 반투명한 프리팹이 마우스를 따라다닌다.

마우스를 놓게되면(onMouseUp) 그 위치에 실제 타워를 건설하고 반투명한 프리팹은 삭제시킨다.




실행화면

td_towerdrag.mp4





여기서 마우스를 클릭하면 생성가능한 지역을 나타내고 싶어서 아래와 같은 이미지를 직접 만들어 알파값을 낮춰주었다.



생성가능한 지역은 MakePath에 저장되어있는 map이라는 배열을 이용하여 

맵에 설치된 오브젝트 중 길인 곳만 막자고 생각하였다.


그래서 위의 TowerMaker 스크립트를 보면 MakeMap이라는 배열을 만들어 MakePath의 map 배열을 받아와 넣어줬다.

바로 가져다써도 되는데 새로 만들어준 이유는 실제 맵데이터를 건들지않고 UI부분이나 타워가 생성되면

그부분을 막아주기 위해서 새로 배열을 만들어서 값만 받아왔다.




이제 TowerMakeClick 스크립트(아래에 배치된 타워프리팹에 들어있는 스크립트)에서

sign이라는 GameObject 배열을 만들어 거기에 미리 프리팹을 생성하여 위치설정해놓고 active만 false로 해뒀다.

(계속 생성 삭제 반복하는것보다는 active만 껐다 켰다하는게 나을것 같아서)

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
public void MakeSign()
{
    // 격자 생성
    for (int i = 0; i < 260; i++)
    {
        // UI구간 1로 초기화(설치못하게)
        if (i < 40)
        {
            GameObject.FindGameObjectWithTag("InstallManager").GetComponent<TowerMaker>().MakeMap[i] = 1;
        }
 
        // 맵에 따라 yes 또는 no 프리팹을 생성하여 해당 위치에 가져다 놓고 active false
        if (GameObject.FindGameObjectWithTag("InstallManager").GetComponent<TowerMaker>().MakeMap[i] == 1)
        {
            var no = Resources.Load("makeNo"typeof(GameObject)) as GameObject;
            sign[i] = Instantiate(no, transform);
        }
        else
        {
            var yes = Resources.Load("makeYes"typeof(GameObject)) as GameObject;
            sign[i] = Instantiate(yes, transform);
        }
        sign[i].transform.position = new Vector3(TileMaker.startX + i % 20 * 0.64f, TileMaker.startY + i / 20 * 0.64f);
        sign[i].SetActive(false);
    }
}
cs




그리고 드래그를 하면 active를 true로 바꿔 생성가능지역을 보여주고

1
2
3
4
5
6
// 생성가능지역 표시
for (int i=0; i<260; i++)
{
    sign[i].SetActive(true);
    sign[i].GetComponent<SpriteRenderer>().color = new Color(11130.0f / 255.0f);
}
cs




마우스를 떼면 다시 false로 만들어 보이지않게 하였다.

1
2
3
4
5
for(int i=0; i<260; i++)
{
    if(sign[i] != null)
        sign[i].SetActive(false);
}
cs




실행화면

td_grid.mp4





이제 여기서 타워가 설치될 공간을 미리 보여주고 싶어서 

마우스가 움직이면 해당 부분의 격자 알파값을 높이는건 어떨까 생각해봤다.


타워는 2x2의 크기로 만들고 싶어서 마우스포인터를 기준으로 오른쪽위아래, 왼쪽위아래의 4가지 경우를 다 작성했다.

마우스의 포지션을 0.64로 나누어서 int형으로 강제형변환하여 1칸당 1의 원하는 수치로 변경하였고

거기에서 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
// 마우스포지션 기준 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;
 
// 오른쪽
if (mousefX > mouseX + 0.5f)
{
    // 위
    if (mousefY > mouseY + 0.5f)
    {
        sign[mouseY * 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[mouseY * 20 + mouseX + 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY + 1* 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY + 1* 20 + mouseX + 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
    }
    // 아래
    else if (mousefY < mouseY + 0.5f)
    {
        sign[mouseY * 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[mouseY * 20 + mouseX + 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY - 1* 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY - 1* 20 + mouseX + 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
    }
}
// 왼쪽
else if (mousefX < mouseX + 0.5f)
{
    // 위
    if (mousefY > mouseY + 0.5f)
    {
        sign[mouseY * 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[mouseY * 20 + mouseX - 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY + 1* 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY + 1* 20 + mouseX - 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
    }
    // 아래
    else if (mousefY < mouseY + 0.5f)
    {
        sign[mouseY * 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[mouseY * 20 + mouseX - 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY - 1* 20 + mouseX].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
        sign[(mouseY - 1* 20 + mouseX - 1].GetComponent<SpriteRenderer>().color = new Color(1110.5f);
    }
}
cs




실행화면

td_grid2.mp4





이제 마우스를 떼면 해당 위치의 중앙으로 정확하게 설치되고

해당 칸은 배열을 체크해주어 붉은색으로 나타나게. 그리고 붉은 부분은 설치하지 못하도록 막을 것이다.

그부분들은 이후에 구현이 다되면 추가하겠음.

Posted by misty_
,