猿问

从 assetBundle 加载的 Prefab 是否可以传递给 Vuforia Anchor

目标是一个两步过程,其中从 AssetBundle 加载 Vuforia GroundPlane 对象的预制件,并将其传递到 AnchorBehavior 变量声明以放置游戏对象。


如果作为 Unity C# 的新手,我没有达到我想要的准确程度,我深表歉意


尝试了各种方法将加载的预制件等同于 AnchorBehavior。但因为这是两种类型的对象,所以会发生错误,表明它们不能隐式相等


声明如下:


public PlaneFinderBehaviour plane;

public ContentPositioningBehaviour planeFinder;

public AnchorBehaviour model;

public string nameOfAssetBundle;

public string nameOfObjectToLoad;

想法是传递代表预制件的“nameOfObjectToLoad”并将其传递给“AnchorBehavior”值,然后当脚本附加到按钮时可以使用以下方法“onClick”。


public void create()

{

    planeFinder.AnchorStage = model.GetComponent<AnchorBehaviour>();

}

期望预制件将传递给 AnchorBehavior 并实例化预制件“onClick”


这是从中提取这些片段的完整脚本。

进一步的研究暴露了我的新手技能。“model = loadAsset;”的最终意图 是我试图直接从一种数据类型转换为另一种数据类型,这是无法明确完成的。但到目前为止,我的研究还没有找到从 AssetBundle 中获取加载的 Prefab 并将其提供给 AnchorBehaviour 变量的方法。


如果有人对这种数据类型之间的转换方法有任何经验,我们非常感谢您的指导。


更新 通过正确转换声明,消除了转换错误。


model = (asset.asset as AnchorBehaviour);


但现在我有一个 NullReference 错误,表明我未能在这一行中正确声明该值


    {

        planeFinder.AnchorStage = model.GetComponent<AnchorBehaviour>();

    }

现在这是我的新困境,因为我不确定我在哪里未能正确声明变量。


更新 当 AnchorBehaviour 变量设置为私有时,此错误得到解决。因此,现在脚本可以编译,但无法产生预期的结果。这可能表明需要更改加载 AssetBundle 组件的方式,如 IEnumerator 部分中所述。Unity 控制台打印出以下日志注释


There is no content to place at the anchor. Set the "Anchor Stage" field to the content you wish to place.

UnityEngine.Debug:LogError(Object)

在所有建议之后,这是最新的脚本,不幸的是它没有放置 AssetBundle 中的内容。我可以看到更多的研究和测试。


翻阅古今
浏览 104回答 1
1回答

守候你守候我

查看AssetBundle.LoadAssetAsync在 5.0 版本之前,用户可以使用 LoadAsync 直接获取各个组件。不再支持此功能。相反,请使用 LoadAssetAsync 首先加载游戏对象,然后查找该对象上的组件。您不能简单地将检索到的引用类型GameObject转换为AnchorBehaviour引用。相反,你必须使用GetComponent.所以你应该做的是AssetBundleRequest assetRequest = assetBundle.LoadAssetAsync<GameObject>(objectNameToLoad);yield return assetRequest;GameObject loadedAsset = (GameObject)assetRequest.asset;// since model is already of type AnchorBehaviour// you should do the GetComponent already heremodel = loadedAsset.GetComponent<AnchorBehavior>();现在您已经有了类型的引用,AnchorBehaviour第二次GetComponent调用将是多余的,因为它返回相同的引用。所以现在只能用public void create(){    planeFinder.AnchorStage = model;}如果您有此脚本的多个实例,则仅加载 assetBundle 一次可能是有意义的,例如private static bool alreadyLoading;private static AssetBundle assetBundle;void Start(){    // only load the bundle once    if(!alreadyLoading)     {        // set the flag to make sure this is never done again        alreadyLoading = true;        StartCoroutine(LoadAsset(nameOfAssetBundle, nameOfObjectToLoad));    }    else    {        LoadObjectFromBundle(nameOfOjectToLoad);    }} private IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad){    string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");    filePath = System.IO.Path.Combine(filePath, assetBundleName);    var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);    yield return assetBundleCreateRequest;    assetBundle = assetBundleCreateRequest.assetBundle;    LoadObjectFromBundle(objectNameToLoad);}private IEnumerator LoadObjectFromBundle(string objectNameToLoad){    AssetBundleRequest assetRequest = assetBundle.LoadAssetAsync<GameObject>(objectNameToLoad);    yield return assetRequest;    GameObject loadedAsset = (GameObject)assetRequest.asset;    model = loadedAsset.GetComponent<AnchorBehavior>();}
随时随地看视频慕课网APP
我要回答