【问题标题】:How to use Unity ARKit to activate objects in scene rather than prefabs如何使用 Unity ARKit 激活场景中的对象而不是预制件
【发布时间】:2021-12-10 14:31:13
【问题描述】:

我有一些游戏对象,我使用 Unity 中的 ARKit 将它们与不同的标记相关联。这些游戏对象目前是预制件,但数量有限,而且每一个都是独一无二的。如果预制件是场景中的非活动游戏对象,当设备摄像头识别标记时变为活动状态,这将更有意义。有没有办法更改下面的代码以使游戏对象设置为活动而不是实例化预制件?

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

[RequireComponent(typeof(ARTrackedImageManager))]

public class ImageTracking : MonoBehaviour
{

    [SerializeField]
    private GameObject[] placeablePrefabs;

    private Dictionary<string, GameObject> spawnedPrefabs = new Dictionary<string, GameObject>();
    private ARTrackedImageManager trackedImageManager;

    private void Awake()
    {
        trackedImageManager = FindObjectOfType<ARTrackedImageManager>();

        foreach(GameObject prefab in placeablePrefabs)
        {
            GameObject newPrefab = Instantiate(prefab, Vector3.zero, Quaternion.identity);
            newPrefab.name = prefab.name;
            spawnedPrefabs.Add(prefab.name, newPrefab);
        }
    }

    private void OnEnable()
    {
        trackedImageManager.trackedImagesChanged += ImageChanged;
    }

    private void OnDisable()
    {
        trackedImageManager.trackedImagesChanged -= ImageChanged;
    }

    private void ImageChanged(ARTrackedImagesChangedEventArgs eventArgs)
    {
        foreach(ARTrackedImage trackedImage in eventArgs.added)
        {
            UpdateImage(trackedImage);
        }
        foreach (ARTrackedImage trackedImage in eventArgs.updated)
        {
            UpdateImage(trackedImage);
        }
        foreach (ARTrackedImage trackedImage in eventArgs.removed)
        {
            spawnedPrefabs[trackedImage.name].SetActive(false);
        }
    }

    private void UpdateImage(ARTrackedImage trackedImage)
    {
        string name = trackedImage.referenceImage.name;
        Vector3 position = trackedImage.transform.position;

        GameObject prefab = spawnedPrefabs[name];
        prefab.transform.position = position;
        prefab.SetActive(true);

        foreach(GameObject go in spawnedPrefabs.Values)
        {
            if(go.name != name)
            {
                go.SetActive(false);
            }
        }
    }
}

【问题讨论】:

    标签: c# unity3d augmented-reality arkit


    【解决方案1】:

    因此,无需预制件,只需将场景中的所有现有对象都引用到 placeablePrefabs(当然以后再更改该名称!)然后做

    [SerializeField]
    private GameObject[] showAbleObjects;
    
    private Dictionary<string, GameObject> nameToGameObject = new Dictionary<string, GameObject>();
    
    private void Awake()
    {
        trackedImageManager = FindObjectOfType<ARTrackedImageManager>();
    
        foreach(var obj in showAbleObjects)
        {
            nameToGameObject.Add(obj.name, obj);
        }
    }
    

    您甚至可以考虑使用一些免费资产,例如SerializableDictionary 并直接通过 Inspector 完成所有操作。

    【讨论】:

    • 效果很好!我更改了一些不再需要的其他行,当然还有命名约定。谢谢你,derHugo。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多