split into multiple assemblies

This commit is contained in:
2022-11-20 12:52:22 +01:00
parent def03954a0
commit 9fdfafc3eb
373 changed files with 380 additions and 119 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 66daa331b4934750b899f09b3bf72749
timeCreated: 1668944964

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b93e07e15ba2f3c47a116f943624a730
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,140 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Portal
m_Shader: {fileID: 4800000, guid: 732968a50c15e194ba1e39cf62976ac1, type: 3}
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _LeftTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _RightTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _Texture:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _Blend: 0
- _BlendOp: 0
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _SampleGI: 0
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZTest: 4
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
--- !u!114 &8905466428277890777
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 603cda73335499d4980d9b171eaffe0d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
Shader "Escape Room Engine/Portal"
{
Properties
{
_LeftTex("Left Eye Texture", 2D) = "" {}
_RightTex("Right Eye Texture", 2D) = "" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
// stencil the portal surface to cut it out from the portal frame
Stencil
{
Ref 1
Pass replace
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float4 positionScreen : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
uniform sampler2D _LeftTex, _RightTex;
Varyings vert(Attributes IN)
{
Varyings OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// calculate the screen position which is used to map the portal texture onto the portal
OUT.positionScreen = ComputeScreenPos(OUT.positionHCS);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
const float2 uv = IN.positionScreen.xy / IN.positionScreen.w;
// sample from the correct texture depending on the eye rendered
return unity_StereoEyeIndex == 0 ? tex2D(_LeftTex, uv) : tex2D(_RightTex, uv);
}
ENDHLSL
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 732968a50c15e194ba1e39cf62976ac1
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6139510f6d3834c439966aabdff0e628
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Portal/Assets/Models/Portal Frame.blend (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: a2052daf99b37934fb434aaffa9e75f2
ModelImporter:
serializedVersion: 21300
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 1
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e56607a291566fb47bc0f9f8ab41485c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Portal/Assets/Models/Portal Screen.blend (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -0,0 +1,106 @@
fileFormatVersion: 2
guid: 45a0860e0db749d4881818b0d8d3d0b4
ModelImporter:
serializedVersion: 21300
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 2
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 1
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 0
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 1
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b5ae4b2ffa7168645b783530527a95fc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 781f9ef4eed07d54a8fdbfc34eb99ada
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,316 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &5635962022185625128
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2246995198243242195}
- component: {fileID: 1249363658}
- component: {fileID: 7604291350124895408}
m_Layer: 7
m_Name: Portal
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2246995198243242195
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635962022185625128}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4697416823958963037}
- {fileID: 9135323956734471646}
- {fileID: 2398425302420252226}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1249363658
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635962022185625128}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ae59cddbf8fa37549bb38b1039feeb34, type: 3}
m_Name:
m_EditorClassIdentifier:
linkedPortal: {fileID: 0}
portalCamera: {fileID: 17691322601746172}
--- !u!65 &7604291350124895408
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5635962022185625128}
m_Material: {fileID: 0}
m_IsTrigger: 1
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 3, z: 0.3}
m_Center: {x: 0, y: 1.5, z: -0.15}
--- !u!1 &7398326895463990628
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2398425302420252226}
- component: {fileID: 7791795762741173939}
- component: {fileID: 5969531196797302096}
- component: {fileID: 17691322601746172}
m_Layer: 0
m_Name: Camera
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2398425302420252226
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398326895463990628}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2246995198243242195}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!20 &7791795762741173939
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398326895463990628}
m_Enabled: 0
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
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: 0
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!114 &5969531196797302096
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398326895463990628}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_VolumeFrameworkUpdateModeOption: 2
m_RenderPostProcessing: 0
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_AllowXRRendering: 0
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
--- !u!114 &17691322601746172
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7398326895463990628}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ad60e3973ab83f3468637a06970d7f1f, type: 3}
m_Name:
m_EditorClassIdentifier:
minNearClipPlane: 0.0001
portal: {fileID: 1249363658}
screen: {fileID: 5871497001431693362}
--- !u!1001 &5096432983393035446
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 2246995198243242195}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_RootOrder
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -7511558181221131132, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_Materials.Array.data[0]
value:
objectReference: {fileID: 2100000, guid: 603cda73335499d4980d9b171eaffe0d, type: 2}
- target: {fileID: 919132149155446097, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
propertyPath: m_Name
value: Portal Screen
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 45a0860e0db749d4881818b0d8d3d0b4, type: 3}
--- !u!4 &4697416823958963037 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
m_PrefabInstance: {fileID: 5096432983393035446}
m_PrefabAsset: {fileID: 0}
--- !u!23 &5871497001431693362 stripped
MeshRenderer:
m_CorrespondingSourceObject: {fileID: -7511558181221131132, guid: 45a0860e0db749d4881818b0d8d3d0b4,
type: 3}
m_PrefabInstance: {fileID: 5096432983393035446}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &8740793916703066677
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 2246995198243242195}
m_Modifications:
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalRotation.w
value: 0.7071067
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalRotation.x
value: 0.7071068
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 919132149155446097, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
propertyPath: m_Name
value: Portal Frame
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: a2052daf99b37934fb434aaffa9e75f2, type: 3}
--- !u!4 &9135323956734471646 stripped
Transform:
m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: a2052daf99b37934fb434aaffa9e75f2,
type: 3}
m_PrefabInstance: {fileID: 8740793916703066677}
m_PrefabAsset: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c50e7df1078c96f46bc6825f7e422fb7
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Portal rendering
- Passing through portals

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 262758ef572e4d6fac62967946667239
timeCreated: 1668943830

3
Assets/Portal/README.md Normal file
View File

@@ -0,0 +1,3 @@
# Escape Room Engine Portals
An implementation of portals for the VR escape room engine.

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ea99eadf762e4f118c169f68d950ec78
timeCreated: 1668943800

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 834c70c6d4fb4c147b2f653ad6a38a89
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
namespace EscapeRoomEngine.Portal.Runtime
{
public class HandPortalDriver : PortalDriver
{
private new void Start()
{
traveller = transform.parent.parent.parent; // get the hand portal offset
base.Start();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee06bb2aa499a594c9761498039d73a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using UnityEngine;
namespace EscapeRoomEngine.Portal.Runtime
{
public class PlayerCamera : MonoBehaviour
{
public new Camera camera;
[SerializeField] private Transform leftEye, rightEye;
public Transform GetEyeTransform(Camera.StereoscopicEye eye) =>
eye == Camera.StereoscopicEye.Left ? leftEye : rightEye;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b2ceb62217b416743baa8beee7109cfb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
{
"name": "Portal",
"rootNamespace": "EscapeRoomEngine",
"references": [
"GUID:75469ad4d38634e559750d17036d5f7c",
"GUID:15fc0a57446b3144c949da3e2b9737a9",
"GUID:fe685ec1767f73d42b749ea8045bfe43"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ba4c7dba98ca4c31818cc46276b5dea1
timeCreated: 1668943888

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace EscapeRoomEngine.Portal.Runtime
{
[RequireComponent(typeof(Collider))]
public class Portal : MonoBehaviour
{
public static readonly Matrix4x4 HalfRotation = Matrix4x4.Rotate(Quaternion.Euler(0, 180, 0));
/// <summary>
/// The portal that is connected with this one.
/// </summary>
public Portal linkedPortal;
/// <summary>
/// The camera that will draw the view for this portal.
/// </summary>
public PortalCamera portalCamera;
private readonly List<PortalDriver> _closePortalDrivers = new();
private void Awake()
{
// check whether the other portal is set up
if (!linkedPortal || linkedPortal.linkedPortal != this) throw new Exception("Other portal not set up correctly.");
// check whether the collider is set up correctly
if (!GetComponent<Collider>().isTrigger) throw new Exception("Collider must be a trigger.");
}
private void FixedUpdate()
{
for (var i = 0; i < _closePortalDrivers.Count; i++)
{
var portalDriver = _closePortalDrivers[i];
if (portalDriver.entrySide < 0 && CalculateSide(portalDriver.transform) >= 0) // must have entered from the front and exited the back
{
StopTrackingDriver(portalDriver);
linkedPortal.StartTrackingDriver(portalDriver, -1);
portalDriver.Teleport(this, linkedPortal);
i--; // decrease the loop counter because the list is one element smaller now
}
}
}
private void StartTrackingDriver(PortalDriver portalDriver, int entrySide)
{
_closePortalDrivers.Add(portalDriver);
portalDriver.EnableClone(linkedPortal);
portalDriver.entrySide = entrySide;
}
private void StopTrackingDriver(PortalDriver portalDriver)
{
_closePortalDrivers.Remove(portalDriver);
portalDriver.DisableClone(linkedPortal);
}
private void OnTriggerEnter(Collider other)
{
var portalDriver = other.GetComponent<PortalDriver>();
if (portalDriver && !_closePortalDrivers.Contains(portalDriver))
{
StartTrackingDriver(portalDriver, CalculateSide(portalDriver.transform));
}
}
private void OnTriggerExit(Collider other)
{
var portalDriver = other.GetComponent<PortalDriver>();
if (portalDriver)
StopTrackingDriver(portalDriver);
}
private int CalculateSide(Transform portalDriverTransform)
{
var t = transform;
return Math.Sign(Vector3.Dot(t.forward, portalDriverTransform.position - t.position));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae59cddbf8fa37549bb38b1039feeb34
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.XR;
namespace EscapeRoomEngine.Portal.Runtime
{
[RequireComponent(typeof(Camera))]
public class PortalCamera : MonoBehaviour
{
private static readonly Camera.StereoscopicEye[] Eyes =
{ Camera.StereoscopicEye.Left, Camera.StereoscopicEye.Right };
private static readonly Dictionary<Camera.StereoscopicEye, int> EyeTextureNames = new()
{
{ Camera.StereoscopicEye.Left, Shader.PropertyToID("_LeftTex") },
{ Camera.StereoscopicEye.Right, Shader.PropertyToID("_RightTex") }
};
/// <summary>
/// The minimum near clip plane distance to be used when calculating the oblique clip plane.
/// </summary>
public float minNearClipPlane = 0.0001f;
/// <summary>
/// The portal this camera renders through.
/// </summary>
[SerializeField] private Portal portal;
/// <summary>
/// The mesh where the rendered texture will be drawn on.
/// </summary>
[SerializeField] private MeshRenderer screen;
private PlayerCamera _playerCamera;
private Camera _camera;
private readonly Dictionary<Camera.StereoscopicEye, RenderTexture> _textures = new();
private void Awake()
{
// get player camera
if (Camera.main != null) _playerCamera = Camera.main.GetComponent<PlayerCamera>();
else throw new Exception("Main camera has no player camera script set up.");
// get portal camera
_camera = GetComponent<Camera>();
}
private void OnEnable()
{
RenderPipelineManager.beginCameraRendering += Render;
}
private void OnDisable()
{
RenderPipelineManager.beginCameraRendering -= Render;
}
private void Render(ScriptableRenderContext scriptableRenderContext, Camera _)
{
// check whether the portal plane is visible from the player camera
var frustumPlanes = GeometryUtility.CalculateFrustumPlanes(_playerCamera.camera);
if (!GeometryUtility.TestPlanesAABB(frustumPlanes, portal.linkedPortal.portalCamera.screen.bounds))
// don't render this portal if it is not visible
return;
var t = portal.transform;
screen.enabled = false;
foreach (var eye in Eyes)
{
// create portal texture if it doesn't exist yet
if (!_textures.ContainsKey(eye))
{
if (XRSettings.eyeTextureWidth > 0 && XRSettings.eyeTextureHeight > 0)
{
_textures.Add(eye,
new RenderTexture(XRSettings.eyeTextureWidth, XRSettings.eyeTextureHeight, 24));
portal.linkedPortal.portalCamera.screen.material.SetTexture(EyeTextureNames[eye], _textures[eye]);
}
else // no texture was created so nothing should be rendered
continue;
}
// position portal camera
var m = t.localToWorldMatrix * Portal.HalfRotation * portal.linkedPortal.transform.worldToLocalMatrix *
_playerCamera.GetEyeTransform(eye).localToWorldMatrix;
transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
_camera.projectionMatrix = _playerCamera.camera.GetStereoProjectionMatrix(eye);
// set camera clip plane to portal (otherwise the wall behind the portal would be rendered)
// calculating the clip plane: https://computergraphics.stackexchange.com/a/1506
var n = -t.forward; // clip plane normal
var portalPlane = new Plane(n, t.position); // clip plane in world space
var clipPlane = _camera.worldToCameraMatrix.inverse.transpose *
new Vector4(n.x, n.y, n.z, portalPlane.distance); // vector format clip plane in camera space
if (-portalPlane.GetDistanceToPoint(transform.position) >= minNearClipPlane)
// only adjust the near clip plane if it doesn't intersect with the camera
_camera.projectionMatrix = _camera.CalculateObliqueMatrix(clipPlane);
// render portal view
_camera.targetTexture = _textures[eye];
UniversalRenderPipeline.RenderSingleCamera(scriptableRenderContext, _camera);
}
screen.enabled = true;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad60e3973ab83f3468637a06970d7f1f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using System;
using UnityEngine;
namespace EscapeRoomEngine.Portal.Runtime
{
[RequireComponent(typeof(Collider), typeof(Rigidbody))]
public class PortalDriver : MonoBehaviour
{
/// <summary>
/// The object that will be transported through the portal. Usually either this object or a parent offset object.
/// If left empty, it will default to this object.
/// </summary>
public Transform traveller;
/// <summary>
/// Whether this portal driver has a clone mirroring it at other portals. Disable this for the player.
/// </summary>
public bool hasClone = true;
/// <summary>
/// The side of the portal this became tracked on.
/// </summary>
[HideInInspector] public int entrySide;
/// <summary>
/// The clone that is used to mirror this portal driver at another portal.
/// </summary>
[HideInInspector] public PortalDriverClone clone;
private Collider _collider;
private Rigidbody _rigidbody;
private void Awake()
{
// check whether the collider is set up correctly
_collider = GetComponent<Collider>();
if (_collider.isTrigger) throw new Exception("Collider must not be a trigger.");
// check whether the traveller is set
if (!traveller) traveller = transform;
// get the rigidbody if there is one
_rigidbody = GetComponent<Rigidbody>();
}
protected void Start()
{
if (hasClone)
clone = PortalDriverClone.Create(this);
}
private void Update()
{
if (hasClone && clone.gameObject.activeSelf)
clone.UpdatePosition(transform);
}
public void EnableClone(Portal at)
{
if (hasClone)
{
clone.portal = at;
clone.gameObject.SetActive(true);
}
}
public void DisableClone(Portal at)
{
if (hasClone && at.Equals(clone.portal)) // don't disable clones that are already at a different portal
{
clone.portal = null;
clone.gameObject.SetActive(false);
}
}
public void Teleport(Portal from, Portal to)
{
var m = to.transform.localToWorldMatrix * Portal.HalfRotation * from.transform.worldToLocalMatrix *
traveller.localToWorldMatrix;
traveller.SetPositionAndRotation(m.GetPosition(), m.rotation);
if (_rigidbody)
{
_rigidbody.velocity = to.transform.TransformDirection(
Portal.HalfRotation.rotation * from.transform.InverseTransformDirection(_rigidbody.velocity));
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1bacec3b1d81cef43972d5dfc26a467b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using UnityEngine;
using UnityEngine.InputSystem.XR;
using UnityEngine.XR.Interaction.Toolkit;
namespace EscapeRoomEngine.Portal.Runtime
{
public class PortalDriverClone : MonoBehaviour
{
/// <summary>
/// The portal where this clone is mirroring the portal driver.
/// </summary>
[HideInInspector] public Portal portal;
public static PortalDriverClone Create(PortalDriver portalDriver)
{
// copy the portal driver object
var clone = Instantiate(portalDriver).gameObject;
// destroy all unnecessary components
Destroy(clone.GetComponent<PortalDriver>());
foreach (var xrGrabInteractable in clone.GetComponentsInChildren<XRGrabInteractable>())
Destroy(xrGrabInteractable);
foreach (var rigidbody in clone.GetComponentsInChildren<Rigidbody>())
Destroy(rigidbody);
foreach (var trackedPoseDriver in clone.GetComponentsInChildren<TrackedPoseDriver>())
Destroy(trackedPoseDriver);
// add a clone component
clone.AddComponent<PortalDriverClone>();
// set up the clone
var portalDriverClone = clone.GetComponent<PortalDriverClone>();
portalDriverClone.gameObject.SetActive(false);
return portalDriverClone;
}
public void UpdatePosition(Transform cloning)
{
var m = portal.transform.localToWorldMatrix * Portal.HalfRotation *
portal.linkedPortal.transform.worldToLocalMatrix * cloning.localToWorldMatrix;
transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 088fae7d750b41e4eb8d333853ffa41a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
{
"displayName": "Escape Room Engine Portals",
"name": "wtf.milan.escape-room-engine.portal",
"version": "0.0.1",
"description": "Portals for the VR escape room engine.",
"unity": "2022.1",
"author": {
"name": "Milan van Zanten",
"email": "milan@milan.wtf",
"url": "https://milan.wtf"
},
"hideInEditor": false,
"keywords": ["vr", "virtual reality", "modular", "escape room"],
"dependencies": {
"com.dbrizov.naughtyattributes": "2.1.4"
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e3ab6063e82341ceb3715639390ea65c
timeCreated: 1668943725