본문 바로가기
개발/Unity

유니티 - Line Renderer로 게임 오브젝트끼리 연결하기 (연결 선 그리기)

by 피로물든딸기 2022. 3. 12.
반응형

Unity 전체 링크

 

참고

- OpenGL로 화면에 선 그리기

 

Debug.DrawRay는 디버깅용이기 때문에 실제 게임 화면에서는 보이지 않는다.

게임 화면에서 선을 그리기 위해서는 라인 렌더러(Line Renderer)가 필요하다.

 

오브젝트를 클릭해서, 다른 오브젝트로 연결할 수 있도록 해보자.

먼저 연결을 시작할 오브젝트에 스크립트와 라인 렌더러를 추가한다.

오브젝트를 클릭하기 때문에 콜라이더가 있어야 한다. 

 

라인 렌더러를 추가하면 아래와 같이 라인이 생긴다.

라인 렌더러는 오브젝트를 이동시켜도 같이 움직이지 않는다.

매번 어떻게 그릴지 스크립트로 정해야한다.

 

따라서 최초에 enabled = false로 주어서 미리 꺼둔다. 

그리고 원하는 색, width 등을 설정한다.

linePoints에 대해서는 아래에 다시 설명한다.

    private float lineWidth = 0.01f;
    private LineRenderer lr;
    private Vector3[] linePoints = new Vector3[2];

    public GameObject connectedProduct;
    private RaycastHit hit;

    void Start()    
    {
        lr = GetComponent<LineRenderer>();
        lr.enabled = false; 
        lr.material.color = Color.blue;
        lr.widthMultiplier = lineWidth; 
        linePoints[0] = transform.position; /* 첫번째 점의 위치는 gameobject */
        lr.positionCount = linePoints.Length;
    }

 

먼저 Update에서 마우스가 클릭된 상태인 경우 아래와 같이 만든다.

클릭된 위치를 WorldPoint로 변경하고, z 축은 카메라와 가까운 지점으로 설정한다.

그리고 linePoints[1]에 mouse로 잡은 위치를 넣고, 라인 렌더러의 SetPosition 메서드에 position을 set 한다.

        if(Input.GetMouseButton(0))
        {
            lr.enabled = true;

            linePoints[1] = Camera.main.ScreenToWorldPoint(new Vector3(
                Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));
            lr.SetPositions(linePoints);
        }

 

Start에서 linePoints[0]이 오브젝트의 현재 위치였으므로, 

아래와 같이 클릭한 위치와 현재 오브젝트까지 라인을 그리게 된다. 

만약 사각형을 그린다면 linePoint[3]까지 설정하면 된다.

 

그러나 현재 오브젝트 바깥의 화면을 터치해도 라인이 생기고 있다. 

따라서 OnMouse 함수를 이용하여 오브젝트 클릭 후 드래그를 하도록 코드를 수정한다.

    private bool mouseButton = false;

    private void OnMouseDown()
    {
        mouseButton = true;
    }
    
    ...
    
    void Update()
    {
        if (mouseButton)
        {
            lr.enabled = true;

            linePoints[1] = Camera.main.ScreenToWorldPoint(new Vector3(
                Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));

            lr.SetPositions(linePoints);
        }
    }

 

이제 마우스를 뗄 경우 로직을 처리한다. 순서대로 설명하면 아래와 같다.

 

- mouseButton을 false로 처리하여 Update에서 라인을 더 이상 그리지 않도록 한다.

- 라인 렌더러를 끈다.

- 마우스를 향해 레이케이스를 그린다.

  → 레이캐스트 hit이 다른 오브젝트라면 connectProduct에 할당한다.

  → 연결이 성공한 경우이므로 lr.enabled = true로 하여 라인을 그린다.

 

  → 레이캐스트 hit이 자신인 경우는 아무 행동도 하지 않는다.

 

  → 레이캐스트 hit이 null이라면 connectProduct에 다시 null을 할당한다.

    private void OnMouseUp()
    {
        mouseButton = false;
        lr.enabled = false;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider.gameObject != this.gameObject)
            {
                connectedProduct = hit.collider.gameObject;

                Debug.Log(hit.collider.gameObject.name + " is connected");

                lr.enabled = true;
                
                return;
            }

            if (hit.collider.gameObject == this.gameObject)
            {
                if (connectedProduct == null) return;
            }
        }

        connectedProduct = null; /* 빈 공간 hit */
        Debug.Log("failed to connect");
    }

 

이제 다시 게임을 실행해보자.

오브젝트와 오브젝트가 연결된 것 같지만, 실제로 카메라를 움직여보면 선이 연결되어 있지 않다.

 

따라서 연결된 오브젝트를 찾으면 line을 hit과 연결해주는 코드를 추가한다.

    if(hit.collider.gameObject != this.gameObject)
    {
        connectedProduct = hit.collider.gameObject; 

        Debug.Log(hit.collider.gameObject.name + " is connected");

        lr.enabled = true;
        
        /* 선택된 오브젝트에 라인 연결 */
        linePoints[1] = hit.collider.gameObject.transform.position;
        lr.SetPositions(linePoints);

        return;
    }

 

이제 카메라를 움직여보면 실제로 오브젝트와 오브젝트가 연결된 것을 알 수 있다.

스크립트 - Connected Product에도 올바르게 오브젝트들이 연결되거나 끊어지는 것을 볼 수 있다.

 

최종 코드는 아래와 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LinkedObject : MonoBehaviour
{
    private float lineWidth = 0.01f;
    private LineRenderer lr;
    private Vector3[] linePoints = new Vector3[2];

    public GameObject connectedProduct;
    private RaycastHit hit;

    private bool mouseButton = false;

    private void OnMouseDown()
    {
        mouseButton = true;
    }

    private void OnMouseUp()
    {
        mouseButton = false;
        lr.enabled = false;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider.gameObject != this.gameObject)
            {
                connectedProduct = hit.collider.gameObject;

                Debug.Log(hit.collider.gameObject.name + " is connected");

                lr.enabled = true;

                /* 선택된 오브젝트에 라인 연결 */
                linePoints[1] = hit.collider.gameObject.transform.position;
                lr.SetPositions(linePoints);

                return;
            }

            if (hit.collider.gameObject == this.gameObject)
            {
                if (connectedProduct == null) return;
            }
        }

        connectedProduct = null; /* 빈 공간 hit */
        Debug.Log("failed to connect");
    }

    void Start()
    {
        lr = GetComponent<LineRenderer>();
        lr.enabled = false;
        lr.material.color = Color.blue;
        lr.widthMultiplier = lineWidth;
        linePoints[0] = transform.position; /* 첫번째 점의 위치는 gameobject */
        lr.positionCount = linePoints.Length;
    }

    void Update()
    {
        if (mouseButton)
        {
            lr.enabled = true;

            linePoints[1] = Camera.main.ScreenToWorldPoint(new Vector3(
                Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));

            lr.SetPositions(linePoints);
        }
    }
}

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글