본문 바로가기
개발/Unity

유니티 - 스크립트로 오브젝트 이동하기, RayCast로 멈추기 (1)

by 피로물든딸기 2022. 2. 21.
반응형

Unity 전체 링크

 

오브젝트를 아래로 떨어트려보자.

여기에서는 물리연산이 아니라 스크립트로 물체를 이동한다.

그리고 일정 간격 단위로만 움직인다고 가정한다. 

 

먼저 단순히 아래로 블럭을 움직이는 코드는 Translate를 이용하면 된다.

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

public class BlockMove : MonoBehaviour
{
    public float speed = GlobalManager.BLOCK_DOWN_SPEED;//Player의 이동 속도

    // Update is called once per frame
    void Update()
    {
        transform.Translate(0, -Time.deltaTime * speed, 0);
    }
}

 

참고로 Global 변수는 static 키워드를 이용해서 관리할 수 있다.

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

public class GlobalManager : MonoBehaviour
{
    //public static GlobalManager Instance = null;

    public static float BLOCK_DOWN_SPEED = 25.0f;
}

이제 RayCast를 이용하여 블럭 아래에 블럭이 있는 경우 멈춰보자.

매번 Update마다 RayCast를 호출하면 부하가 커지기 때문에, 블럭과 충돌이 발생하는 경우에만 RayCast를 호출하자.

 

먼저 Block 아래의 Ground를 적당히 잡는다. 여기에서는 100 x 100 x 100 Cube로 잡았다.

 

 

그리고 Box Collider와 Rigidbody를 추가한다.

물리적인 충돌 효과는 발생하지 않고, 영역 감지 역할만 필요하므로 Collider의 Is Trigger체크한다.

스크립트로만 움직이기 때문에 Rigidbody에서 Use Gravity해제한다.

 

마찬가지로 움직이는 Block에도 Collider + Is Trigger 체크, Rigidbody + Use Gravity 체크 해제를 한다.

그리고 여기서는 Sphere Collider를 이용한다.

Radius가 0.75정도 되면 블럭전체가 공 안에 들어온다.

 

script를 아래와 같이 수정한다.

- 오브젝트는 move가 true인 경우만 움직인다.

- OnTriggerEnter로 충돌이 감지되면, 아래로 Ray를 쏜다.

- Ray를 쏴서 뭔가(Ground)가 있으면 멈춘다.

- Ray가 제대로 나오는지 확인하기 위해 Update에 Debug.DrawRay로 선을 그려둔다.

public class BlockMove : MonoBehaviour
{
    public bool move = true;
    public float speed = GlobalManager.BLOCK_DOWN_SPEED;//Player의 이동 속도
    private RaycastHit hit;
    Vector3 blockDown = Vector3.down;
    public float rayLength = 1.0f;

    void Update()
    {
        if (move) transform.Translate(0, -Time.deltaTime * speed, 0);

        Debug.DrawRay(transform.position, blockDown * rayLength, Color.red);
    }

    private void OnTriggerEnter(Collider col)
    {
        if (Physics.Raycast(transform.position, blockDown, out hit, rayLength))
        {
            move = false;
            Debug.Log("point " + hit.point + "/ distance " + hit.distance + "/ name " + hit.collider.name);
        }
    }
}

위의 RayCast는 (오브젝트의 현재 위치, Ray를 쏠 방향, Ray가 검출한 오브젝트, Ray의 길이)를 넘겨서 작동한다.

 

이때 Collider + RayCast로 오브젝트를 이동시키기 때문에 적정한 Collider의 크기와 Ray의 길이를 직접 찾아야한다.

Ray가 너무 길면 Ground보다 훨씬 위에 멈출 것이고, 너무 짧으면 Ground 아래에 멈추게 된다.

그리고 Collider보다 Ray가 짧으면 충돌은 감지하지만 Ray가 블럭을 얻지 못한다.

콜라이더의 반지름이 0.75이기 때문에, RayCast는 1.0f로 잡아서 Collider보다 조금 크게 잡았다.

RayCast는 오브젝트의 중심에서 발사한다.

 

이제 게임을 실행해보자.

Ground를 만나면 move가 false가 된다. 그리고 translate도 동작하지 않는다.

하지만 Ground보다 아래에서 멈추는 문제가 발생한다. Collider가 충돌하는 순간 RayCast가 생기기 때문이다.

따라서 정확한 Y 지점에 멈추도록 코드를 추가해야 한다.

여기서는 블럭이 정확히 Y = 0에 멈춰야한다.

 

블럭이 적절한 위치에 멈추는 것은 다음 글에서 알아보자.

 

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

반응형

댓글