Download and use an asset bundle in arcore
I am currently experimenting with ARcore for unity and I have been tinkering with the HelloARController.cs script, I would like to be able to download and use an asset bundle from a server instead of the "Andy" prefabs in the example
My script so far is shown below
Line 96 is where the script imports my bundle from the webserver, this works fine but displays it at the viewpoint of the phone from the start, I could load this 1000m away without it being an issue tbh so that's not a problem, the problem lies in replacing the prefabs and line 160 is where it starts to select one of the predefined prefabs, I have put the entire script as I am not expert when it comes to unity scripting and am quite surprised my model import from a server worked as well as it did tbh so yeah small victories and all that,
Cheers
Pod
//-----------------------------------------------------------------------
// <copyright file="HelloARController.cs" company="Google">
//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
//-----------------------------------------------------------------------
namespace GoogleARCore.Examples.HelloAR
{
using System.Collections.Generic;
using GoogleARCore;
using GoogleARCore.Examples.Common;
using UnityEngine;
using System;
using System.Collections;
#if UNITY_EDITOR
// Set up touch input propagation while using Instant Preview in the editor.
using Input = InstantPreviewInput;
#endif
/// <summary>
/// Controls the HelloAR example.
/// </summary>
public class HelloARController : MonoBehaviour
{
public string BundleURL; // --> http://Myserver/public_http/Assets/AssetBundles/cube_prefab (path to the AssetBundle)
public string AssetName; // --> Cube_pref (name of the Asset prefab)
public int version;
/// <summary>
/// The first-person camera being used to render the passthrough camera image (i.e. AR background).
/// </summary>
public Camera FirstPersonCamera;
/// <summary>
/// A prefab for tracking and visualizing detected planes.
/// </summary>
public GameObject DetectedPlanePrefab;
/// <summary>
/// A model to place when a raycast from a user touch hits a plane.
/// </summary>
public GameObject AndyPlanePrefab;
/// <summary>
/// A model to place when a raycast from a user touch hits a feature point.
/// </summary>
public GameObject AndyPointPrefab;
/// <summary>
/// A gameobject parenting UI for displaying the "searching for planes" snackbar.
/// </summary>
public GameObject SearchingForPlaneUI;
/// <summary>
/// The rotation in degrees need to apply to model when the Andy model is placed.
/// </summary>
private const float k_ModelRotation = 180.0f;
/// <summary>
/// A list to hold all planes ARCore is tracking in the current frame. This object is used across
/// the application to avoid per-frame allocations.
/// </summary>
private List<DetectedPlane> m_AllPlanes = new List<DetectedPlane>();
/// <summary>
/// True if the app is in the process of quitting due to an ARCore connection error, otherwise false.
/// </summary>
private bool m_IsQuitting = false;
/// <summary>
/// The Unity Update() method.
/// </summary>
void Start()
{
StartCoroutine(DownloadAndCache());
}
IEnumerator DownloadAndCache()
{
// Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, version))
{
yield return www;
if (www.error != null)
throw new Exception("WWW download had an error:" + www.error);
AssetBundle bundle = www.assetBundle;
if (AssetName == "")
Instantiate(bundle.mainAsset);
else
{
GameObject dennis = bundle.LoadAsset(AssetName) as GameObject;
Instantiate(bundle.LoadAsset(AssetName));
}
// Unload the AssetBundles compressed contents to conserve memory
bundle.Unload(false);
} // memory is freed from the web stream (www.Dispose() gets called implicitly)
}
public void Update()
{
_UpdateApplicationLifecycle();
// Hide snackbar when currently tracking at least one plane.
Session.GetTrackables<DetectedPlane>(m_AllPlanes);
bool showSearchingUI = true;
for (int i = 0; i < m_AllPlanes.Count; i++)
{
if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
{
showSearchingUI = false;
break;
}
}
SearchingForPlaneUI.SetActive(showSearchingUI);
// If the player has not touched the screen, we are done with this update.
Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
{
return;
}
// Raycast against the location the player touched to search for planes.
TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
TrackableHitFlags.FeaturePointWithSurfaceNormal;
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
{
// Use hit pose and camera pose to check if hittest is from the
// back of the plane, if it is, no need to create the anchor.
if ((hit.Trackable is DetectedPlane) &&
Vector3.Dot(FirstPersonCamera.transform.position - hit.Pose.position,
hit.Pose.rotation * Vector3.up) < 0)
{
Debug.Log("Hit at back of the current DetectedPlane");
}
else
{
// Choose the Andy model for the Trackable that got hit.
GameObject prefab;
if (hit.Trackable is FeaturePoint)
{
prefab = AndyPointPrefab;
}
else
{
prefab = AndyPlanePrefab;
}
// Instantiate Andy model at the hit pose.
var andyObject = Instantiate(prefab, hit.Pose.position, hit.Pose.rotation);
// Compensate for the hitPose rotation facing away from the raycast (i.e. camera).
andyObject.transform.Rotate(0, k_ModelRotation, 0, Space.Self);
// Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
// world evolves.
var anchor = hit.Trackable.CreateAnchor(hit.Pose);
// Make Andy model a child of the anchor.
andyObject.transform.parent = anchor.transform;
}
}
}
/// <summary>
/// Check and update the application lifecycle.
/// </summary>
private void _UpdateApplicationLifecycle()
{
// Exit the app when the 'back' button is pressed.
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
// Only allow the screen to sleep when not tracking.
if (Session.Status != SessionStatus.Tracking)
{
const int lostTrackingSleepTimeout = 15;
Screen.sleepTimeout = lostTrackingSleepTimeout;
}
else
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
if (m_IsQuitting)
{
return;
}
// Quit if ARCore was unable to connect and give Unity some time for the toast to appear.
if (Session.Status == SessionStatus.ErrorPermissionNotGranted)
{
_ShowAndroidToastMessage("Camera permission is needed to run this application.");
m_IsQuitting = true;
Invoke("_DoQuit", 0.5f);
}
else if (Session.Status.IsError())
{
_ShowAndroidToastMessage("ARCore encountered a problem connecting. Please start the app again.");
m_IsQuitting = true;
Invoke("_DoQuit", 0.5f);
}
}
/// <summary>
/// Actually quit the application.
/// </summary>
private void _DoQuit()
{
Application.Quit();
}
/// <summary>
/// Show an Android toast message.
/// </summary>
/// <param name="message">Message string to show in the toast.</param>
private void _ShowAndroidToastMessage(string message)
{
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
if (unityActivity != null)
{
AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
{
AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity,
message, 0);
toastObject.Call("show");
}));
}
}
}
}
Your answer
Follow this Question
Related Questions
Why my prefab's Scale is changed to 0 at runtime? 1 Answer
Importing particles at runtime with Asset Bundles 1 Answer
Trying to package a prefab for sale in asset store 0 Answers
Instantiating without the use of Resource Folder in Unity? 0 Answers
Architecture advice on how to cycle a prefab's characteristics at runtime? 0 Answers