This commit is contained in:
Ferlat Thibaud
2026-03-27 12:18:48 +01:00
176 changed files with 6526 additions and 200 deletions
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0786eea16a39aad45a66d878d9427145
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,642 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
[InitializeOnLoad]
public static class SceneEditPresenceTool
{
private const string ServerUrl = "http://unityapi.coiriergraphics.fr/scene_presence/";
private const double HeartbeatInterval = 180;
private static string _userId;
private static string _projectName;
private static string _scenePath;
private static double _nextHeartbeat;
private static bool _offline;
private static string _currentEditor = "none";
private static bool _requestInFlight;
private const float OverlayHeight = 30f;
private const float OverlayMarginTop = 3f;
private const float OverlayOffsetX = 48f;
private const float OverlayBaseWidth = 420f;
private const float OverlayWidthScale = .70f;
private const float ButtonWidth = 78f;
private static string ConfigPath =>
Path.Combine(
Directory.GetParent(Application.dataPath).FullName,
"UserSettings",
"ScenePresenceUser.json"
);
static SceneEditPresenceTool()
{
_projectName = Directory.GetParent(Application.dataPath).Name;
_userId = LoadOrAskUserId();
EditorApplication.delayCall += OnStartup;
EditorApplication.update += OnUpdate;
EditorSceneManager.activeSceneChangedInEditMode += OnSceneChanged;
SceneView.duringSceneGui += OnSceneGui;
}
private static async void OnStartup()
{
if (string.IsNullOrWhiteSpace(_userId))
return;
var scene = SceneManager.GetActiveScene();
if (!string.IsNullOrEmpty(scene.path))
{
_scenePath = scene.path;
await OpenScene();
}
}
private static async void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (string.IsNullOrWhiteSpace(_userId))
return;
if (!string.IsNullOrEmpty(newScene.path))
{
_scenePath = newScene.path;
await OpenScene();
}
}
private static async void OnUpdate()
{
if (string.IsNullOrWhiteSpace(_userId))
return;
if (string.IsNullOrEmpty(_scenePath))
return;
if (_requestInFlight)
return;
if (EditorApplication.timeSinceStartup < _nextHeartbeat)
return;
_nextHeartbeat = EditorApplication.timeSinceStartup + HeartbeatInterval;
await Heartbeat();
RepaintSceneView();
}
private static void OnSceneGui(SceneView sceneView)
{
Handles.BeginGUI();
float width = Mathf.Min(sceneView.position.width - (OverlayOffsetX + 16f), OverlayBaseWidth) * OverlayWidthScale;
Rect rect = new Rect(
OverlayOffsetX,
OverlayMarginTop,
width,
OverlayHeight
);
DrawTopBar(rect);
Handles.EndGUI();
}
private static void DrawTopBar(Rect rect)
{
UiState state = GetUiState();
string buttonLabel = state == UiState.OwnedByMe ? "Release" : "Edit";
bool buttonEnabled = state != UiState.Offline && !_requestInFlight;
Rect buttonRect = new Rect(
rect.xMax - ButtonWidth - 6f,
rect.y + 4f,
ButtonWidth,
rect.height - 8f
);
Rect textRect = new Rect(
rect.x + 10f,
rect.y,
rect.width - ButtonWidth - 22f,
rect.height
);
EditorGUI.DrawRect(rect, GetBackgroundColor(state));
GUIStyle textStyle = new GUIStyle(EditorStyles.label)
{
alignment = TextAnchor.MiddleLeft,
fontStyle = FontStyle.Bold,
fontSize = 11,
normal = { textColor = Color.white },
clipping = TextClipping.Clip
};
GUI.Label(textRect, GetMessage(state), textStyle);
Color oldColor = GUI.backgroundColor;
GUI.backgroundColor = GetButtonColor(state);
EditorGUI.BeginDisabledGroup(!buttonEnabled);
if (GUI.Button(buttonRect, buttonLabel))
{
if (state == UiState.MissingUserId)
{
AskUserIdWindow.ShowWindow(SaveUserIdAndRefresh);
}
else if (state == UiState.OwnedByMe)
{
ReleaseEditMode();
}
else
{
TakeEditMode();
}
}
EditorGUI.EndDisabledGroup();
GUI.backgroundColor = oldColor;
}
private static UiState GetUiState()
{
if (string.IsNullOrWhiteSpace(_userId))
return UiState.MissingUserId;
if (_offline)
return UiState.Offline;
if (_currentEditor == _userId)
return UiState.OwnedByMe;
if (!string.IsNullOrEmpty(_currentEditor) && _currentEditor != "none")
return UiState.OwnedByOther;
return UiState.Free;
}
private static string GetMessage(UiState state)
{
switch (state)
{
case UiState.MissingUserId:
return "User ID required";
case UiState.OwnedByMe:
return "You are editing this scene";
case UiState.OwnedByOther:
return $"{_currentEditor} is editing this scene";
case UiState.Offline:
return "Offline";
default:
return "Scene available";
}
}
private static Color GetBackgroundColor(UiState state)
{
const float alpha = 0.70f;
switch (state)
{
case UiState.MissingUserId:
case UiState.Offline:
return new Color(1.00f, 0.10f, 0.10f, alpha);
case UiState.OwnedByMe:
return new Color(0.22f, 0.55f, 0.28f, alpha);
case UiState.OwnedByOther:
return new Color(0.82f, 0.48f, 0.10f, alpha);
default:
return new Color(0.18f, 0.18f, 0.18f, alpha);
}
}
private static Color GetButtonColor(UiState state)
{
switch (state)
{
case UiState.Free:
return new Color(0.38f, 0.66f, 1.00f, 1f);
case UiState.MissingUserId:
case UiState.OwnedByOther:
case UiState.OwnedByMe:
case UiState.Offline:
default:
return new Color(0.22f, 0.22f, 0.22f, 1f);
}
}
private static async void TakeEditMode()
{
if (string.IsNullOrWhiteSpace(_userId))
{
AskUserIdWindow.ShowWindow(SaveUserIdAndRefresh);
return;
}
if (string.IsNullOrEmpty(_scenePath))
return;
EditModeRequest payload = new EditModeRequest
{
projectName = _projectName,
scenePath = _scenePath,
userId = _userId,
dateTime = DateTime.UtcNow.ToString("o"),
force = false
};
SetEditModeResponse result = await Request<SetEditModeResponse>("set_edit_mode.php", payload);
if (result == null)
{
SetOffline();
return;
}
_offline = false;
if (!result.success)
{
Debug.LogError("[ScenePresence] set_edit_mode failed.");
RepaintSceneView();
return;
}
if (result.granted)
{
_currentEditor = _userId;
RepaintSceneView();
return;
}
string ownerName = !string.IsNullOrWhiteSpace(result.occupiedBy)
? result.occupiedBy
: (!string.IsNullOrWhiteSpace(_currentEditor) && _currentEditor != "none" ? _currentEditor : "another user");
bool forceTake = EditorUtility.DisplayDialog(
"Scene Already In Edit Mode",
$"This scene is already locked by {ownerName}.\nDo you want to take control anyway?",
"Take Control",
"Cancel"
);
if (!forceTake)
return;
payload.force = true;
SetEditModeResponse forced = await Request<SetEditModeResponse>("set_edit_mode.php", payload);
if (forced == null)
{
SetOffline();
return;
}
_offline = false;
if (forced.success && forced.granted)
{
_currentEditor = _userId;
RepaintSceneView();
}
}
private static async void ReleaseEditMode()
{
if (string.IsNullOrWhiteSpace(_userId))
return;
if (string.IsNullOrEmpty(_scenePath))
return;
ReleaseResponse result = await Request<ReleaseResponse>("release_edit_mode.php", new BaseRequest
{
projectName = _projectName,
scenePath = _scenePath,
userId = _userId,
dateTime = DateTime.UtcNow.ToString("o")
});
if (result == null)
{
SetOffline();
return;
}
_offline = false;
_currentEditor = "none";
RepaintSceneView();
await OpenScene();
}
private static async Task OpenScene()
{
OpenSceneResponse result = await Request<OpenSceneResponse>("open_scene.php", new BaseRequest
{
projectName = _projectName,
scenePath = _scenePath,
userId = _userId,
dateTime = DateTime.UtcNow.ToString("o")
});
if (result == null)
{
SetOffline();
return;
}
_offline = false;
if (result.hasEditor)
{
_currentEditor = string.IsNullOrWhiteSpace(result.editorUserId) ? "none" : result.editorUserId;
}
else
{
_currentEditor = "none";
}
RepaintSceneView();
}
private static async Task Heartbeat()
{
HeartbeatResponse result = await Request<HeartbeatResponse>("heartbeat.php", new BaseRequest
{
projectName = _projectName,
scenePath = _scenePath,
userId = _userId,
dateTime = DateTime.UtcNow.ToString("o")
});
if (result == null)
{
SetOffline();
return;
}
_offline = false;
if (result.hasEditor)
_currentEditor = string.IsNullOrWhiteSpace(result.editorUserId) ? "none" : result.editorUserId;
else
_currentEditor = "none";
RepaintSceneView();
}
private static async Task<T> Request<T>(string endpoint, object payload) where T : class
{
_requestInFlight = true;
try
{
string json = JsonUtility.ToJson(payload);
byte[] bytes = Encoding.UTF8.GetBytes(json);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ServerUrl + endpoint);
request.Method = "POST";
request.ContentType = "application/json";
request.Timeout = 5000;
request.ReadWriteTimeout = 5000;
request.ContentLength = bytes.Length;
using (var requestStream = await request.GetRequestStreamAsync())
{
await requestStream.WriteAsync(bytes, 0, bytes.Length);
}
using var response = await request.GetResponseAsync();
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream);
string responseJson = await reader.ReadToEndAsync();
if (string.IsNullOrWhiteSpace(responseJson))
return null;
if (!responseJson.TrimStart().StartsWith("{"))
{
Debug.LogError($"[ScenePresence] Non-JSON response from {endpoint}: {responseJson}");
return null;
}
//Debug.Log($"[ScenePresence] {endpoint} => {responseJson}");
return JsonUtility.FromJson<T>(responseJson);
}
catch (Exception ex)
{
Debug.LogError($"[ScenePresence] Request failed ({endpoint}): {ex}");
return null;
}
finally
{
_requestInFlight = false;
}
}
private static void SetOffline()
{
_offline = true;
RepaintSceneView();
}
private static void RepaintSceneView()
{
if (SceneView.lastActiveSceneView != null)
SceneView.lastActiveSceneView.Repaint();
}
private static string LoadOrAskUserId()
{
try
{
if (File.Exists(ConfigPath))
{
UserConfig saved = JsonUtility.FromJson<UserConfig>(File.ReadAllText(ConfigPath));
if (saved != null && !string.IsNullOrWhiteSpace(saved.userId))
return saved.userId.Trim();
}
}
catch (Exception ex)
{
Debug.LogWarning($"[ScenePresence] Failed to read config: {ex.Message}");
}
EditorApplication.delayCall += () =>
{
AskUserIdWindow.ShowWindow(SaveUserIdAndRefresh);
};
return null;
}
private static void SaveUserIdAndRefresh(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
return;
_userId = userId.Trim();
SaveUserId(_userId);
EditorApplication.delayCall += async () =>
{
Scene scene = SceneManager.GetActiveScene();
if (!string.IsNullOrEmpty(scene.path))
{
_scenePath = scene.path;
await OpenScene();
}
RepaintSceneView();
};
}
private static void SaveUserId(string userId)
{
try
{
string directory = Path.GetDirectoryName(ConfigPath);
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
UserConfig config = new UserConfig { userId = userId };
File.WriteAllText(ConfigPath, JsonUtility.ToJson(config, true));
}
catch (Exception ex)
{
Debug.LogError($"[ScenePresence] Failed to save config: {ex.Message}");
}
}
[Serializable]
private class UserConfig
{
public string userId;
}
[Serializable]
private class BaseRequest
{
public string projectName;
public string scenePath;
public string userId;
public string dateTime;
}
[Serializable]
private class EditModeRequest : BaseRequest
{
public bool force;
}
[Serializable]
private class OpenSceneResponse
{
public bool success;
public bool hasEditor;
public string editorUserId;
public string editorDateTime;
public string editorServerTakenAt;
public bool editorOnline;
}
[Serializable]
private class HeartbeatResponse
{
public bool success;
public bool hasEditor;
public string editorUserId;
public bool editorOnline;
}
[Serializable]
private class SetEditModeResponse
{
public bool success;
public bool granted;
public bool forced;
public string occupiedBy;
public string editorUserId;
}
[Serializable]
private class ReleaseResponse
{
public bool success;
public bool released;
}
private enum UiState
{
MissingUserId,
Free,
OwnedByOther,
OwnedByMe,
Offline
}
}
public class AskUserIdWindow : EditorWindow
{
private static Action<string> _onSave;
private static AskUserIdWindow _instance;
private string _userId = "";
public static void ShowWindow(Action<string> onSave)
{
if (_instance != null)
{
_instance.Focus();
return;
}
_onSave = onSave;
_instance = CreateInstance<AskUserIdWindow>();
_instance.titleContent = new GUIContent("Scene Presence Setup");
_instance.minSize = new Vector2(240, 60);
_instance.maxSize = new Vector2(240, 60);
_instance.ShowUtility();
_instance.Focus();
}
private void OnDestroy()
{
if (_instance == this)
_instance = null;
}
private void OnGUI()
{
GUILayout.Space(10);
EditorGUIUtility.labelWidth = 60;
_userId = EditorGUILayout.TextField("User ID", _userId);
GUILayout.FlexibleSpace();
using (new EditorGUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
GUI.enabled = !string.IsNullOrWhiteSpace(_userId);
if (GUILayout.Button("Save", GUILayout.Width(80)))
{
_onSave?.Invoke(_userId.Trim());
Close();
}
GUI.enabled = true;
}
GUILayout.Space(10);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d9c85ae0c5f70cc4da07f387065c0015
@@ -40780,6 +40780,187 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 7977652778530834609, guid: 9d4ef384d30b05644add2b0f2671172d, type: 3}
m_PrefabInstance: {fileID: 2118815573}
m_PrefabAsset: {fileID: 0}
--- !u!1 &2120285857
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2120285861}
- component: {fileID: 2120285860}
- component: {fileID: 2120285859}
- component: {fileID: 2120285858}
- component: {fileID: 2120285863}
- component: {fileID: 2120285864}
- component: {fileID: 2120285865}
m_Layer: 0
m_Name: Test Binaural Trigger Box
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!65 &2120285858
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 1
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!23 &2120285859
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &2120285860
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &2120285861
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
serializedVersion: 2
m_LocalRotation: {x: -0, y: 0.37134382, z: -0, w: 0.92849547}
m_LocalPosition: {x: 4.27, y: 0.67, z: 4.34}
m_LocalScale: {x: 4.0511775, y: 1, z: 0.080541}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 43.597, z: 0}
--- !u!114 &2120285863
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4ccb80e2899444642bdbf406a3c31f7b, type: 3}
m_Name:
m_EditorClassIdentifier: AK.Wwise.Unity.MonoBehaviour::AkGameObj
m_listeners:
initialListenerList: []
useDefaultListeners: 1
isEnvironmentAware: 1
isStaticObject: 0
usePositionOffsetData: 0
m_positionOffsetData:
KeepMe: 0
positionOffset: {x: 0, y: 0, z: 0}
scalingFactor: 1
m_posOffsetData: {fileID: 0}
listenerMask: 1
--- !u!114 &2120285864
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e373aeb0201d8a04f9db6db17c228f5b, type: 3}
m_Name:
m_EditorClassIdentifier: AK.Wwise.Unity.MonoBehaviour::AkTriggerCollisionEnter
triggerObject: {fileID: 0}
--- !u!114 &2120285865
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2120285857}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: eec618f338d13bf43b8519814d335311, type: 3}
m_Name:
m_EditorClassIdentifier: AK.Wwise.Unity.MonoBehaviour::AkEvent
triggerList: d1bbb3b5
useOtherObject: 0
actionOnEventType: 0
curveInterpolation: 4
enableActionOnEvent: 0
data:
idInternal: 0
valueGuidInternal:
WwiseObjectReference: {fileID: 11400000, guid: d5f4712941b510141bf650af8b0f2d30, type: 2}
useCallbacks: 0
stopSoundOnDestroy: 1
Callbacks: []
soundEmitterObject: {fileID: 0}
transitionDuration: 0
eventIdInternal: 0
valueGuidInternal:
m_callbackDataInternal: {fileID: 0}
--- !u!1001 &2120929457
PrefabInstance:
m_ObjectHideFlags: 0
@@ -41166,6 +41347,75 @@ Transform:
- {fileID: 1953778498}
m_Father: {fileID: 1025255338}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1326677913385073831
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 346295483107942936, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_Name
value: Tree
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalScale.x
value: -0.1078
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalScale.y
value: -0.1078
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalScale.z
value: -0.1078
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalPosition.x
value: 5.524
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalPosition.y
value: 1.798
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalPosition.z
value: 5.456
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7006957402099132261, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 58a9d39fccd0ba9429443d35e5338bab, type: 3}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
@@ -41175,3 +41425,5 @@ SceneRoots:
- {fileID: 1101670451}
- {fileID: 1965767837}
- {fileID: 1391553830}
- {fileID: 1326677913385073831}
- {fileID: 2120285861}