Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,91 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Oculus.Interaction.Surfaces;
using UnityEngine.SceneManagement;
using System.Linq;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(BoundsClipper))]
public class BoundsClipperEditor : UnityEditor.Editor
{
private bool _visualize = false;
private IEnumerable<IRemoteDrawable> _drawables;
private BoundsClipper Clipper => target as BoundsClipper;
public override void OnInspectorGUI()
{
if (GUILayout.Button(_visualize ? "Hide Surface Visuals" : "Show Surface Visuals"))
{
_visualize = !_visualize;
_drawables = null;
SceneView.RepaintAll();
}
EditorGUILayout.Space();
base.OnInspectorGUI();
}
private void UpdateDrawables()
{
_drawables = SceneManager.GetActiveScene()
.GetRootGameObjects()
.Union(new[] { Clipper.transform.root.gameObject })
.SelectMany(root => root
.GetComponentsInChildren<IClippedSurface<IBoundsClipper>>(false))
.Where((s) => s.GetClippers().Contains(Clipper))
.Select(s => CreateEditor(s as Object) as IRemoteDrawable);
}
private void OnSceneGUI()
{
if (!Clipper.GetLocalBounds(Clipper.transform, out Bounds localBounds))
{
return;
}
var prevColor = Handles.color;
var prevMatrix = Handles.matrix;
Handles.color = _visualize ? Color.white : Color.white;
Handles.matrix = Clipper.transform.localToWorldMatrix;
Handles.DrawWireCube(localBounds.center, localBounds.size);
Handles.color = prevColor;
Handles.matrix = prevMatrix;
if (_visualize)
{
if (_drawables == null)
{
UpdateDrawables();
}
foreach (var drawer in _drawables)
{
drawer.DrawRemote();
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ac62e2f2d66aeef43b16ba05a35880fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,54 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEditor;
using UnityEngine;
using Oculus.Interaction.Surfaces;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(CircleSurface), true)]
public class CircleSurfaceEditor : UnityEditor.Editor
{
private SerializedProperty _planeSurfaceProperty;
private SerializedProperty _radiusProperty;
private void Awake()
{
_planeSurfaceProperty = serializedObject.FindProperty("_planeSurface");
_radiusProperty = serializedObject.FindProperty("_radius");
}
public void OnSceneGUI()
{
Handles.color = EditorConstants.PRIMARY_COLOR;
ISurface planeSurface = _planeSurfaceProperty.objectReferenceValue as PlaneSurface;
if (planeSurface == null)
{
return;
}
Transform transform = planeSurface.Transform;
float radius = _radiusProperty.floatValue * transform.lossyScale.x;
Handles.DrawWireDisc(transform.position, -transform.forward, radius, EditorConstants.LINE_THICKNESS);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d9ba4888a594ab4da6322969db35417
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,85 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEditor;
using Oculus.Interaction.Surfaces;
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(ClippedCylinderSurface))]
public class ClippedCylinderSurfaceEditor : UnityEditor.Editor, IRemoteDrawable
{
private ClippedCylinderSurface ClippedCylinder =>
target as ClippedCylinderSurface;
public void DrawRemote()
{
DrawClippers();
DrawClippedArea();
}
private void OnSceneGUI()
{
if (ClippedCylinder.BackingSurface == null ||
ClippedCylinder.Transform == null)
{
return;
}
DrawClippers();
DrawClippedArea();
}
private void DrawClippers()
{
IEnumerable<ICylinderClipper> activeClippers =
ClippedCylinder.GetClippers()
.Where(c => c != null);
if (activeClippers.Count() > 0)
{
foreach (var clipper in activeClippers)
{
if (clipper.GetCylinderSegment(out CylinderSegment segment))
{
Handles.color = Color.gray;
SurfaceDrawing.DrawCylinderSegment(
ClippedCylinder.Cylinder, segment);
}
}
}
}
private void DrawClippedArea()
{
Handles.color = EditorConstants.PRIMARY_COLOR;
if (ClippedCylinder.GetClipped(
out CylinderSegment clipped))
{
SurfaceDrawing.DrawCylinderSegment(
ClippedCylinder.Cylinder, clipped);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c85fb333acdbe64083291403294e7aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,106 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEditor;
using Oculus.Interaction.Surfaces;
using UnityEngine;
using System.Linq;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(ClippedPlaneSurface))]
public class ClippedPlaneSurfaceEditor : UnityEditor.Editor, IRemoteDrawable
{
private ClippedPlaneSurface ClippedPlane =>
target as ClippedPlaneSurface;
private void OnSceneGUI()
{
if (ClippedPlane.BackingSurface == null ||
ClippedPlane.Transform == null)
{
return;
}
if (ClippedPlane.GetClippers()
.Where(c => c != null)
.Count() > 0)
{
DrawClippingVolumes();
DrawClippedArea();
}
}
public void DrawRemote()
{
DrawClippedArea();
}
private void DrawClippingVolumes()
{
var prevMatrix = Handles.matrix;
Handles.matrix = ClippedPlane.Transform.localToWorldMatrix;
// Draw each clipping area
foreach (var clipVolume in ClippedPlane.GetClippers()
.Where((c) => c != null))
{
Handles.color = Color.gray;
if ((clipVolume as IBoundsClipper).
GetLocalBounds(ClippedPlane.Transform, out Bounds bounds))
{
Handles.DrawWireCube(bounds.center, bounds.size);
}
}
Handles.matrix = prevMatrix;
}
private void DrawClippedArea()
{
Bounds maxSize = new Bounds(Vector3.zero, Vector3.one * float.MaxValue);
if (!ClippedPlane.ClipBounds(maxSize, out Bounds bounds))
{
return;
}
var prevMatrix = Handles.matrix;
Handles.matrix = ClippedPlane.Transform.localToWorldMatrix;
// Draw final clipping area
Handles.color = Color.white;
Handles.DrawWireCube(bounds.center, bounds.size);
Handles.color = EditorConstants.PRIMARY_COLOR;
Vector3 planeMin = new Vector3(bounds.min.x, bounds.min.y, 0);
Vector3 planeMax = new Vector3(bounds.max.x, bounds.max.y, 0);
// Draw clipped plane quad
Handles.DrawLine(planeMin, planeMax);
Handles.DrawLine(planeMin, new Vector3(planeMin.x, planeMax.y, 0));
Handles.DrawLine(new Vector3(planeMin.x, planeMax.y, 0), planeMax);
Handles.DrawLine(planeMax, new Vector3(planeMax.x, planeMin.y, 0));
Handles.DrawLine(new Vector3(planeMax.x, planeMin.y, 0), planeMin);
Handles.matrix = prevMatrix;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 313c3cc53f8d2cb4196f3850d3da63dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,83 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Oculus.Interaction.Surfaces;
using UnityEngine.SceneManagement;
using System.Linq;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(CylinderClipper))]
public class CylinderClipperEditor : UnityEditor.Editor
{
private bool _visualize = false;
private IEnumerable<IRemoteDrawable> _drawables;
private CylinderClipper Clipper => target as CylinderClipper;
public override void OnInspectorGUI()
{
if (GUILayout.Button(_visualize ? "Hide Surface Visuals" : "Show Surface Visuals"))
{
_visualize = !_visualize;
_drawables = null;
SceneView.RepaintAll();
}
EditorGUILayout.Space();
base.OnInspectorGUI();
}
private void UpdateDrawables()
{
_drawables = SceneManager.GetActiveScene()
.GetRootGameObjects()
.Union(new[] { Clipper.transform.root.gameObject })
.SelectMany(root => root
.GetComponentsInChildren<IClippedSurface<ICylinderClipper>>(false))
.Where((s) => s.GetClippers().Contains(Clipper))
.Select(s => CreateEditor(s as Object) as IRemoteDrawable);
}
private void OnSceneGUI()
{
if (!Clipper.GetCylinderSegment(out CylinderSegment curvedPlane))
{
return;
}
if (_visualize)
{
if (_drawables == null)
{
UpdateDrawables();
}
foreach (var drawer in _drawables)
{
drawer.DrawRemote();
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8a426a292deba194c9b8e1e270b692dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,98 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEngine;
using UnityEditor;
using Oculus.Interaction.Surfaces;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(CylinderSurface))]
public class CylinderSurfaceEditor : UnityEditor.Editor
{
private const int NUM_SEGMENTS = 30;
private static readonly Color ValidColor = Color.green * 0.8f;
private static readonly Color InvalidColor = Color.red * 0.8f;
public void OnSceneGUI()
{
CylinderSurface cylinder = target as CylinderSurface;
if (cylinder.Cylinder != null)
{
Draw(cylinder);
}
}
public static void Draw(CylinderSurface cylinderSurface)
{
Color prevColor = Handles.color;
Handles.color = cylinderSurface.IsValid ? ValidColor : InvalidColor;
float gizmoHeight = cylinderSurface.Height;
float camYOffset = 0;
bool infiniteHeight = cylinderSurface.Height <= 0;
if (infiniteHeight && SceneView.lastActiveSceneView?.camera != null)
{
gizmoHeight = 1000f;
Vector3 sceneCamPos = SceneView.lastActiveSceneView.camera.transform.position;
camYOffset = cylinderSurface.Cylinder.transform.InverseTransformPoint(sceneCamPos).y;
}
for (int i = 0; i < 2; ++i)
{
bool isTop = i == 1;
float y = isTop ? gizmoHeight / 2 : -gizmoHeight / 2;
int numSegments = (int)(NUM_SEGMENTS * Mathf.Max(cylinderSurface.Radius / 2, 1));
Vector3 prevSegmentWorld = Vector3.zero;
for (int seg = 0; seg <= numSegments; ++seg)
{
float ratio = (float)seg / numSegments * Mathf.PI * 2;
float x = Mathf.Cos(ratio) * cylinderSurface.Radius;
float z = Mathf.Sin(ratio) * cylinderSurface.Radius;
Vector3 curSegmentLocal = new Vector3(x, y + camYOffset, z);
Vector3 curSegmentWorld = cylinderSurface.Cylinder.transform.TransformPoint(curSegmentLocal);
if (isTop) // Draw connecting lines from top circle
{
Vector3 bottomVert = new Vector3(curSegmentLocal.x,
curSegmentLocal.y - gizmoHeight,
curSegmentLocal.z);
bottomVert = cylinderSurface.Cylinder.transform.TransformPoint(bottomVert);
Handles.DrawLine(curSegmentWorld, bottomVert);
}
if (seg > 0 && !infiniteHeight)
{
Handles.DrawLine(curSegmentWorld, prevSegmentWorld);
}
prevSegmentWorld = curSegmentWorld;
}
}
Handles.color = prevColor;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e07ffae6a51b8ba438d7976a6c2dfd0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,102 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEngine;
using UnityEditor;
using Oculus.Interaction.Surfaces;
namespace Oculus.Interaction.Editor
{
[CustomEditor(typeof(PlaneSurface))]
public class PlaneSurfaceEditor : UnityEditor.Editor
{
private const int NUM_SEGMENTS = 80;
private const float MAX_DISTANCE = 20f;
private static readonly Color ColorFront = EditorConstants.PRIMARY_COLOR;
private static readonly Color ColorBack = EditorConstants.ERROR_COLOR;
private static float Interval => MAX_DISTANCE / NUM_SEGMENTS;
private static Vector3[] _lines = new Vector3[NUM_SEGMENTS * 2 * 2];
public void OnSceneGUI()
{
PlaneSurface plane = target as PlaneSurface;
Draw(plane);
}
public void Draw(PlaneSurface plane)
{
Vector3 origin = plane.transform.position;
Color color = ColorFront;
if (SceneView.lastActiveSceneView?.camera != null)
{
Transform camTransform = SceneView.lastActiveSceneView.camera.transform;
bool isBehind = Vector3.Dot(camTransform.forward, plane.transform.forward) < 0f;
if (isBehind)
{
color = ColorBack;
}
if (plane.ClosestSurfacePoint(camTransform.position, out SurfaceHit hit, 0))
{
Vector3 hitDelta = PoseUtils.Delta(plane.transform, new Pose(hit.Point, plane.transform.rotation)).position;
hitDelta.x = Mathf.RoundToInt(hitDelta.x / Interval) * Interval;
hitDelta.y = Mathf.RoundToInt(hitDelta.y / Interval) * Interval;
hitDelta.z = 0f;
origin = PoseUtils.Multiply(plane.transform.GetPose(), new Pose(hitDelta, Quaternion.identity)).position;
}
}
DrawLines(origin, plane.Normal, plane.transform.up, color);
DrawLines(origin, plane.Normal, plane.transform.right, color);
}
private void DrawLines(in Vector3 origin,
in Vector3 normal,
in Vector3 direction,
in Color color)
{
Vector3 step = direction * Interval;
Vector3 offsetOrigin = origin - step * NUM_SEGMENTS;
int index = 0;
for (int i = -NUM_SEGMENTS; i < NUM_SEGMENTS; ++i)
{
Vector3 cross = Vector3.Cross(normal, direction).normalized * MAX_DISTANCE;
Vector3 start = offsetOrigin - cross;
Vector3 end = offsetOrigin + cross;
_lines[index++] = start;
_lines[index++] = end;
offsetOrigin += step;
}
Color prevColor = Handles.color;
Handles.color = color;
Handles.DrawLines(_lines);
Handles.color = prevColor;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc41df2906bfe5d4a97191241199d6bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,112 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* 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.
*/
using UnityEditor;
using UnityEngine;
using Oculus.Interaction.Surfaces;
namespace Oculus.Interaction.Editor
{
public static class SurfaceDrawing
{
public static void DrawCylinderSegment(Cylinder cylinder, CylinderSegment segment)
{
const int SEGMENTS_PER_UNIT = 5;
if (cylinder == null ||
segment.ArcDegrees <= 0f)
{
return;
}
// Handle infinite height using scene camera Y
float top, bottom;
if (segment.IsInfiniteHeight)
{
if (SceneView.lastActiveSceneView != null &&
SceneView.lastActiveSceneView.camera != null)
{
Vector3 cameraPos =
cylinder.transform.InverseTransformPoint(
SceneView.lastActiveSceneView.camera.transform.position);
bottom = cameraPos.y - 10;
top = cameraPos.y + 10;
}
else
{
bottom = -30;
top = 30;
}
}
else
{
bottom = segment.Bottom;
top = segment.Top;
}
float height = top - bottom;
float width = segment.ArcDegrees * Mathf.Deg2Rad * cylinder.Radius;
int verticalSegments = Mathf.Max(2, Mathf.CeilToInt(SEGMENTS_PER_UNIT * height));
int horizontalSegments = Mathf.Max(2, Mathf.FloorToInt(SEGMENTS_PER_UNIT * width));
for (int v = 0; v <= verticalSegments; ++v)
{
float y = Mathf.Lerp(bottom, top, (float)v / verticalSegments);
DrawArc(cylinder, segment, y);
}
for (int h = 0; h <= horizontalSegments; ++h)
{
float x = Mathf.Lerp(-segment.ArcDegrees / 2,
segment.ArcDegrees / 2,
(float)h / horizontalSegments);
DrawLine(cylinder, segment, bottom, top, x);
}
}
private static void DrawArc(Cylinder cylinder, CylinderSegment segment, float y)
{
Vector3 center = cylinder.transform.TransformPoint(new Vector3(0, y, 0));
Vector3 forward = cylinder.transform.TransformDirection(
Quaternion.Euler(0, segment.Rotation - segment.ArcDegrees / 2, 0) *
Vector3.forward);
Handles.DrawWireArc(center,
cylinder.transform.up,
forward,
segment.ArcDegrees,
cylinder.Radius * cylinder.transform.lossyScale.z
, EditorConstants.LINE_THICKNESS
);
}
private static void DrawLine(Cylinder cylinder, CylinderSegment segment,
float bottom, float top, float deg)
{
Vector3 forward = Quaternion.Euler(0, segment.Rotation + deg, 0) *
Vector3.forward * cylinder.Radius;
Vector3 p1 = cylinder.transform.TransformPoint((Vector3.up * bottom) + forward);
Vector3 p2 = cylinder.transform.TransformPoint((Vector3.up * top) + forward);
Handles.DrawLine(p1, p2, EditorConstants.LINE_THICKNESS);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf88c6307a5127044b8532fafa492449
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: