AR 콘텐츠 기초

[AR Foundation] 자동차 터치 스와이프로 모델링 회전, 스마트폰에서 앱 실행 중에 꺼짐 방지, ScrollView, Content, 자동차 색 변경, 자동차 색 변경 시 위치 안따라오기

다모아 2023. 11. 2. 11:59

shfit + alt

Cell은 이미지

ScrollView에 추가

 

Show Mask Graphic 체크 해제하면 옆에 하얀색 없어짐

 

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

[RequireComponent(typeof(Button))]
public class CellButton : MonoBehaviour
{
    public enum eColor
    {
        Yellow, Blue, Red, Black, Purple
    }

    [SerializeField] private eColor color;
    [SerializeField] private Button btn;

}

 

알아서 컴포넌트를 추가

 

CarManager에 추가

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class CarManager : MonoBehaviour
{
    [SerializeField] private Material[] colorMaterials;
    [SerializeField] private GameObject canvasGo;
    [SerializeField] private GameObject indicatorGo;
    [SerializeField] private CellButton[] cellButtons;
    [SerializeField] private float relocationDistance = 1.0f;
    [SerializeField] private ARRaycastManager arManager;
    [SerializeField] private GameObject carPrefab;
    
    private GameObject carGo;

    // Start is called before the first frame update
    void Start()
    {
        this.indicatorGo.SetActive(false);

        this.canvasGo.SetActive(false);
        foreach(var cellButton in cellButtons)
        {
            cellButton.onClick = (color) =>
            {
                this.ChangeColor(color);
            };
        }
    }

    private void ChangeColor(CellButton.eColor color)
    {
        Material mat = this.colorMaterials[(int)color];
        Transform body = this.carGo.transform.Find("Body");
        MeshRenderer meshRenderer = body.GetComponent<MeshRenderer>();
        meshRenderer.material = mat;
    }

    // Update is called once per frame
    void Update()
    {
        this.DetectGround();

        if(EventSystem.current.currentSelectedGameObject)
        {
            Debug.Log(EventSystem.current.currentSelectedGameObject);
            return;
        }

        if(this.indicatorGo.activeInHierarchy && Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            if(touch.phase == TouchPhase.Began)
            {
                if(this.carGo == null)
                {
                    this.carGo = Instantiate(this.carPrefab, this.indicatorGo.transform.position, this.indicatorGo.transform.rotation);

                    //Show UI
                    this.canvasGo.SetActive(true);
                }
                else
                {
                    float distance = Vector3.Distance(this.carGo.transform.position, this.indicatorGo.transform.position);
                    if(distance > this.relocationDistance)
                    {
                        this.carGo.transform.SetPositionAndRotation(indicatorGo.transform.position, indicatorGo.transform.rotation);
                    }
                }
            }
        }
    }

    private void DetectGround()
    {
        Vector2 screenSize = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); // 스크린의 중앙
        List<ARRaycastHit> hitInfos = new List<ARRaycastHit>();
        if(this.arManager.Raycast(screenSize, hitInfos, TrackableType.Planes))
        {
            this.indicatorGo.SetActive(true);
            this.indicatorGo.transform.position = hitInfos[0].pose.position; // world
            this.indicatorGo.transform.rotation = hitInfos[0].pose.rotation;

            this.indicatorGo.transform.position += this.indicatorGo.transform.up * 0.1f;
        }
        else
        {
            this.indicatorGo.SetActive(false);
        }
    }
}

 

 


터치 스와이프로 모델링 회전하기

 

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

public class CarController : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);

            if(touch.phase == TouchPhase.Moved)
            {

            }
        }
    }
}

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

public class CarController : MonoBehaviour
{
    [SerializeField] private float rotSpeed = 0.1f;

    // Update is called once per frame
    void Update()
    {
        if(Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);

            if(touch.phase == TouchPhase.Moved)
            {
                Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
                RaycastHit hitInfo;

                if(Physics.Raycast(ray, out hitInfo, Mathf.Infinity, 1 << 6))
                {
                    Vector3 deltaPos = touch.deltaPosition;

                    this.transform.Rotate(this.transform.up, deltaPos.x * -1.0f * this.rotSpeed);
                }
            }
        }
    }
}

 


스마트폰에서 앱 실행 중에 꺼짐 방지

https://docs.unity3d.com/ScriptReference/Screen-sleepTimeout.html

 

Unity - Scripting API: Screen.sleepTimeout

Most useful for handheld devices, allowing OS to preserve battery life in most efficient ways. Does nothing on non-handheld devices. sleepTimeout is measured in seconds. The default value varies from platform to platform, generally being non-zero. On mobil

docs.unity3d.com

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

public class NoneSleepMode : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Screen.sleepTimeout = SleepTimeout.NeverSleep;
    }
}