Unity 2022.3.5f1 Google VR Cardboard - 03

VR/Google Cardboard VR (GVR) 2023. 9. 15. 16:25
반응형

지정된 경로를 따라서 이동하는 로직 

 

레퍼런스 게임 : 지정된 웨이포인트를 따라서 움직이며 헤드트래킹으로 조준해서 암세포를 죽이는 방식의 게임 

 

https://play.google.com/store/apps/details?id=com.nivalvr.inmind&hl=en_US&pli=1 

 

InMind VR (Cardboard) - Apps on Google Play

InMind is a short adventure with arcade elements designed for the Cardboard VR

play.google.com

 

WayPointGroup 빈 오브젝트 생성 

 

자식으로 빈오브젝트 (Point)를 만들어 준다 

콜라이더를 부착 하고 IsTrigger체크를 해준다 

 

 

 

WayPoint 태그를 추가 해준다 

 

Point를 선택하고 태그를 설정 한다 

 

총 11개가 되도록 Point를 복사 생성한다 

 

스크립트 작성 

MoveCtrl 스크립트를 만들어 작성하고 Player에 부착 한다 

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class MoveCtrl : MonoBehaviour
{
    public enum eMoveType
    {
        WAY_POINT,
        LOOK_AT
    }

    public eMoveType moveType = eMoveType.WAY_POINT;    //이동방식 
    public float speed = 1.0f;  //이동속도
    public float damping = 3.0f;    //회전 속도

    [SerializeField] private Transform[] points;

    private int nextIdx = 1;    //다음에 이동해야할 인덱스 
    
    void Start()
    {
        GameObject wayPointGroup = GameObject.Find("WayPointGroup");
        if (wayPointGroup != null)
        {
            this.points = wayPointGroup.GetComponentsInChildren<Transform>();
        }
    }
    
    void Update()
    {
        switch (this.moveType)
        {
            case eMoveType.WAY_POINT:
                this.MoveWayPoint();
                break;
            case eMoveType.LOOK_AT:
                break;
        }
    }

    private void MoveWayPoint()
    {
        Vector3 dir = this.points[this.nextIdx].position - this.transform.position;
        Quaternion rot = Quaternion.LookRotation(dir);
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rot, Time.deltaTime * damping);
        this.transform.Translate(Vector3.forward * Time.deltaTime * this.speed);
    }

    void OnTriggerEnter(Collider col)
    {
        if (col.CompareTag("WayPoint"))
        {
            //this.nextIdx = (++nextIdx >= points.Length) ? 1 : nextIdx;
            this.nextIdx = (nextIdx + 1) % points.Length;
        }
    }
}

 

 

 


 

 

 

바라보는 시선으로 이동하는 로직 

스테이지에 콜라이더 부착 

 

스크립트 수정 및 추가 

 

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class MoveCtrl : MonoBehaviour
{
    public enum eMoveType
    {
        WAY_POINT,
        LOOK_AT
    }

    public eMoveType moveType = eMoveType.WAY_POINT;    //이동방식 
    public float speed = 1.0f;  //이동속도
    public float damping = 3.0f;    //회전 속도

    [SerializeField] private Transform[] points;

    private int nextIdx = 1;    //다음에 이동해야할 인덱스 


    private CharacterController controller;
    private Transform camTrans;
    
    void Start()
    {
        GameObject wayPointGroup = GameObject.Find("WayPointGroup");
        if (wayPointGroup != null)
        {
            this.points = wayPointGroup.GetComponentsInChildren<Transform>();
        }

        this.controller = this.GetComponent<CharacterController>();
        this.camTrans = Camera.main.GetComponent<Transform>();
    }
    
    void Update()
    {
        switch (this.moveType)
        {
            case eMoveType.WAY_POINT:
                this.MoveWayPoint();
                break;
            case eMoveType.LOOK_AT:
                this.MoveLookAt(1);
                break;
        }
    }

    private void MoveLookAt(int facing)
    {
        Vector3 heading = this.camTrans.forward;
        heading.y = 0.0f;
        Debug.DrawRay(this.transform.position, heading.normalized * 1.0f, Color.red);
        this.controller.SimpleMove(heading * this.speed * facing);
    }

    private void MoveWayPoint()
    {
        Vector3 dir = this.points[this.nextIdx].position - this.transform.position;
        Quaternion rot = Quaternion.LookRotation(dir);
        this.transform.rotation = Quaternion.Slerp(this.transform.rotation, rot, Time.deltaTime * damping);
        this.transform.Translate(Vector3.forward * Time.deltaTime * this.speed);
    }

    void OnTriggerEnter(Collider col)
    {
        if (col.CompareTag("WayPoint"))
        {
            //this.nextIdx = (++nextIdx >= points.Length) ? 1 : nextIdx;
            this.nextIdx = (nextIdx + 1) % points.Length;
        }
    }
}
private void MoveLookAt(int facing)

facing이 1일경우 전진, -1일경우 후진

 

 

 

 


리펙토링 버전 

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

public class MoveCtrl : MonoBehaviour
{
    public enum MoveType
    {
        WayPoint,
        LookAt
    }

    public MoveType moveType = MoveType.WayPoint; // 이동 방식
    public float speed = 1.0f; // 이동 속도
    public float damping = 3.0f; // 회전 속도

    [SerializeField] private Transform[] points;

    private int nextIdx = 1; // 다음에 이동해야 할 인덱스

    private CharacterController controller;
    private Transform camTrans;

    private void Start()
    {
        FindWayPoints(); // WayPointGroup를 찾고 포인트를 가져옴
        GetReferences(); // 컨트롤러 및 카메라 참조 가져오기
    }

    private void Update()
    {
        switch (moveType)
        {
            case MoveType.WayPoint:
                MoveWayPoint();
                break;
            case MoveType.LookAt:
                MoveLookAt(1);
                break;
        }
    }

    private void FindWayPoints()
    {
        GameObject wayPointGroup = GameObject.Find("WayPointGroup");
        if (wayPointGroup != null)
        {
            points = wayPointGroup.GetComponentsInChildren<Transform>();
        }
    }

    private void GetReferences()
    {
        controller = GetComponent<CharacterController>();
        camTrans = Camera.main.GetComponent<Transform>();
    }

    private void MoveLookAt(int facing)
    {
        Vector3 heading = camTrans.forward;
        heading.y = 0.0f;
        Debug.DrawRay(transform.position, heading.normalized * 1.0f, Color.red);
        controller.SimpleMove(heading * speed * facing);
    }

    private void MoveWayPoint()
    {
        Vector3 dir = points[nextIdx].position - transform.position;
        Quaternion rot = Quaternion.LookRotation(dir);
        transform.rotation = Quaternion.Slerp(transform.rotation, rot, Time.deltaTime * damping);
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
    }

    private void OnTriggerEnter(Collider col)
    {
        if (col.CompareTag("WayPoint"))
        {
            // 다음 인덱스 계산을 수정
            nextIdx = (nextIdx + 1) % points.Length;
        }
    }
}

https://docs.unity3d.com/ScriptReference/Component.GetComponentsInChildren.html

 

Unity - Scripting API: Component.GetComponentsInChildren

The typical usage for this method is to call it from a MonoBehaviour script (which itself is a type of component), to find references to other Components or MonoBehaviours attached to the same GameObject as that script, or its child GameObjects. In this ca

docs.unity3d.com

GetComponentInChildren, GetComponentsInChildren

두 메서드는 모두 자식 객체 중 특정 컴포넌트를 추출하는 기능을 한다.



GetComponentInChildren 

자식 객체 중 지정한 컴포넌트 하나만 추출하는데,

자식 객체가 여러 개라면 TransformSort 기준으로 가장 상위에 있는 자식객체의 컴포넌트를 추출한다.



GetComponentsInChildren 

자식 객체들에게서 지정한 컴포넌트를 모두 추출한다.

데이터가 여러 개라서 배열(Array)형태로 추출한다.

**참고로 부모객체인 자신의 컴포넌트까지 포함해서 추출하므로 주의할 것.
void Start()
    {
        GameObject wayPointGroup = GameObject.Find("WayPointGroup");
        // if (wayPointGroup != null)
        // {
        //     this.points = wayPointGroup.GetComponentsInChildren<Transform>();
        // }
        Transform[] childTransforms = wayPointGroup.GetComponentsInChildren<Transform>();
        List<Transform> childList = new List<Transform>(childTransforms);
        childList.Remove(wayPointGroup.transform); // WayPointGroup의 Transform 제거
        this.points = childList.ToArray();


        this.controller = this.GetComponent<CharacterController>();
        this.camTrans = Camera.main.GetComponent<Transform>();
    }

 


 

 

실행후 결과를 확인 하자 

반응형
: