[Unity] Electricity (2)

suhan0304·2024년 5월 1일

유니티-Electricity

목록 보기
2/18
post-thumbnail

BuildManager에서 Block을 가져다가 건설할 수 있도록 Block Script를 생성해준 다음에 Node에 onMouseDown 이벤트를 작성해보자. 작성하면서 변수들도 어느정도 정리를 해주어 인스펙터에서 쉽게 어떤 변수인지 파악할 수 있도록 해주었다.

Node.cs

using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public class Node : MonoBehaviour
{
    [Header("Height")]
    [SerializeField]
    private float nodeHeight = 0; // to calculate buildBlock Position
    private float blocksTotalHeight = 0; // total of blocks height on node

    [Space(10)]
    [Header("Colors")]
    [SerializeField]
    public Color hoverColor; // color changes when mouse is hovered over

    private Renderer rend; // renderer component
    private Color startColor;  // start color

    [Space(10)]
    [Header("Block On Node")]
    [SerializeField]
    private GameObject blockOnNode; // Block Object ( built on node )

    private void Start()
    {
        nodeHeight = transform.localScale.y / 2; // half of node height - for build
        rend = GetComponent<Renderer>(); // call renderer component
        startColor = rend.material.color; // remember start color
    }

    private void OnMouseEnter() // When the mouse passes or enters an object collider
    {
        rend.material.color = hoverColor; // change color to hoverColor
    }

    private void OnMouseExit() // When the mouse leaves the object collider
    {
        rend.material.color = startColor; // return color to startColor
    }

    private void OnMouseDown() //When the mouse click the object collider
    {
        // Build a Block
        BuildBlockOnNode();
    }


    /// <summary>
    /// Build Block On Node
    /// - The buildManager holds information about the blocks the player has chosen to build.
    /// </summary>
    private void BuildBlockOnNode()
    {
        GameObject blockBuild = BuildManager.instance.GetBlockToBuild();

        float blockHeight = blockBuild.transform.localScale.y;
        blockOnNode = (GameObject)Instantiate(blockBuild, new Vector3(
            transform.position.x,                                                       // Build Position - Vector.x 
            transform.position.y + nodeHeight + blocksTotalHeight +  blockHeight,      // Build Position - Vector.y
            transform.position.z),                                                      // Build Position - Vector.z 
            transform.rotation);

        blocksTotalHeight += blockHeight; // Update blocksTotalHeights ( add block height )

        Debug.Log("Build the Block!");
    }
}

여기서 중요한 점은 블럭을 위로 계속 쌓을 수 있도록 초기 높이값을 지정해주었다. 나중에 Rigidbody 쓸 수 있는데 그러면 어느 정도 높이 위에서 생성한 후 물리 법칙 적용 시켜서 중력으로 떨어지게 하면 저런 높이 계산 과정을 모두 삭제해도 되지만 일단 지금은 Block에 Rigidbody를 추가하게 된다면 그 때 적용시키자.

초기 높이값을 설정해주면 해당 높이에 맞게 Block을 Build 해주고 Node에 지어진 블럭들의 총 높이 변수인 blocksTotalHeight을 늘려줘서 다음 블럭을 지으면 현재 블록의 위에 지어지도록 해준다.

뭔가 이상하다. 초기 높이 값 설정이 좀 이상한거 같은데 한번 확인해보자.

transform.position.y + nodeHeight + blocksTotalHeight + blockHeight

block의 Position은 block의 가운데를 기준으로 결정되기 때문에 blockHeight을 2로 나누어서 더해주어야한다.

transform.position.y + nodeHeight + blocksTotalHeight + (blockHeight/2)

원하는 그림이 나왔다. 막상 Block을 Build하고 나니깐 가시성이 좀 떨어지는점 2가지 있는데

1. 그냥 Instantiate하다 보니깐 "standardBlock(Clone)"이 그냥 아래로 계속해서 생성된다는 점

2. 블럭이 몇 개 쌓여있는지 확인하기 어려운점

먼저 1번을 해결보자. 생성할 때 누른 노드의 자식 오브젝트로 생성되게 해서 Hierarchy가 좀 정돈된 형태로 유지되도록 하고 나중에 노드를 삭제할 일이 생기면 그 위에 쌓여있는 블럭들도 같이 삭제가 될 수 있도록 해보자.

        blockOnNode = (GameObject)Instantiate(blockBuild, new Vector3(
            transform.position.x,                                                       // Build Position - Vector.x 
            transform.position.y + nodeHeight + blocksTotalHeight +  (blockHeight/2),   // Build Position - Vector.y
            transform.position.z),                                                      // Build Position - Vector.z 
            transform.rotation,
            transform);

마지막에 transform을 넣어서 node를 부모 오브젝트로 수정해준다.

자식 오브젝트로 들어가면서 scale에 문제가 발생했다.

        blockOnNode = (GameObject)Instantiate(blockBuild, new Vector3(
            transform.position.x,                                                       // Build Position - Vector.x 
            transform.position.y + nodeHeight + blocksTotalHeight +  (blockHeight/2),   // Build Position - Vector.y
            transform.position.z),                                                      // Build Position - Vector.z 
            transform.rotation);

        blockOnNode.transform.SetParent(transform, true); // set Parent

transform.setParent를 써서 기존 오브젝트의 scale을 유지시켜주도록 한다.

worldPositionStays란 bool 인자가 참일 경우 개체가 이전과 동일한 월드 위치, 각도, 스케일을 유지하도록 부모오브젝트와 관계에 의해 상대적으로 수정된다.

Block이 정상 사이즈로 잘 생성되는 것을 확인할 수 있다. Block을 나중에 기회가 된다면 제작할 예정이지만 일단은 가시성을 높이기 위해 기존 standardBlock을 Cube 오브젝트 1개가 아니라 3개로 다시 제작해서 각 부분별로 다른 Material을 적용시켜서 여러 블럭을 Build해서 올렸을때 개수를 쉽게 파악할 수 있도록 했다. ( 개수를 알아야 어느 정도 높이를 알고 이를 이용한 z 축 플레이가 가능해질 것이라고 생각했다 )

이제 여러개 건설을 해보면 아래처럼 몇개를 쌓아올렸는지 플레이어 입장에서 쉽게 구별할 수 있다.


추후 계획

일단 여러 노드를 여러개 바닥에 깔아놓은 다음에 start와 end Point를 추가할 예정이다. 그리고 카메라 뷰를 키보드를 이용해서 제어할 예정이다. 마우스를 게임 창의 가장자리로 가져갔을때 카메라의 움직임을 추가할지 말지는 실제로 테스트해보고 좀 불편하다 싶으면 키보드로만 카메라 회전 이동 제어를 사용할 예정이다.

일단은 Node들을 이용해 맵을 구성하게 될텐데 카메라가 해당 맵 가운데를 중심으로 어느정도 높이에서 원 형태로 움직이도록 구현할 예정이다.

profile
Be Honest, Be Harder, Be Stronger

0개의 댓글