본문 바로가기
개발/Unity

유니티 - [오늘의 집] 오브젝트를 움직일 때 좌표축 만들기 (Line Renderer)

by 피로물든딸기 2022. 4. 16.
반응형

Unity 전체 링크

 

오늘의 집에서 가구를 배치할 때, 오브젝트를 선택하면 오브젝트에 아웃라인이 생기고

움직이게 되면 하얀색 라인이 생기고 최초의 좌표와 움직이는 좌표 사이에도 라인이 생긴다.

 

유니티 라인 렌더러로 이것을 구현해보자.

 

라인 렌더러는 연속적인 선만 그릴 수 있다.

불연속적인 선은 여러 개의 라인 렌더러로 그려야 한다.

 

위의 경우는 x, y, z 축 좌표 → 3개의 라인이 필요하며,

현재 좌표와 다음 좌표를 이을 선 1개 총 4개의 선이 필요하다.

 

빈 오브젝트를 만들고 4개의 빈 오브젝트를 추가한다.

 

Line0~4에 Line Renderer를 추가하고 Width를 적절히 변경한다.

 

블록을 움직이는 스크립트에 LineRenderer 배열을 추가한 후, 설정한다.

 

테스트를 위해 Start에서는 color를 설정한 후, Update에 라인을 그려본다.

    public LineRenderer[] lineRenderer;

    private void Start()
    {
        foreach (LineRenderer lr in lineRenderer)
        {
            lr.enabled = true;
            lr.material.color = Color.red;
        }
    }

    private void Update()
    {
        Vector3[] linePoints = new Vector3[2];

        /* (x, 0, 0) */
        linePoints[0] = this.transform.position + Vector3.right * 100.0f;
        linePoints[1] = this.transform.position + Vector3.left * 100.0f;
        lineRenderer[0].SetPositions(linePoints);

        /* (0, y, 0) */
        linePoints[0] = this.transform.position + Vector3.up * 100.0f;
        linePoints[1] = this.transform.position + Vector3.down * 100.0f;
        lineRenderer[1].SetPositions(linePoints);

        /* (0, 0, z) */
        linePoints[0] = this.transform.position + Vector3.forward * 100.0f;
        linePoints[1] = this.transform.position + Vector3.back * 100.0f;
        lineRenderer[2].SetPositions(linePoints);
    }

 

이제 오브젝트를 움직이면, 아래와 같이 좌표축이 생기는 것을 알 수 있다.


마우스를 클릭했을 때, 모든 라인 렌더러를 enabled = true로 하고, 현재 좌표를 저장한다.

반대로 마우스 클릭이 종료되면 모든 라인렌더러를 끈다.

 

마우스를 드래그할 때 현재 오브젝트의 좌표를 movePoints[1]에 넣고 SetPositions로 라인을 그린다.

    Vector3[] movePoints = new Vector3[2];
    
    private void OnMouseDown()
    {
        foreach (LineRenderer lr in lineRenderer) lr.enabled = true;

        movePoints[0] = this.transform.position;
    }
    
    private void OnMouseUp()
    {
        foreach (LineRenderer lr in lineRenderer) lr.enabled = false;
    }

    private void OnMouseDrag()
    {
        movePoints[1] = this.transform.position;
        lineRenderer[3].SetPositions(movePoints);
    }

 

최초의 지점과 움직이는 점 사이의 선이 역동적으로 생성된다.


마지막으로 오늘의 좌표에서는 x, y, z 축이 최초로 고정이다. 

이것은 Update에서 처리하는 라인 렌더러를 mouseDown으로 옮겨주면 된다.

    private void OnMouseDown()
    {
        foreach (LineRenderer lr in lineRenderer) lr.enabled = true;

        movePoints[0] = this.transform.position;
        movePoints[0].y -= this.transform.position.y;

        Vector3[] linePoints = new Vector3[2];

        /* (x, 0, 0) */
        linePoints[0] = this.transform.position + Vector3.right * 100.0f;
        linePoints[1] = this.transform.position + Vector3.left * 100.0f;
        lineRenderer[0].SetPositions(linePoints);

        /* (0, y, 0) */
        linePoints[0] = this.transform.position + Vector3.up * 100.0f;
        linePoints[1] = this.transform.position + Vector3.down * 100.0f;
        lineRenderer[1].SetPositions(linePoints);

        /* (0, 0, z) */
        linePoints[0] = this.transform.position + Vector3.forward * 100.0f;
        linePoints[1] = this.transform.position + Vector3.back * 100.0f;
        lineRenderer[2].SetPositions(linePoints);
    }
    
    /* Update는 삭제 */

 

전체 코드는 다음과 같다.

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

public class DragAndMove : MonoBehaviour
{
    public LineRenderer[] lineRenderer;
    Vector3[] movePoints = new Vector3[2];

    GameObject objectHitPostion;
    RaycastHit hitRay, hitLayerMask;

    private void OnMouseUp()
    {
        foreach (LineRenderer lr in lineRenderer) lr.enabled = false;

        this.transform.parent = null;
        Destroy(objectHitPostion);
    }

    private void OnMouseDown()
    {
        foreach (LineRenderer lr in lineRenderer) lr.enabled = true;

        movePoints[0] = this.transform.position;

        Vector3[] linePoints = new Vector3[2];

        /* (x, 0, 0) */
        linePoints[0] = this.transform.position + Vector3.right * 100.0f;
        linePoints[1] = this.transform.position + Vector3.left * 100.0f;
        lineRenderer[0].SetPositions(linePoints);

        /* (0, y, 0) */
        linePoints[0] = this.transform.position + Vector3.up * 100.0f;
        linePoints[1] = this.transform.position + Vector3.down * 100.0f;
        lineRenderer[1].SetPositions(linePoints);

        /* (0, 0, z) */
        linePoints[0] = this.transform.position + Vector3.forward * 100.0f;
        linePoints[1] = this.transform.position + Vector3.back * 100.0f;
        lineRenderer[2].SetPositions(linePoints);

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(ray, out hitRay))
        {
            objectHitPostion = new GameObject("HitPosition");
            objectHitPostion.transform.position = hitRay.point;
            this.transform.SetParent(objectHitPostion.transform);
        }
    }

    private void OnMouseDrag()
    {
        movePoints[1] = this.transform.position;
        lineRenderer[3].SetPositions(movePoints);

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction * 1000, Color.green);

        int layerMask = 1 << LayerMask.NameToLayer("Stage");
        if(Physics.Raycast(ray, out hitLayerMask, Mathf.Infinity, layerMask))
        {
            float H = Camera.main.transform.position.y;
            float h = objectHitPostion.transform.position.y;

            Vector3 newPos = (hitLayerMask.point * (H - h) + Camera.main.transform.position * h) / H;

            objectHitPostion.transform.position = newPos;
        }
    }

    private void Start()
    {
        foreach (LineRenderer lr in lineRenderer) lr.material.color = Color.red;
    }
}

 

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

반응형

댓글