고양이 나옴 (AR 파운데이션 증강현실 앱 개발 강좌)





ARManager.cs 소스입니다


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.AI;

public class ARManager : MonoBehaviour
{

    void OnEnable()
    {
        arCameraManager.frameReceived += FrameUpdated;
        //arImageManager.trackedImagesChanged += OnTrackedImagesChanged;
    }

    void OnDisable() 
    {
        arCameraManager.frameReceived -= FrameUpdated;
        //arImageManager.trackedImagesChanged -= OnTrackedImagesChanged;
    }

    void Update()
    {
        //PlacePrefab();
        //PlaceIndicator();
        PlayerMove();
    }


    #region 바닥에 프리팹 놓기

    public ARRaycastManager arRaycater;
    public GameObject spawnPrefab;
    List<ARRaycastHit> hits = new List<ARRaycastHit>();

    void PlacePrefab()
    {
        if (Input.touchCount == 0) return;

        Touch touch = Input.GetTouch(0);
        if (touch.phase != TouchPhase.Began) return;

        if (arRaycater.Raycast(touch.position, hits, TrackableType.Planes))
        {
            Pose hitPose = hits[0].pose;
            Instantiate(spawnPrefab, hitPose.position, hitPose.rotation);
        }
    }

    #endregion


    #region 바닥 활성화

    public ARPlaneManager arPlane;

    public void ShowPlane(bool b)
    {
        foreach (var plane in arPlane.trackables)
            plane.gameObject.SetActive(b);
    }

    #endregion


    #region 바닥 표시기

    public Transform Indicator;
    List<ARRaycastHit> indicatorHits = new List<ARRaycastHit>();

    void PlaceIndicator()
    {
        arRaycater.Raycast(new Vector2(Screen.width * 0.5f, Screen.height * 0.5f), indicatorHits, TrackableType.Planes);

        if (indicatorHits.Count > 0)
        {
            Indicator.position = indicatorHits[0].pose.position;
            Indicator.rotation = indicatorHits[0].pose.rotation;
        }
    }

    public void PlaceIndicatorPrefab()
    {
        Pose hitPose = indicatorHits[0].pose;
        Instantiate(spawnPrefab, hitPose.position, hitPose.rotation);
    }

    #endregion


    #region 원점 설정

    public ARSessionOrigin arOrigin;
    List<ARRaycastHit> originHits = new List<ARRaycastHit>();

    public void PlaceOrigin()
    {
        arRaycater.Raycast(new Vector2(Screen.width * 0.5f, Screen.height * 0.5f), originHits, TrackableType.Planes);
        if (originHits.Count > 0)
        {
            Pose hitpose = originHits[0].pose;

            // 괄호안에 들어가는 것이 원점이 된다
            arOrigin.MakeContentAppearAt(arOrigin.transform, hitpose.position, hitpose.rotation);
        }
    }

    #endregion


    #region 빛 감지

    public ARCameraManager arCameraManager;
    public Light currentLight;

    void FrameUpdated(ARCameraFrameEventArgs args)
    {
        var brightness = args.lightEstimation.averageBrightness;

        if (brightness.HasValue)
        {
            bool isBright = brightness.Value > 0.3f;
            float fixBrightness = brightness.Value * 4f;
            currentLight.intensity = fixBrightness;
            print($"밝기 : {brightness.Value} \n빛의 세기 : {fixBrightness} \n밝음 : {isBright}");
        }
    }

    #endregion


    #region 이미지 감지

    public ARTrackedImageManager arImageManager;

    void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs args) 
    {
        List<ARTrackedImage> addedImages = args.added;

        foreach (ARTrackedImage image in addedImages) 
        {
            if (image.referenceImage.name == "R2")
                image.GetComponent<Renderer>().material.color = Color.red;

            else if (image.referenceImage.name == "R3")
                image.GetComponent<Renderer>().material.color = Color.green;
        }
    }

    #endregion


    #region 플레이어를 중심으로 이동

    public NavMeshAgent agent;
    public GameObject TouchParticle;

    public void MoveTarget()
    {
        if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out RaycastHit hit))
        {
            agent.SetDestination(hit.point);
            Destroy(Instantiate(TouchParticle, hit.point, Quaternion.identity), 3);
        }
    }

    void PlayerMove() 
    {
        PlayerPos.playerPos = agent.transform.position;
        arOrigin.transform.position = PlayerPos.playerPos;
        SetMapCenter(PlayerPos.playerPos);
    }

    #endregion


    #region 머테리얼 숨기기

    public Material[] MapMts;

    void Start() => SetMapRadius(40f);
void OnApplicationQuit() => SetMapRadius(float.MaxValue);

void SetMapCenter(Vector3 vec)
    {
        Vector4 myVec = new Vector4(vec.x, vec.y, vec.z, 0);

        for (int i = 0; i < MapMts.Length; i++)
            MapMts[i].SetVector("_Center", myVec);
    }

    void SetMapRadius(float r)
    {
        for (int i = 0; i < MapMts.Length; i++)
            MapMts[i].SetFloat("_Radius", r);
    }

    #endregion
}

public static class PlayerPos
{
    public static Vector3 playerPos;
}













HideObject.cs 소스입니다


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

public class HideObject : MonoBehaviour
{
    WaitForSeconds Delay04 = new WaitForSeconds(0.4f);
    Renderer RR;

    void Start()
    {
        RR = GetComponent<Renderer>();
        StartCoroutine(HideRendererCo());
    }

    IEnumerator HideRendererCo()
    {
        while (true)
        {
            RR.enabled = (PlayerPos.playerPos - transform.position).sqrMagnitude < 2116;
            yield return Delay04;
        }
    }
}