From 64f549d3d47f52397fb2198cd933910e1b5c3c22 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 10:39:11 +0200 Subject: [PATCH 1/9] fix compiling bug of CookieException --- websocket-sharp/Net/CookieException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/websocket-sharp/Net/CookieException.cs b/websocket-sharp/Net/CookieException.cs index e6a942844..2a5abe98a 100644 --- a/websocket-sharp/Net/CookieException.cs +++ b/websocket-sharp/Net/CookieException.cs @@ -46,7 +46,7 @@ namespace WebSocketSharp.Net /// The exception that is thrown when a gets an error. /// [Serializable] - public class CookieException : FormatException + public class CookieException : FormatException, ISerializable { #region Internal Constructors From 09a5ed0841f36e01ea4aeaf857c0ac6c210d3f73 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 10:43:38 +0200 Subject: [PATCH 2/9] add unity gitignore --- unity/.gitignore | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 unity/.gitignore diff --git a/unity/.gitignore b/unity/.gitignore new file mode 100644 index 000000000..638dea085 --- /dev/null +++ b/unity/.gitignore @@ -0,0 +1,51 @@ +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +[Ll]ogs/ + +# Never ignore Asset meta data +![Aa]ssets/**/*.meta + +# Uncomment this line if you wish to ignore the asset store tools plugin +# [Aa]ssets/AssetStoreTools* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.unitypackage + +# Crashlytics generated file +crashlytics-build.properties From 19acb2ce1fc19d055a374590abf92983f93108c2 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 13:20:14 +0200 Subject: [PATCH 3/9] add unity example stub --- unity/Example1/Assets/Scenes.meta | 8 + .../Example1/Assets/Scenes/SampleScene.unity | 259 +++++++ .../Assets/Scenes/SampleScene.unity.meta | 7 + unity/Example1/Packages/manifest.json | 41 ++ .../ProjectSettings/AudioManager.asset | 19 + .../ProjectSettings/ClusterInputManager.asset | 6 + .../ProjectSettings/DynamicsManager.asset | 34 + .../ProjectSettings/EditorBuildSettings.asset | 8 + .../ProjectSettings/EditorSettings.asset | 25 + .../ProjectSettings/GraphicsSettings.asset | 61 ++ .../ProjectSettings/InputManager.asset | 295 ++++++++ .../ProjectSettings/NavMeshAreas.asset | 91 +++ .../ProjectSettings/Physics2DSettings.asset | 56 ++ .../ProjectSettings/PresetManager.asset | 6 + .../ProjectSettings/ProjectSettings.asset | 644 ++++++++++++++++++ .../ProjectSettings/ProjectVersion.txt | 2 + .../ProjectSettings/QualitySettings.asset | 231 +++++++ .../Example1/ProjectSettings/TagManager.asset | 43 ++ .../ProjectSettings/TimeManager.asset | 9 + .../UnityConnectSettings.asset | 34 + .../Example1/ProjectSettings/VFXManager.asset | 11 + .../Example1/ProjectSettings/XRSettings.asset | 10 + 22 files changed, 1900 insertions(+) create mode 100644 unity/Example1/Assets/Scenes.meta create mode 100644 unity/Example1/Assets/Scenes/SampleScene.unity create mode 100644 unity/Example1/Assets/Scenes/SampleScene.unity.meta create mode 100644 unity/Example1/Packages/manifest.json create mode 100644 unity/Example1/ProjectSettings/AudioManager.asset create mode 100644 unity/Example1/ProjectSettings/ClusterInputManager.asset create mode 100644 unity/Example1/ProjectSettings/DynamicsManager.asset create mode 100644 unity/Example1/ProjectSettings/EditorBuildSettings.asset create mode 100644 unity/Example1/ProjectSettings/EditorSettings.asset create mode 100644 unity/Example1/ProjectSettings/GraphicsSettings.asset create mode 100644 unity/Example1/ProjectSettings/InputManager.asset create mode 100644 unity/Example1/ProjectSettings/NavMeshAreas.asset create mode 100644 unity/Example1/ProjectSettings/Physics2DSettings.asset create mode 100644 unity/Example1/ProjectSettings/PresetManager.asset create mode 100644 unity/Example1/ProjectSettings/ProjectSettings.asset create mode 100644 unity/Example1/ProjectSettings/ProjectVersion.txt create mode 100644 unity/Example1/ProjectSettings/QualitySettings.asset create mode 100644 unity/Example1/ProjectSettings/TagManager.asset create mode 100644 unity/Example1/ProjectSettings/TimeManager.asset create mode 100644 unity/Example1/ProjectSettings/UnityConnectSettings.asset create mode 100644 unity/Example1/ProjectSettings/VFXManager.asset create mode 100644 unity/Example1/ProjectSettings/XRSettings.asset diff --git a/unity/Example1/Assets/Scenes.meta b/unity/Example1/Assets/Scenes.meta new file mode 100644 index 000000000..cfe6a703a --- /dev/null +++ b/unity/Example1/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c6efaef6be3992f41a63bc3702d54be3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Example1/Assets/Scenes/SampleScene.unity b/unity/Example1/Assets/Scenes/SampleScene.unity new file mode 100644 index 000000000..7cdec2a0a --- /dev/null +++ b/unity/Example1/Assets/Scenes/SampleScene.unity @@ -0,0 +1,259 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 705507994} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_TemporalCoherenceThreshold: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 10 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringMode: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ShowResolutionOverlay: 1 + m_LightingDataAsset: {fileID: 0} + m_UseShadowmask: 1 +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &705507993 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 705507995} + - component: {fileID: 705507994} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &705507994 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 1 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &705507995 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_GateFitMode: 2 + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/unity/Example1/Assets/Scenes/SampleScene.unity.meta b/unity/Example1/Assets/Scenes/SampleScene.unity.meta new file mode 100644 index 000000000..952bd1e9e --- /dev/null +++ b/unity/Example1/Assets/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9fc0d4010bbf28b4594072e72b8655ab +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Example1/Packages/manifest.json b/unity/Example1/Packages/manifest.json new file mode 100644 index 000000000..d7bcbaa56 --- /dev/null +++ b/unity/Example1/Packages/manifest.json @@ -0,0 +1,41 @@ +{ + "dependencies": { + "com.unity.ads": "2.0.8", + "com.unity.analytics": "3.3.2", + "com.unity.collab-proxy": "1.2.16", + "com.unity.package-manager-ui": "2.1.2", + "com.unity.purchasing": "2.0.6", + "com.unity.textmeshpro": "2.0.1", + "com.unity.timeline": "1.0.0", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/unity/Example1/ProjectSettings/AudioManager.asset b/unity/Example1/ProjectSettings/AudioManager.asset new file mode 100644 index 000000000..07ebfb05d --- /dev/null +++ b/unity/Example1/ProjectSettings/AudioManager.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 1024 diff --git a/unity/Example1/ProjectSettings/ClusterInputManager.asset b/unity/Example1/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 000000000..e7886b266 --- /dev/null +++ b/unity/Example1/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/unity/Example1/ProjectSettings/DynamicsManager.asset b/unity/Example1/ProjectSettings/DynamicsManager.asset new file mode 100644 index 000000000..cdc1f3eab --- /dev/null +++ b/unity/Example1/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_EnableUnifiedHeightmaps: 1 + m_DefaultMaxAngluarSpeed: 7 diff --git a/unity/Example1/ProjectSettings/EditorBuildSettings.asset b/unity/Example1/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 000000000..0147887ef --- /dev/null +++ b/unity/Example1/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/unity/Example1/ProjectSettings/EditorSettings.asset b/unity/Example1/ProjectSettings/EditorSettings.asset new file mode 100644 index 000000000..a66e506e7 --- /dev/null +++ b/unity/Example1/ProjectSettings/EditorSettings.asset @@ -0,0 +1,25 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 7 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 2 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp + m_ProjectGenerationRootNamespace: + m_CollabEditorSettings: + inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1 diff --git a/unity/Example1/ProjectSettings/GraphicsSettings.asset b/unity/Example1/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 000000000..74d7b532b --- /dev/null +++ b/unity/Example1/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,61 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 diff --git a/unity/Example1/ProjectSettings/InputManager.asset b/unity/Example1/ProjectSettings/InputManager.asset new file mode 100644 index 000000000..17c8f538e --- /dev/null +++ b/unity/Example1/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/unity/Example1/ProjectSettings/NavMeshAreas.asset b/unity/Example1/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 000000000..3b0b7c3d1 --- /dev/null +++ b/unity/Example1/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/unity/Example1/ProjectSettings/Physics2DSettings.asset b/unity/Example1/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 000000000..47880b1c8 --- /dev/null +++ b/unity/Example1/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 4 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/unity/Example1/ProjectSettings/PresetManager.asset b/unity/Example1/ProjectSettings/PresetManager.asset new file mode 100644 index 000000000..636a595b3 --- /dev/null +++ b/unity/Example1/ProjectSettings/PresetManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + m_DefaultList: [] diff --git a/unity/Example1/ProjectSettings/ProjectSettings.asset b/unity/Example1/ProjectSettings/ProjectSettings.asset new file mode 100644 index 000000000..394a51b6f --- /dev/null +++ b/unity/Example1/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,644 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 16 + productGUID: cb8d819fb927e4e41a8e9b2b71b742cc + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: Example1 + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1024 + defaultScreenHeight: 768 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosAppInBackgroundBehavior: 0 + displayResolutionDialog: 0 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidBlitType: 0 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + graphicsJobs: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + graphicsJobMode: 0 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + vulkanEnableSetSRGBWrite: 0 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + cardboard: + depthFormat: 0 + enableTransitionView: 0 + daydream: + depthFormat: 0 + useSustainedPerformanceMode: 0 + enableVideoLayer: 0 + useProtectedVideoMemory: 0 + minimumSupportedHeadTracking: 0 + maximumSupportedHeadTracking: 1 + hololens: + depthFormat: 1 + depthBufferSharingEnabled: 1 + lumin: + depthFormat: 0 + frameTiming: 2 + enableGLCache: 0 + glCacheMaxBlobSize: 524288 + glCacheMaxFileSize: 8388608 + oculus: + sharedDepthBuffer: 1 + dashSupport: 1 + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + protectGraphicsMemory: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: {} + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 16 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 9.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 9.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + iPhoneSplashScreen: {fileID: 0} + iPhoneHighResSplashScreen: {fileID: 0} + iPhoneTallHighResSplashScreen: {fileID: 0} + iPhone47inSplashScreen: {fileID: 0} + iPhone55inPortraitSplashScreen: {fileID: 0} + iPhone55inLandscapeSplashScreen: {fileID: 0} + iPhone58inPortraitSplashScreen: {fileID: 0} + iPhone58inLandscapeSplashScreen: {fileID: 0} + iPadPortraitSplashScreen: {fileID: 0} + iPadHighResPortraitSplashScreen: {fileID: 0} + iPadLandscapeSplashScreen: {fileID: 0} + iPadHighResLandscapeSplashScreen: {fileID: 0} + iPhone65inPortraitSplashScreen: {fileID: 0} + iPhone65inLandscapeSplashScreen: {fileID: 0} + iPhone61inPortraitSplashScreen: {fileID: 0} + iPhone61inLandscapeSplashScreen: {fileID: 0} + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSUseLaunchScreenStoryboard: 0 + iOSLaunchScreenCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea + templatePackageId: com.unity.template.3d@2.3.3 + templateDefaultScene: Assets/Scenes/SampleScene.unity + AndroidTargetArchitectures: 1 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: '{inproject}: ' + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + resolutionDialogBanner: {fileID: 0} + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 0 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 0 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + m_BuildTargetEnableVuforiaSettings: [] + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 3 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLWasmStreaming: 0 + scriptingDefineSymbols: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + allowUnsafeCode: 0 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 0 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_3D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_3D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, + a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + xboxOneScriptCompiler: 1 + XboxOneOverrideIdentityName: + vrEditorSettings: + daydream: + daydreamIconForeground: {fileID: 0} + daydreamIconBackground: {fileID: 0} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + facebookSdkVersion: 7.9.4 + facebookAppId: + facebookCookies: 1 + facebookLogging: 1 + facebookStatus: 1 + facebookXfbml: 0 + facebookFrictionlessRequests: 1 + apiCompatibilityLevel: 6 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + projectName: + organizationId: + cloudEnabled: 0 + enableNativePlatformBackendsForNewInputSystem: 0 + disableOldInputManagerSupport: 0 + legacyClampBlendShapeWeights: 0 diff --git a/unity/Example1/ProjectSettings/ProjectVersion.txt b/unity/Example1/ProjectSettings/ProjectVersion.txt new file mode 100644 index 000000000..93895bd69 --- /dev/null +++ b/unity/Example1/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2019.1.10f1 +m_EditorVersionWithRevision: 2019.1.10f1 (f007ed779b7a) diff --git a/unity/Example1/ProjectSettings/QualitySettings.asset b/unity/Example1/ProjectSettings/QualitySettings.asset new file mode 100644 index 000000000..ed26313a8 --- /dev/null +++ b/unity/Example1/ProjectSettings/QualitySettings.asset @@ -0,0 +1,231 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Lumin: 5 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSP2: 2 + Standalone: 5 + WebGL: 3 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/unity/Example1/ProjectSettings/TagManager.asset b/unity/Example1/ProjectSettings/TagManager.asset new file mode 100644 index 000000000..1c92a7840 --- /dev/null +++ b/unity/Example1/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/unity/Example1/ProjectSettings/TimeManager.asset b/unity/Example1/ProjectSettings/TimeManager.asset new file mode 100644 index 000000000..558a017e1 --- /dev/null +++ b/unity/Example1/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/unity/Example1/ProjectSettings/UnityConnectSettings.asset b/unity/Example1/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 000000000..fa0b14657 --- /dev/null +++ b/unity/Example1/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/unity/Example1/ProjectSettings/VFXManager.asset b/unity/Example1/ProjectSettings/VFXManager.asset new file mode 100644 index 000000000..6e0eaca40 --- /dev/null +++ b/unity/Example1/ProjectSettings/VFXManager.asset @@ -0,0 +1,11 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/unity/Example1/ProjectSettings/XRSettings.asset b/unity/Example1/ProjectSettings/XRSettings.asset new file mode 100644 index 000000000..482590c19 --- /dev/null +++ b/unity/Example1/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file From 0fca1f8b3916e504f1699746d4c8bfcf99a0f0de Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 15:46:40 +0200 Subject: [PATCH 4/9] add some basic code where an unity app connects with a basic JS client --- unity/Example1/Assets/Controller.cs | 47 +++++ unity/Example1/Assets/Controller.cs.meta | 11 ++ unity/Example1/Assets/Plugins.meta | 8 + .../Assets/Plugins/websocket-sharp.dll | Bin 0 -> 255488 bytes .../Assets/Plugins/websocket-sharp.dll.meta | 33 ++++ .../Example1/Assets/Scenes/SampleScene.unity | 165 ++++++++++++++++-- .../ProjectSettings/EditorBuildSettings.asset | 5 +- .../ProjectSettings/GraphicsSettings.asset | 3 + .../UnityConnectSettings.asset | 2 +- web/Example1/index.html | 14 ++ web/Example1/main.js | 13 ++ 11 files changed, 287 insertions(+), 14 deletions(-) create mode 100644 unity/Example1/Assets/Controller.cs create mode 100644 unity/Example1/Assets/Controller.cs.meta create mode 100644 unity/Example1/Assets/Plugins.meta create mode 100644 unity/Example1/Assets/Plugins/websocket-sharp.dll create mode 100644 unity/Example1/Assets/Plugins/websocket-sharp.dll.meta create mode 100644 web/Example1/index.html create mode 100644 web/Example1/main.js diff --git a/unity/Example1/Assets/Controller.cs b/unity/Example1/Assets/Controller.cs new file mode 100644 index 000000000..e27ceef87 --- /dev/null +++ b/unity/Example1/Assets/Controller.cs @@ -0,0 +1,47 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +using WebSocketSharp; +using WebSocketSharp.Server; + +public class Controller : MonoBehaviour +{ + private WebSocketServer m_WSServer = null; + + public class Laputa : WebSocketBehavior + { + protected override void OnMessage(MessageEventArgs e) + { + var msg = e.Data == "BALUS" + ? "I've been balused already..." + : "I'm not available now."; + + Send(msg); + } + } + + // Start is called before the first frame update + void Start() + { + Debug.Log("Start"); + + m_WSServer = new WebSocketServer("ws://127.0.0.1:55555"); + m_WSServer.AddWebSocketService("/Laputa"); + m_WSServer.Start(); + + Debug.Log("Start ended"); + } + + void OnDestroy() + { + Debug.Log("OnDestroy"); + m_WSServer.Stop(); + m_WSServer = null; + } + + // Update is called once per frame + void Update() + { + } +} diff --git a/unity/Example1/Assets/Controller.cs.meta b/unity/Example1/Assets/Controller.cs.meta new file mode 100644 index 000000000..44d3963e8 --- /dev/null +++ b/unity/Example1/Assets/Controller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 282c6ca1d508a694390db02a289b422c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Example1/Assets/Plugins.meta b/unity/Example1/Assets/Plugins.meta new file mode 100644 index 000000000..3901647f1 --- /dev/null +++ b/unity/Example1/Assets/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2fc666e5d11fa2c4eb13a0132c2a2d87 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/unity/Example1/Assets/Plugins/websocket-sharp.dll b/unity/Example1/Assets/Plugins/websocket-sharp.dll new file mode 100644 index 0000000000000000000000000000000000000000..c3e9db37254f04c9669f772c629b04154dee1b66 GIT binary patch literal 255488 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�`So;*3v1;=d&FI|l1*q}C< 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 + + + + + + + + Example 1 + + + + + \ No newline at end of file diff --git a/web/Example1/main.js b/web/Example1/main.js new file mode 100644 index 000000000..2ebb609cc --- /dev/null +++ b/web/Example1/main.js @@ -0,0 +1,13 @@ +$(document).ready(function () { + console.log("go"); + + const connection = new WebSocket("ws://127.0.0.1:55555/Laputa"); + connection.onopen = () => { + console.log("opened"); + } + + connection.onerror = error => { + console.log("WebSocket error"); + console.log(error); + } +}); \ No newline at end of file From 8e7a32173fbe31cfc04a5c99638ebb8569f4f9de Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 16:07:19 +0200 Subject: [PATCH 5/9] send message to unity WSServer and get response based on it --- web/Example1/main.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/Example1/main.js b/web/Example1/main.js index 2ebb609cc..bedfa92e0 100644 --- a/web/Example1/main.js +++ b/web/Example1/main.js @@ -4,10 +4,20 @@ $(document).ready(function () { const connection = new WebSocket("ws://127.0.0.1:55555/Laputa"); connection.onopen = () => { console.log("opened"); + connection.send('BALUS'); } connection.onerror = error => { console.log("WebSocket error"); console.log(error); } + + connection.onclose = e => { + console.log("connection closes"); + console.log(e); + } + + connection.onmessage = (e) => { + console.log(e.data); + } }); \ No newline at end of file From cf5c1ba05137413d9e38e8fb3fd4e0360ded2656 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Tue, 16 Jul 2019 17:26:48 +0200 Subject: [PATCH 6/9] add three.js stuff. --- web/Example1/OrbitControls.js | 1070 +++++++++++++++++++++++++++++++++ web/Example1/index.html | 4 + web/Example1/main.js | 67 ++- 3 files changed, 1140 insertions(+), 1 deletion(-) create mode 100644 web/Example1/OrbitControls.js diff --git a/web/Example1/OrbitControls.js b/web/Example1/OrbitControls.js new file mode 100644 index 000000000..87841da4f --- /dev/null +++ b/web/Example1/OrbitControls.js @@ -0,0 +1,1070 @@ +/** + * @author qiao / https://github.com/qiao + * @author mrdoob / http://mrdoob.com + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author erich666 / http://erichaines.com + */ + +// This set of controls performs orbiting, dollying (zooming), and panning. +// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). +// +// Orbit - left mouse / touch: one-finger move +// Zoom - middle mouse, or mousewheel / touch: two-finger spread or squish +// Pan - right mouse, or left mouse + ctrl/meta/shiftKey, or arrow keys / touch: two-finger move + +THREE.OrbitControls = function ( object, domElement ) { + + this.object = object; + + this.domElement = ( domElement !== undefined ) ? domElement : document; + + // Set to false to disable this control + this.enabled = true; + + // "target" sets the location of focus, where the object orbits around + this.target = new THREE.Vector3(); + + // How far you can dolly in and out ( PerspectiveCamera only ) + this.minDistance = 0; + this.maxDistance = Infinity; + + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; + this.rotateSpeed = 1.0; + + // Set to false to disable panning + this.enablePan = true; + this.panSpeed = 1.0; + this.screenSpacePanning = false; // if true, pan in screen-space + this.keyPanSpeed = 7.0; // pixels moved per arrow key push + + // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop + this.autoRotate = false; + this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 + + // Set to false to disable use of the keys + this.enableKeys = true; + + // The four arrow keys + this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; + + // Mouse buttons + this.mouseButtons = { LEFT: THREE.MOUSE.LEFT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.RIGHT }; + + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; + + // + // public methods + // + + this.getPolarAngle = function () { + + return spherical.phi; + + }; + + this.getAzimuthalAngle = function () { + + return spherical.theta; + + }; + + this.saveState = function () { + + scope.target0.copy( scope.target ); + scope.position0.copy( scope.object.position ); + scope.zoom0 = scope.object.zoom; + + }; + + this.reset = function () { + + scope.target.copy( scope.target0 ); + scope.object.position.copy( scope.position0 ); + scope.object.zoom = scope.zoom0; + + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); + + scope.update(); + + state = STATE.NONE; + + }; + + // this method is exposed, but perhaps it would be better if we can make it private... + this.update = function () { + + var offset = new THREE.Vector3(); + + // so camera.up is the orbit axis + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); + + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); + + return function update() { + + var position = scope.object.position; + + offset.copy( position ).sub( scope.target ); + + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); + + // angle from z-axis around y-axis + spherical.setFromVector3( offset ); + + if ( scope.autoRotate && state === STATE.NONE ) { + + rotateLeft( getAutoRotationAngle() ); + + } + + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; + + // restrict theta to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); + + // restrict phi to be between desired limits + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); + + spherical.makeSafe(); + + + spherical.radius *= scale; + + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); + + // move target to panned location + scope.target.add( panOffset ); + + offset.setFromSpherical( spherical ); + + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); + + position.copy( scope.target ).add( offset ); + + scope.object.lookAt( scope.target ); + + if ( scope.enableDamping === true ) { + + sphericalDelta.theta *= ( 1 - scope.dampingFactor ); + sphericalDelta.phi *= ( 1 - scope.dampingFactor ); + + panOffset.multiplyScalar( 1 - scope.dampingFactor ); + + } else { + + sphericalDelta.set( 0, 0, 0 ); + + panOffset.set( 0, 0, 0 ); + + } + + scale = 1; + + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 + + if ( zoomChanged || + lastPosition.distanceToSquared( scope.object.position ) > EPS || + 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { + + scope.dispatchEvent( changeEvent ); + + lastPosition.copy( scope.object.position ); + lastQuaternion.copy( scope.object.quaternion ); + zoomChanged = false; + + return true; + + } + + return false; + + }; + + }(); + + this.dispose = function () { + + scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); + scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.removeEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + window.removeEventListener( 'keydown', onKeyDown, false ); + + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? + + }; + + // + // internals + // + + var scope = this; + + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; + + var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 }; + + var state = STATE.NONE; + + var EPS = 0.000001; + + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); + + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; + + var rotateStart = new THREE.Vector2(); + var rotateEnd = new THREE.Vector2(); + var rotateDelta = new THREE.Vector2(); + + var panStart = new THREE.Vector2(); + var panEnd = new THREE.Vector2(); + var panDelta = new THREE.Vector2(); + + var dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); + + function getAutoRotationAngle() { + + return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; + + } + + function getZoomScale() { + + return Math.pow( 0.95, scope.zoomSpeed ); + + } + + function rotateLeft( angle ) { + + sphericalDelta.theta -= angle; + + } + + function rotateUp( angle ) { + + sphericalDelta.phi -= angle; + + } + + var panLeft = function () { + + var v = new THREE.Vector3(); + + return function panLeft( distance, objectMatrix ) { + + v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix + v.multiplyScalar( - distance ); + + panOffset.add( v ); + + }; + + }(); + + var panUp = function () { + + var v = new THREE.Vector3(); + + return function panUp( distance, objectMatrix ) { + + if ( scope.screenSpacePanning === true ) { + + v.setFromMatrixColumn( objectMatrix, 1 ); + + } else { + + v.setFromMatrixColumn( objectMatrix, 0 ); + v.crossVectors( scope.object.up, v ); + + } + + v.multiplyScalar( distance ); + + panOffset.add( v ); + + }; + + }(); + + // deltaX and deltaY are in pixels; right and down are positive + var pan = function () { + + var offset = new THREE.Vector3(); + + return function pan( deltaX, deltaY ) { + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object.isPerspectiveCamera ) { + + // perspective + var position = scope.object.position; + offset.copy( position ).sub( scope.target ); + var targetDistance = offset.length(); + + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); + + // we use only clientHeight here so aspect ratio does not distort speed + panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); + panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); + + } else if ( scope.object.isOrthographicCamera ) { + + // orthographic + panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); + panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); + + } else { + + // camera neither orthographic nor perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + scope.enablePan = false; + + } + + }; + + }(); + + function dollyIn( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + function dollyOut( dollyScale ) { + + if ( scope.object.isPerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object.isOrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; + + } + + } + + // + // event callbacks - update the object state + // + + function handleMouseDownRotate( event ) { + + //console.log( 'handleMouseDownRotate' ); + + rotateStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownDolly( event ) { + + //console.log( 'handleMouseDownDolly' ); + + dollyStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownPan( event ) { + + //console.log( 'handleMouseDownPan' ); + + panStart.set( event.clientX, event.clientY ); + + } + + function handleMouseMoveRotate( event ) { + + //console.log( 'handleMouseMoveRotate' ); + + rotateEnd.set( event.clientX, event.clientY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleMouseMoveDolly( event ) { + + //console.log( 'handleMouseMoveDolly' ); + + dollyEnd.set( event.clientX, event.clientY ); + + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyIn( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyOut( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleMouseMovePan( event ) { + + //console.log( 'handleMouseMovePan' ); + + panEnd.set( event.clientX, event.clientY ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleMouseUp( event ) { + + // console.log( 'handleMouseUp' ); + + } + + function handleMouseWheel( event ) { + + // console.log( 'handleMouseWheel' ); + + if ( event.deltaY < 0 ) { + + dollyOut( getZoomScale() ); + + } else if ( event.deltaY > 0 ) { + + dollyIn( getZoomScale() ); + + } + + scope.update(); + + } + + function handleKeyDown( event ) { + + // console.log( 'handleKeyDown' ); + + var needsUpdate = false; + + switch ( event.keyCode ) { + + case scope.keys.UP: + pan( 0, scope.keyPanSpeed ); + needsUpdate = true; + break; + + case scope.keys.BOTTOM: + pan( 0, - scope.keyPanSpeed ); + needsUpdate = true; + break; + + case scope.keys.LEFT: + pan( scope.keyPanSpeed, 0 ); + needsUpdate = true; + break; + + case scope.keys.RIGHT: + pan( - scope.keyPanSpeed, 0 ); + needsUpdate = true; + break; + + } + + if ( needsUpdate ) { + + // prevent the browser from scrolling on cursor keys + event.preventDefault(); + + scope.update(); + + } + + + } + + function handleTouchStartRotate( event ) { + + //console.log( 'handleTouchStartRotate' ); + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchStartDollyPan( event ) { + + //console.log( 'handleTouchStartDollyPan' ); + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyStart.set( 0, distance ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panStart.set( x, y ); + + } + + } + + function handleTouchMoveRotate( event ) { + + //console.log( 'handleTouchMoveRotate' ); + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height + + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleTouchMoveDollyPan( event ) { + + //console.log( 'handleTouchMoveDollyPan' ); + + if ( scope.enableZoom ) { + + var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; + var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; + + var distance = Math.sqrt( dx * dx + dy * dy ); + + dollyEnd.set( 0, distance ); + + dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) ); + + dollyIn( dollyDelta.y ); + + dollyStart.copy( dollyEnd ); + + } + + if ( scope.enablePan ) { + + var x = 0.5 * ( event.touches[ 0 ].pageX + event.touches[ 1 ].pageX ); + var y = 0.5 * ( event.touches[ 0 ].pageY + event.touches[ 1 ].pageY ); + + panEnd.set( x, y ); + + panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + } + + scope.update(); + + } + + function handleTouchEnd( event ) { + + //console.log( 'handleTouchEnd' ); + + } + + // + // event handlers - FSM: listen for events and reset state + // + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + + // Prevent the browser from scrolling. + + event.preventDefault(); + + // Manually set the focus since calling preventDefault above + // prevents the browser from setting it automatically. + + scope.domElement.focus ? scope.domElement.focus() : window.focus(); + + switch ( event.button ) { + + case scope.mouseButtons.LEFT: + + if ( event.ctrlKey || event.metaKey || event.shiftKey ) { + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + } else { + + if ( scope.enableRotate === false ) return; + + handleMouseDownRotate( event ); + + state = STATE.ROTATE; + + } + + break; + + case scope.mouseButtons.MIDDLE: + + if ( scope.enableZoom === false ) return; + + handleMouseDownDolly( event ); + + state = STATE.DOLLY; + + break; + + case scope.mouseButtons.RIGHT: + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + break; + + } + + if ( state !== STATE.NONE ) { + + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( startEvent ); + + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( state ) { + + case STATE.ROTATE: + + if ( scope.enableRotate === false ) return; + + handleMouseMoveRotate( event ); + + break; + + case STATE.DOLLY: + + if ( scope.enableZoom === false ) return; + + handleMouseMoveDolly( event ); + + break; + + case STATE.PAN: + + if ( scope.enablePan === false ) return; + + handleMouseMovePan( event ); + + break; + + } + + } + + function onMouseUp( event ) { + + if ( scope.enabled === false ) return; + + handleMouseUp( event ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; + + event.preventDefault(); + event.stopPropagation(); + + scope.dispatchEvent( startEvent ); + + handleMouseWheel( event ); + + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; + + handleKeyDown( event ); + + } + + function onTouchStart( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + + handleTouchStartRotate( event ); + + state = STATE.TOUCH_ROTATE; + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + + handleTouchStartDollyPan( event ); + + state = STATE.TOUCH_DOLLY_PAN; + + break; + + default: + + state = STATE.NONE; + + } + + if ( state !== STATE.NONE ) { + + scope.dispatchEvent( startEvent ); + + } + + } + + function onTouchMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.touches.length ) { + + case 1: // one-fingered touch: rotate + + if ( scope.enableRotate === false ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed? + + handleTouchMoveRotate( event ); + + break; + + case 2: // two-fingered touch: dolly-pan + + if ( scope.enableZoom === false && scope.enablePan === false ) return; + if ( state !== STATE.TOUCH_DOLLY_PAN ) return; // is this needed? + + handleTouchMoveDollyPan( event ); + + break; + + default: + + state = STATE.NONE; + + } + + } + + function onTouchEnd( event ) { + + if ( scope.enabled === false ) return; + + handleTouchEnd( event ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onContextMenu( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + } + + // + + scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); + + scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.addEventListener( 'wheel', onMouseWheel, false ); + + scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + + this.update(); + +}; + +THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); +THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; + +Object.defineProperties( THREE.OrbitControls.prototype, { + + center: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); + return this.target; + + } + + }, + + // backward compatibility + + noZoom: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + return ! this.enableZoom; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + this.enableZoom = ! value; + + } + + }, + + noRotate: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + return ! this.enableRotate; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + this.enableRotate = ! value; + + } + + }, + + noPan: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + return ! this.enablePan; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + this.enablePan = ! value; + + } + + }, + + noKeys: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + return ! this.enableKeys; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + this.enableKeys = ! value; + + } + + }, + + staticMoving: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + return ! this.enableDamping; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + this.enableDamping = ! value; + + } + + }, + + dynamicDampingFactor: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + return this.dampingFactor; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + this.dampingFactor = value; + + } + + } + +} ); diff --git a/web/Example1/index.html b/web/Example1/index.html index f250a6909..6f6c166b8 100644 --- a/web/Example1/index.html +++ b/web/Example1/index.html @@ -5,10 +5,14 @@ + + Example 1 + +
\ No newline at end of file diff --git a/web/Example1/main.js b/web/Example1/main.js index bedfa92e0..f355f12e8 100644 --- a/web/Example1/main.js +++ b/web/Example1/main.js @@ -1,7 +1,71 @@ +let connection; +let container; +let scene; +let camera; +let controls; +let mesh; +let mousePressed = false; + +function initThreeJS (){ + container = document.querySelector( '#scene-container' ); + + // scene + scene = new THREE.Scene(); + scene.background = new THREE.Color( 0x7FBCDD ); + // camera + camera = new THREE.PerspectiveCamera(35, container.clientWidth / container.clientHeight, 0.1, 100,); + camera.position.set( -4, 4, 10 ); + // controls + controls = new THREE.OrbitControls( camera, container ); + // mesh + const geometry = new THREE.BoxBufferGeometry( 2, 2, 2 ); + const material = new THREE.MeshStandardMaterial( { color: 0x005000 } ); + mesh = new THREE.Mesh( geometry, material ); + scene.add( mesh ); + // light + const ambientLight = new THREE.HemisphereLight(0xffaaff, 0x202020, 6); + const mainLight = new THREE.DirectionalLight( 0xffffff, 4 ); + mainLight.position.set( 10, 10, 10 ); + scene.add( ambientLight, mainLight ); + // renderer + renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setSize( container.clientWidth, container.clientHeight ); + renderer.setPixelRatio( window.devicePixelRatio ); + container.appendChild( renderer.domElement ); + + // start the animation loop + renderer.setAnimationLoop( () => { + renderer.render( scene, camera ); + } ); +} + +function initMouseEvents (){ + container = document.querySelector( '#scene-container' ); + container.onmousemove = function(){ + if(mousePressed){ + sendAngles(controls.getAzimuthalAngle(), controls.getPolarAngle()); + } + }; + container.onmousedown = function(){ + mousePressed = true; + } + container.onmouseup = function(){ + mousePressed = false; + } +} + +function sendAngles(azimuth, elevation){ + // todo: send this stuff over websocket to the server + console.log(azimuth + ' ' + elevation); +} + $(document).ready(function () { console.log("go"); - const connection = new WebSocket("ws://127.0.0.1:55555/Laputa"); + initThreeJS(); + initMouseEvents(); + + connection = new WebSocket("ws://127.0.0.1:55555/Laputa"); connection.onopen = () => { console.log("opened"); connection.send('BALUS'); @@ -20,4 +84,5 @@ $(document).ready(function () { connection.onmessage = (e) => { console.log(e.data); } + }); \ No newline at end of file From 446a1b6a1f074529ed2ef1a93387e5edb278a003 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Wed, 17 Jul 2019 11:17:37 +0200 Subject: [PATCH 7/9] init js websocket and send data to server as json --- web/Example1/index.html | 4 ++- web/Example1/main.css | 5 ++++ web/Example1/main.js | 56 ++++++++++++++++++++++---------------- web/Example1/notify.min.js | 1 + 4 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 web/Example1/main.css create mode 100644 web/Example1/notify.min.js diff --git a/web/Example1/index.html b/web/Example1/index.html index 6f6c166b8..b02d52e5a 100644 --- a/web/Example1/index.html +++ b/web/Example1/index.html @@ -6,13 +6,15 @@ + + Example 1 -
+
\ No newline at end of file diff --git a/web/Example1/main.css b/web/Example1/main.css new file mode 100644 index 000000000..6dbabaf4f --- /dev/null +++ b/web/Example1/main.css @@ -0,0 +1,5 @@ +#scene-container { + width: 100%; + height: 100%; + position: absolute; +} diff --git a/web/Example1/main.js b/web/Example1/main.js index f355f12e8..552ed9c0c 100644 --- a/web/Example1/main.js +++ b/web/Example1/main.js @@ -1,4 +1,4 @@ -let connection; +let wsocket; let container; let scene; let camera; @@ -54,35 +54,43 @@ function initMouseEvents (){ } } -function sendAngles(azimuth, elevation){ - // todo: send this stuff over websocket to the server - console.log(azimuth + ' ' + elevation); -} - -$(document).ready(function () { - console.log("go"); - - initThreeJS(); - initMouseEvents(); - - connection = new WebSocket("ws://127.0.0.1:55555/Laputa"); - connection.onopen = () => { - console.log("opened"); - connection.send('BALUS'); +function initWebSocket (addr){ + wsocket = new WebSocket(addr); + // set callbacks + wsocket.onopen = () => { + console.log("websocket onopen"); + $.notify("Connected to server", "success"); } - - connection.onerror = error => { - console.log("WebSocket error"); + wsocket.onerror = error => { console.log(error); + $.notify("WebSocket Error", "error"); } - - connection.onclose = e => { - console.log("connection closes"); + wsocket.onclose = e => { console.log(e); + let msg = e.reason ? "connection closed with the reason: " + e.reason : "connection closed without any reason"; + $.notify(msg, "warn"); } - - connection.onmessage = (e) => { + wsocket.onmessage = (e) => { + console.log("message received from server"); console.log(e.data); } +} + +function sendAngles(azimuth, elevation){ + if(wsocket.readyState === WebSocket.OPEN){ + wsocket.send(JSON.stringify({ + az: azimuth, + el: elevation + })); + } +} + +$(document).ready(function () { + // more here: https://notifyjs.jpillora.com + $.notify.defaults( {globalPosition: "top left"} ); + + initThreeJS(); + initMouseEvents(); + initWebSocket("ws://127.0.0.1:55555/Laputa"); }); \ No newline at end of file diff --git a/web/Example1/notify.min.js b/web/Example1/notify.min.js new file mode 100644 index 000000000..6766fd1d8 --- /dev/null +++ b/web/Example1/notify.min.js @@ -0,0 +1 @@ +(function(e){typeof define=="function"&&define.amd?define(["jquery"],e):typeof module=="object"&&module.exports?module.exports=function(t,n){return n===undefined&&(typeof window!="undefined"?n=require("jquery"):n=require("jquery")(t)),e(n),n}:e(jQuery)})(function(e){function A(t,n,i){typeof i=="string"&&(i={className:i}),this.options=E(w,e.isPlainObject(i)?i:{}),this.loadHTML(),this.wrapper=e(h.html),this.options.clickToHide&&this.wrapper.addClass(r+"-hidable"),this.wrapper.data(r,this),this.arrow=this.wrapper.find("."+r+"-arrow"),this.container=this.wrapper.find("."+r+"-container"),this.container.append(this.userContainer),t&&t.length&&(this.elementType=t.attr("type"),this.originalElement=t,this.elem=N(t),this.elem.data(r,this),this.elem.before(this.wrapper)),this.container.hide(),this.run(n)}var t=[].indexOf||function(e){for(var t=0,n=this.length;t\n
\n
\n',css:"."+r+"-corner {\n position: fixed;\n margin: 5px;\n z-index: 1050;\n}\n\n."+r+"-corner ."+r+"-wrapper,\n."+r+"-corner ."+r+"-container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n margin: 3px;\n}\n\n."+r+"-wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n."+r+"-container {\n display: none;\n z-index: 1;\n position: absolute;\n}\n\n."+r+"-hidable {\n cursor: pointer;\n}\n\n[data-notify-text],[data-notify-html] {\n position: relative;\n}\n\n."+r+"-arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}"},p={"border-radius":["-webkit-","-moz-"]},d=function(e){return c[e]},v=function(e){if(!e)throw"Missing Style name";c[e]&&delete c[e]},m=function(t,i){if(!t)throw"Missing Style name";if(!i)throw"Missing Style definition";if(!i.html)throw"Missing Style HTML";var s=c[t];s&&s.cssElem&&(window.console&&console.warn(n+": overwriting style '"+t+"'"),c[t].cssElem.remove()),i.name=t,c[t]=i;var o="";i.classes&&e.each(i.classes,function(t,n){return o+="."+r+"-"+i.name+"-"+t+" {\n",e.each(n,function(t,n){return p[t]&&e.each(p[t],function(e,r){return o+=" "+r+t+": "+n+";\n"}),o+=" "+t+": "+n+";\n"}),o+="}\n"}),i.css&&(o+="/* styles for "+i.name+" */\n"+i.css),o&&(i.cssElem=g(o),i.cssElem.attr("id","notify-"+i.name));var u={},a=e(i.html);y("html",a,u),y("text",a,u),i.fields=u},g=function(t){var n,r,i;r=x("style"),r.attr("type","text/css"),e("head").append(r);try{r.html(t)}catch(s){r[0].styleSheet.cssText=t}return r},y=function(t,n,r){var s;return t!=="html"&&(t="text"),s="data-notify-"+t,b(n,"["+s+"]").each(function(){var n;n=e(this).attr(s),n||(n=i),r[n]=t})},b=function(e,t){return e.is(t)?e:e.find(t)},w={clickToHide:!0,autoHide:!0,autoHideDelay:5e3,arrowShow:!0,arrowSize:5,breakNewLines:!0,elementPosition:"bottom",globalPosition:"top right",style:"bootstrap",className:"error",showAnimation:"slideDown",showDuration:400,hideAnimation:"slideUp",hideDuration:200,gap:5},E=function(t,n){var r;return r=function(){},r.prototype=t,e.extend(!0,new r,n)},S=function(t){return e.extend(w,t)},x=function(t){return e("<"+t+">")},T={},N=function(t){var n;return t.is("[type=radio]")&&(n=t.parents("form:first").find("[type=radio]").filter(function(n,r){return e(r).attr("name")===t.attr("name")}),t=n.first()),t},C=function(e,t,n){var r,i;if(typeof n=="string")n=parseInt(n,10);else if(typeof n!="number")return;if(isNaN(n))return;return r=s[f[t.charAt(0)]],i=t,e[r]!==undefined&&(t=s[r.charAt(0)],n=-n),e[t]===undefined?e[t]=n:e[t]+=n,null},k=function(e,t,n){if(e==="l"||e==="t")return 0;if(e==="c"||e==="m")return n/2-t/2;if(e==="r"||e==="b")return n-t;throw"Invalid alignment"},L=function(e){return L.e=L.e||x("div"),L.e.text(e).html()};A.prototype.loadHTML=function(){var t;t=this.getStyle(),this.userContainer=e(t.html),this.userFields=t.fields},A.prototype.show=function(e,t){var n,r,i,s,o;r=function(n){return function(){!e&&!n.elem&&n.destroy();if(t)return t()}}(this),o=this.container.parent().parents(":hidden").length>0,i=this.container.add(this.arrow),n=[];if(o&&e)s="show";else if(o&&!e)s="hide";else if(!o&&e)s=this.options.showAnimation,n.push(this.options.showDuration);else{if(!!o||!!e)return r();s=this.options.hideAnimation,n.push(this.options.hideDuration)}return n.push(r),i[s].apply(i,n)},A.prototype.setGlobalPosition=function(){var t=this.getPosition(),n=t[0],i=t[1],o=s[n],u=s[i],a=n+"|"+i,f=T[a];if(!f||!document.body.contains(f[0])){f=T[a]=x("div");var l={};l[o]=0,u==="middle"?l.top="45%":u==="center"?l.left="45%":l[u]=0,f.css(l).addClass(r+"-corner"),e("body").append(f)}return f.prepend(this.wrapper)},A.prototype.setElementPosition=function(){var n,r,i,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,L,A,O,M,_,D,P,H,B,j;H=this.getPosition(),_=H[0],O=H[1],M=H[2],g=this.elem.position(),d=this.elem.outerHeight(),y=this.elem.outerWidth(),v=this.elem.innerHeight(),m=this.elem.innerWidth(),j=this.wrapper.position(),c=this.container.height(),h=this.container.width(),T=s[_],L=f[_],A=s[L],p={},p[A]=_==="b"?d:_==="r"?y:0,C(p,"top",g.top-j.top),C(p,"left",g.left-j.left),B=["top","left"];for(w=0,S=B.length;w=0&&C(r,s[O],i*2)}t.call(u,_)>=0?(C(p,"left",k(O,h,y)),r&&C(r,"left",k(O,i,m))):t.call(o,_)>=0&&(C(p,"top",k(O,c,d)),r&&C(r,"top",k(O,i,v))),this.container.is(":visible")&&(p.display="block"),this.container.removeAttr("style").css(p);if(r)return this.arrow.removeAttr("style").css(r)},A.prototype.getPosition=function(){var e,n,r,i,s,f,c,h;h=this.options.position||(this.elem?this.options.elementPosition:this.options.globalPosition),e=l(h),e.length===0&&(e[0]="b");if(n=e[0],t.call(a,n)<0)throw"Must be one of ["+a+"]";if(e.length===1||(r=e[0],t.call(u,r)>=0)&&(i=e[1],t.call(o,i)<0)||(s=e[0],t.call(o,s)>=0)&&(f=e[1],t.call(u,f)<0))e[1]=(c=e[0],t.call(o,c)>=0)?"m":"l";return e.length===2&&(e[2]=e[1]),e},A.prototype.getStyle=function(e){var t;e||(e=this.options.style),e||(e="default"),t=c[e];if(!t)throw"Missing style: "+e;return t},A.prototype.updateClasses=function(){var t,n;return t=["base"],e.isArray(this.options.className)?t=t.concat(this.options.className):this.options.className&&t.push(this.options.className),n=this.getStyle(),t=e.map(t,function(e){return r+"-"+n.name+"-"+e}).join(" "),this.userContainer.attr("class",t)},A.prototype.run=function(t,n){var r,s,o,u,a;e.isPlainObject(n)?e.extend(this.options,n):e.type(n)==="string"&&(this.options.className=n);if(this.container&&!t){this.show(!1);return}if(!this.container&&!t)return;s={},e.isPlainObject(t)?s=t:s[i]=t;for(o in s){r=s[o],u=this.userFields[o];if(!u)continue;u==="text"&&(r=L(r),this.options.breakNewLines&&(r=r.replace(/\n/g,"
"))),a=o===i?"":"="+o,b(this.userContainer,"[data-notify-"+u+a+"]").html(r)}this.updateClasses(),this.elem?this.setElementPosition():this.setGlobalPosition(),this.show(!0),this.options.autoHide&&(clearTimeout(this.autohideTimer),this.autohideTimer=setTimeout(this.show.bind(this,!1),this.options.autoHideDelay))},A.prototype.destroy=function(){this.wrapper.data(r,null),this.wrapper.remove()},e[n]=function(t,r,i){return t&&t.nodeName||t.jquery?e(t)[n](r,i):(i=r,r=t,new A(null,r,i)),t},e.fn[n]=function(t,n){return e(this).each(function(){var i=N(e(this)).data(r);i&&i.destroy();var s=new A(e(this),t,n)}),this},e.extend(e[n],{defaults:S,addStyle:m,removeStyle:v,pluginOptions:w,getStyle:d,insertCSS:g}),m("bootstrap",{html:"
\n\n
",classes:{base:{"font-weight":"bold",padding:"8px 15px 8px 14px","text-shadow":"0 1px 0 rgba(255, 255, 255, 0.5)","background-color":"#fcf8e3",border:"1px solid #fbeed5","border-radius":"4px","white-space":"nowrap","padding-left":"25px","background-repeat":"no-repeat","background-position":"3px 7px"},error:{color:"#B94A48","background-color":"#F2DEDE","border-color":"#EED3D7","background-image":"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)"},success:{color:"#468847","background-color":"#DFF0D8","border-color":"#D6E9C6","background-image":"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)"},info:{color:"#3A87AD","background-color":"#D9EDF7","border-color":"#BCE8F1","background-image":"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)"},warn:{color:"#C09853","background-color":"#FCF8E3","border-color":"#FBEED5","background-image":"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)"}}}),e(function(){g(h.css).attr("id","core-notify"),e(document).on("click","."+r+"-hidable",function(t){e(this).trigger("notify-hide")}),e(document).on("notify-hide","."+r+"-wrapper",function(t){var n=e(this).data(r);n&&n.show(!1)})})}) \ No newline at end of file From f24de1d30e436ba8cd4c083a4ab42da19faeffc8 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Wed, 17 Jul 2019 12:07:44 +0200 Subject: [PATCH 8/9] add bootstrap and set up input group for websocket address stuff --- web/Example1/index.html | 26 +++++++++++++++++++++++--- web/Example1/main.css | 9 ++++++--- web/Example1/main.js | 20 +++++++++++++------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/web/Example1/index.html b/web/Example1/index.html index b02d52e5a..f0ab3e865 100644 --- a/web/Example1/index.html +++ b/web/Example1/index.html @@ -6,15 +6,35 @@ + + + Example 1 - -
- +
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/web/Example1/main.css b/web/Example1/main.css index 6dbabaf4f..26d2c2b6f 100644 --- a/web/Example1/main.css +++ b/web/Example1/main.css @@ -1,5 +1,8 @@ +.page-header { + padding-top: 10px; + padding-bottom: 10px; +} + #scene-container { - width: 100%; - height: 100%; - position: absolute; + min-height: 70vh; } diff --git a/web/Example1/main.js b/web/Example1/main.js index 552ed9c0c..514d41bea 100644 --- a/web/Example1/main.js +++ b/web/Example1/main.js @@ -77,11 +77,13 @@ function initWebSocket (addr){ } function sendAngles(azimuth, elevation){ - if(wsocket.readyState === WebSocket.OPEN){ - wsocket.send(JSON.stringify({ - az: azimuth, - el: elevation - })); + if(wsocket){ + if(wsocket.readyState === WebSocket.OPEN){ + wsocket.send(JSON.stringify({ + az: azimuth, + el: elevation + })); + } } } @@ -89,8 +91,12 @@ $(document).ready(function () { // more here: https://notifyjs.jpillora.com $.notify.defaults( {globalPosition: "top left"} ); + let btnConnect = document.querySelector( '#btn-connect' ); + btnConnect.onclick = function(){ + let addr = document.getElementById("ws-address").value; + initWebSocket("ws://" + addr); + } + initThreeJS(); initMouseEvents(); - initWebSocket("ws://127.0.0.1:55555/Laputa"); - }); \ No newline at end of file From 76fbd9b655254f9cf5fdb3c6344813d911de5a06 Mon Sep 17 00:00:00 2001 From: Dimitri Podborski Date: Wed, 17 Jul 2019 19:31:50 +0200 Subject: [PATCH 9/9] implement unity side parsing and controlling of the object over websocket, implements rotation and scaling --- unity/Example1/Assets/Controller.cs | 61 +++++++++++++------ .../Example1/Assets/Scenes/SampleScene.unity | 6 +- web/Example1/main.js | 29 ++++++--- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/unity/Example1/Assets/Controller.cs b/unity/Example1/Assets/Controller.cs index e27ceef87..54cdf6f00 100644 --- a/unity/Example1/Assets/Controller.cs +++ b/unity/Example1/Assets/Controller.cs @@ -1,36 +1,57 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; +using System.Runtime.Serialization; using UnityEngine; using WebSocketSharp; using WebSocketSharp.Server; -public class Controller : MonoBehaviour +public static class GlobalVariables { - private WebSocketServer m_WSServer = null; + public static float azimuth = 0; + public static float elevation = 0; + public static float zoom = 1; +} - public class Laputa : WebSocketBehavior +public class Example1 : WebSocketBehavior +{ + // this is the data that we send using websockets (as JSON) + [Serializable] + public class WSData { - protected override void OnMessage(MessageEventArgs e) - { - var msg = e.Data == "BALUS" - ? "I've been balused already..." - : "I'm not available now."; - - Send(msg); - } + public float az; + public float el; + public float z; } - // Start is called before the first frame update - void Start() + protected override void OnMessage(MessageEventArgs e) { - Debug.Log("Start"); + WSData data = JsonUtility.FromJson(e.Data); + GlobalVariables.azimuth = data.az / (float)Math.PI * 180; + GlobalVariables.elevation = data.el / (float)Math.PI * 180; + GlobalVariables.zoom = data.z; + } - m_WSServer = new WebSocketServer("ws://127.0.0.1:55555"); - m_WSServer.AddWebSocketService("/Laputa"); - m_WSServer.Start(); + protected override void OnOpen() + { + Debug.Log("connection opened"); + } +} + +public class Controller : MonoBehaviour +{ + public string m_IP = "127.0.0.1"; + public int m_port = 55555; + private WebSocketServer m_WSServer = null; - Debug.Log("Start ended"); + void Start() + { + string addr = "ws://" + m_IP + ":" + m_port.ToString(); + Debug.Log("Run WS Server at: " + addr); + m_WSServer = new WebSocketServer(addr); + m_WSServer.AddWebSocketService("/Example1"); + m_WSServer.Start(); } void OnDestroy() @@ -43,5 +64,7 @@ void OnDestroy() // Update is called once per frame void Update() { + gameObject.transform.eulerAngles = new Vector3(GlobalVariables.elevation, GlobalVariables.azimuth, gameObject.transform.eulerAngles.z); + gameObject.transform.localScale = new Vector3(GlobalVariables.zoom, GlobalVariables.zoom, GlobalVariables.zoom); } } diff --git a/unity/Example1/Assets/Scenes/SampleScene.unity b/unity/Example1/Assets/Scenes/SampleScene.unity index 15923a8c0..165cc585c 100644 --- a/unity/Example1/Assets/Scenes/SampleScene.unity +++ b/unity/Example1/Assets/Scenes/SampleScene.unity @@ -288,7 +288,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 963194225} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalPosition: {x: 0, y: 0, z: -2} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} @@ -308,7 +308,7 @@ GameObject: - component: {fileID: 1706378002} - component: {fileID: 1706378006} m_Layer: 0 - m_Name: Cube + m_Name: TargetCube m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -398,3 +398,5 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 282c6ca1d508a694390db02a289b422c, type: 3} m_Name: m_EditorClassIdentifier: + m_IP: 127.0.0.1 + m_port: 55555 diff --git a/web/Example1/main.js b/web/Example1/main.js index 514d41bea..8e35145da 100644 --- a/web/Example1/main.js +++ b/web/Example1/main.js @@ -5,6 +5,13 @@ let camera; let controls; let mesh; let mousePressed = false; +let startingDistance; + +let dataStruct = { + az: 0, // azimuth + el: 0, // elevation + z: 1 // zoom +}; function initThreeJS (){ container = document.querySelector( '#scene-container' ); @@ -14,11 +21,11 @@ function initThreeJS (){ scene.background = new THREE.Color( 0x7FBCDD ); // camera camera = new THREE.PerspectiveCamera(35, container.clientWidth / container.clientHeight, 0.1, 100,); - camera.position.set( -4, 4, 10 ); + camera.position.set( 0, 0, 5 ); // controls controls = new THREE.OrbitControls( camera, container ); // mesh - const geometry = new THREE.BoxBufferGeometry( 2, 2, 2 ); + const geometry = new THREE.BoxBufferGeometry( 1, 1, 1 ); const material = new THREE.MeshStandardMaterial( { color: 0x005000 } ); mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); @@ -43,7 +50,9 @@ function initMouseEvents (){ container = document.querySelector( '#scene-container' ); container.onmousemove = function(){ if(mousePressed){ - sendAngles(controls.getAzimuthalAngle(), controls.getPolarAngle()); + dataStruct.az = controls.getAzimuthalAngle(); + dataStruct.el = controls.getPolarAngle(); + sendData(); } }; container.onmousedown = function(){ @@ -52,6 +61,13 @@ function initMouseEvents (){ container.onmouseup = function(){ mousePressed = false; } + // mouse wheel + container.addEventListener("wheel", function(){ + dataStruct.z = startingDistance/controls.target.distanceTo( controls.object.position ); + sendData(); + }); + + startingDistance = controls.target.distanceTo( controls.object.position ); } function initWebSocket (addr){ @@ -76,13 +92,10 @@ function initWebSocket (addr){ } } -function sendAngles(azimuth, elevation){ +function sendData(azimuth, elevation){ if(wsocket){ if(wsocket.readyState === WebSocket.OPEN){ - wsocket.send(JSON.stringify({ - az: azimuth, - el: elevation - })); + wsocket.send(JSON.stringify(dataStruct)); } } }