Implementing Cloud Save and Load
1. CloudSaveAnchor
Add the CloudSaveAnchor method to NRWorldAnchorStore
.
- Use FirebaseUse Aliyun OSS
- Use Aliyun OSS
namespace NRKernal.Persistence
{
// ... Other codes ...
public class NRWorldAnchorStore : IDisposable
{
// ... Other codes ...
public const string CloudAnchor2ObjectFile = "cloud_anchor2object.json";
/// <summary>save an anchor to firebase cloud server</summary>
public async Task<bool> CloudSaveAnchor(NRWorldAnchor anchor)
{
NRDebugger.Info("[NRWorldAnchorStore] Cloud save Anchor: {0}", anchor.UserDefinedKey);
string localFilename = Path.Combine(MapPath, anchor.UUID);
Debug.LogError("UploadFile: "+localFilename);
NRDebugger.Info("[NRWorldAnchorStore] UploadFile:" + localFilename);
FirebaseStorageManager storageManager = FirebaseStorageManager.Instance;
await storageManager.UploadFile(anchor.UUID, localFilename);
// Update the cloud anchor to object dictionary
// Save the dictionary to a JSON file
string json = LitJson.JsonMapper.ToJson(m_Anchor2ObjectDict);
string path = Path.Combine(MapPath, CloudAnchor2ObjectFile);
NRDebugger.Info("[NRWorldAnchorStore] Save to the path for next upload:" + path + " json:" + json);
File.WriteAllText(path, json);
// Upload the JSON file to the cloud
await storageManager.UploadFile(CloudAnchor2ObjectFile, path);
return true;
}
}
// ... Other codes ...
}
}
namespace NRKernal.Persistence
{
// ... Other codes ...
public class NRWorldAnchorStore : IDisposable
{
// ... Other codes ...
private AliyunOSSManager ossManager;
// ... Other codes ...
public const string CloudAnchor2ObjectFile = "cloud_anchor2object.json";
/// <summary>save an anchor to Aliyun cloud server</summary>
public async Task<bool> CloudSaveAnchor(NRWorldAnchor anchor)
{
NRDebugger.Info("[NRWorldAnchorStore] Cloud save Anchor: {0}", anchor.UserDefinedKey);
string localFilename = Path.Combine(MapPath, anchor.UUID);
Debug.LogError("UploadFile: "+localFilename);
NRDebugger.Info("[NRWorldAnchorStore] UploadFile:" + localFilename);
ossManager = AliyunOSSManager.Instance;
// FirebaseStorageManager storageManager = FirebaseStorageManager.Instance;
await ossManager.UploadFile(anchor.UUID, localFilename);
// Update the cloud anchor to object dictionary
// Save the dictionary to a JSON file
string json = LitJson.JsonMapper.ToJson(m_Anchor2ObjectDict);
string path = Path.Combine(MapPath, CloudAnchor2ObjectFile);
NRDebugger.Info("[NRWorldAnchorStore] Save to the path for next upload:" + path + " json:" + json);
File.WriteAllText(path, json);
// Upload the JSON file to the cloud
await ossManager.UploadFile(CloudAnchor2ObjectFile, path);
return true;
}
// ... Other codes ...
}
}
Add the CloudSaveAnchor method in NRWorldAnchor
, remember to add the namespace at the top of the script using System.Threading.Tasks;
public async Task<bool> CloudSaveAnchor()
{
return await NRWorldAnchorStore.Instance.CloudSaveAnchor(this);
}
2. CloudSave
Add the CloudSave method in AnchorItem.
public async void CloudSave()
{
if (m_NRWorldAnchor != null)
{
bool result=await NRWorldAnchorStore.Instance.CloudSaveAnchor(m_NRWorldAnchor);
if (result)
{
NRDebugger.Info("Ready to share anchor: " + m_NRWorldAnchor.UUID);
Debug.Log("Ready to share anchor: " + m_NRWorldAnchor.UUID);
}
else
{
Debug.LogError("Failed to save anchor");
}
}
else
{
Debug.LogError("m_NRWorldAnchor is null, failed to save this anchor to CloudStorage");
}
}
3. CloudLoad
Add CloudLoad() method in localMapExample
: Download the specified file from the cloud server by specifying UUID and load it into the scene with LoadwithUUID.
public const string CloudAnchor2ObjectFile = "cloud_anchor2object.json";
public async Task CloudLoad(string uuid)
{
if (m_NRWorldAnchorStore == null)
{
Debug.Log("[m_NRWorldAnchorStore] is null");
return;
}
// Download the cloud anchor to object dictionary from the cloud
string path = Path.Combine(m_NRWorldAnchorStore.MapPath, CloudAnchor2ObjectFile);
//await ossManager.DownloadFile(CloudAnchor2ObjectFile, path);
await storageManager.DownloadFile(CloudAnchor2ObjectFile, path);
// Read the dictionary from the downloaded JSON file
Dictionary<string, string> m_Anchor2ObjectDict = new Dictionary<string, string>();
if (File.Exists(path))
{
string json = File.ReadAllText(path);
m_Anchor2ObjectDict = LitJson.JsonMapper.ToObject<Dictionary<string, string>>(json);
}
// Get the UserDefinedKey for the given uuid
string UserDefinedKey;
if (m_Anchor2ObjectDict.TryGetValue(uuid, out UserDefinedKey))
{
// Download the anchor file from the cloud
string anchorPath = Path.Combine(m_NRWorldAnchorStore.MapPath, uuid);
//await ossManager.DownloadFile(uuid, anchorPath);
await storageManager.DownloadFile(uuid, anchorPath);
Debug.Log("anchorPath: "+anchorPath);
Debug.Log("uuid: "+uuid);
Debug.Log("UserDefinedKey: "+UserDefinedKey);
// Create a new dictionary for the specific UUID and Key
Dictionary<string, string> specificAnchorDict = new Dictionary<string, string>();
specificAnchorDict[uuid] = UserDefinedKey;
// Save the downloaded dictionary to the NRWorldAnchorStore
m_NRWorldAnchorStore.SetAnchor2ObjectDict(specificAnchorDict);
// Load the anchor
m_NRWorldAnchorStore.LoadwithUUID(uuid, (UInt64 handle) =>
{
var go = Instantiate(m_AnchorPrefabDict[UserDefinedKey]);
Debug.Log("cloud load: successful! ");
#if UNITY_EDITOR
go.transform.position = UnityEngine.Random.insideUnitSphere + Vector3.forward * 2;
#else
go.transform.position = Vector3.forward * 10000;
#endif
NRWorldAnchor anchor = go.AddComponent<NRWorldAnchor>();
anchor.UserDefinedKey = UserDefinedKey;
anchor.UUID = uuid;
anchor.BindAnchor(handle);
go.SetActive(true);
NRDebugger.Info("[NRWorldAnchorStore] CloudLoadwithUUID: {0}, UserDefinedKey: {1} Handle: {2}", uuid, UserDefinedKey, handle);
});
}
else
{
Debug.LogError("No UserDefinedKey found for uuid: " + uuid);
}
}
This requires adding a method in NRWorldAnchorStore.cs to put the UUID of the anchor downloaded from the cloud into m_Anchor2ObjectDict.
Copy
public void SetAnchor2ObjectDict(Dictionary<string, string> newDict)
{
foreach (var item in newDict)
{
if (!m_Anchor2ObjectDict.ContainsKey(item.Key))
{
m_Anchor2ObjectDict.Add(item.Key, item.Value);
}
}
}
Similarly, this method needs to be added to NRWorldAnchor.
public void SetAnchor2ObjectDict(Dictionary<string, string> newDict)
{
NRWorldAnchorStore.Instance.SetAnchor2ObjectDict(newDict);
}