init
72
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
# This .gitignore file should be placed at the root of your Unity project directory
|
||||||
|
#
|
||||||
|
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
|
||||||
|
#
|
||||||
|
/[Ll]ibrary/
|
||||||
|
/[Tt]emp/
|
||||||
|
/[Oo]bj/
|
||||||
|
/[Bb]uild/
|
||||||
|
/[Bb]uilds/
|
||||||
|
/[Ll]ogs/
|
||||||
|
/[Uu]ser[Ss]ettings/
|
||||||
|
|
||||||
|
# MemoryCaptures can get excessive in size.
|
||||||
|
# They also could contain extremely sensitive data
|
||||||
|
/[Mm]emoryCaptures/
|
||||||
|
|
||||||
|
# Recordings can get excessive in size
|
||||||
|
/[Rr]ecordings/
|
||||||
|
|
||||||
|
# Uncomment this line if you wish to ignore the asset store tools plugin
|
||||||
|
# /[Aa]ssets/AssetStoreTools*
|
||||||
|
|
||||||
|
# Autogenerated Jetbrains Rider plugin
|
||||||
|
/[Aa]ssets/Plugins/Editor/JetBrains*
|
||||||
|
|
||||||
|
# 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
|
||||||
|
*.aab
|
||||||
|
*.unitypackage
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# Crashlytics generated file
|
||||||
|
crashlytics-build.properties
|
||||||
|
|
||||||
|
# Packed Addressables
|
||||||
|
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
|
||||||
|
|
||||||
|
# Temporary auto-generated Android Assets
|
||||||
|
/[Aa]ssets/[Ss]treamingAssets/aa.meta
|
||||||
|
/[Aa]ssets/[Ss]treamingAssets/aa/*
|
||||||
55
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
{
|
||||||
|
"files.exclude":
|
||||||
|
{
|
||||||
|
"**/.DS_Store":true,
|
||||||
|
"**/.git":true,
|
||||||
|
"**/.gitmodules":true,
|
||||||
|
"**/*.booproj":true,
|
||||||
|
"**/*.pidb":true,
|
||||||
|
"**/*.suo":true,
|
||||||
|
"**/*.user":true,
|
||||||
|
"**/*.userprefs":true,
|
||||||
|
"**/*.unityproj":true,
|
||||||
|
"**/*.dll":true,
|
||||||
|
"**/*.exe":true,
|
||||||
|
"**/*.pdf":true,
|
||||||
|
"**/*.mid":true,
|
||||||
|
"**/*.midi":true,
|
||||||
|
"**/*.wav":true,
|
||||||
|
"**/*.gif":true,
|
||||||
|
"**/*.ico":true,
|
||||||
|
"**/*.jpg":true,
|
||||||
|
"**/*.jpeg":true,
|
||||||
|
"**/*.png":true,
|
||||||
|
"**/*.psd":true,
|
||||||
|
"**/*.tga":true,
|
||||||
|
"**/*.tif":true,
|
||||||
|
"**/*.tiff":true,
|
||||||
|
"**/*.3ds":true,
|
||||||
|
"**/*.3DS":true,
|
||||||
|
"**/*.fbx":true,
|
||||||
|
"**/*.FBX":true,
|
||||||
|
"**/*.lxo":true,
|
||||||
|
"**/*.LXO":true,
|
||||||
|
"**/*.ma":true,
|
||||||
|
"**/*.MA":true,
|
||||||
|
"**/*.obj":true,
|
||||||
|
"**/*.OBJ":true,
|
||||||
|
"**/*.asset":true,
|
||||||
|
"**/*.cubemap":true,
|
||||||
|
"**/*.flare":true,
|
||||||
|
"**/*.mat":true,
|
||||||
|
"**/*.meta":true,
|
||||||
|
"**/*.prefab":true,
|
||||||
|
"**/*.unity":true,
|
||||||
|
"build/":true,
|
||||||
|
"Build/":true,
|
||||||
|
"Library/":true,
|
||||||
|
"library/":true,
|
||||||
|
"obj/":true,
|
||||||
|
"Obj/":true,
|
||||||
|
"ProjectSettings/":true,
|
||||||
|
"temp/":true,
|
||||||
|
"Temp/":true
|
||||||
|
}
|
||||||
|
}
|
||||||
78
Assets/Client.mat
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!21 &2100000
|
||||||
|
Material:
|
||||||
|
serializedVersion: 6
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: Client
|
||||||
|
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_ShaderKeywords:
|
||||||
|
m_LightmapFlags: 4
|
||||||
|
m_EnableInstancingVariants: 0
|
||||||
|
m_DoubleSidedGI: 0
|
||||||
|
m_CustomRenderQueue: -1
|
||||||
|
stringTagMap: {}
|
||||||
|
disabledShaderPasses: []
|
||||||
|
m_SavedProperties:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TexEnvs:
|
||||||
|
- _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}
|
||||||
|
- _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}
|
||||||
|
m_Floats:
|
||||||
|
- _BumpScale: 1
|
||||||
|
- _Cutoff: 0.5
|
||||||
|
- _DetailNormalMapScale: 1
|
||||||
|
- _DstBlend: 0
|
||||||
|
- _GlossMapScale: 1
|
||||||
|
- _Glossiness: 0.5
|
||||||
|
- _GlossyReflections: 1
|
||||||
|
- _Metallic: 0
|
||||||
|
- _Mode: 0
|
||||||
|
- _OcclusionStrength: 1
|
||||||
|
- _Parallax: 0.02
|
||||||
|
- _SmoothnessTextureChannel: 0
|
||||||
|
- _SpecularHighlights: 1
|
||||||
|
- _SrcBlend: 1
|
||||||
|
- _UVSec: 0
|
||||||
|
- _ZWrite: 1
|
||||||
|
m_Colors:
|
||||||
|
- _Color: {r: 1, g: 0, b: 0, a: 1}
|
||||||
|
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_BuildTextureStacks: []
|
||||||
8
Assets/Client.mat.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4151b8cfb6c586f46b7c2235f8e37ffb
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 2100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5a7f75edb8db8494a856b560d2bce067
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0f3dc386b0074be4caf7b858e3189529
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo/Basic.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cd20cf8481e733f42a140665486354bd
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
732
Assets/Ignorance/Demo/Basic/BasicWithIgnorance.unity
Normal file
|
|
@ -0,0 +1,732 @@
|
||||||
|
%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, g: 0, b: 0, 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: 3
|
||||||
|
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||||
|
m_SkyboxMaterial: {fileID: 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: 1
|
||||||
|
m_DefaultReflectionResolution: 128
|
||||||
|
m_ReflectionBounces: 1
|
||||||
|
m_ReflectionIntensity: 1
|
||||||
|
m_CustomReflection: {fileID: 0}
|
||||||
|
m_Sun: {fileID: 0}
|
||||||
|
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||||
|
m_UseRadianceAmbientProbe: 0
|
||||||
|
--- !u!157 &3
|
||||||
|
LightmapSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 12
|
||||||
|
m_GIWorkflowMode: 0
|
||||||
|
m_GISettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_BounceScale: 1
|
||||||
|
m_IndirectOutputScale: 1
|
||||||
|
m_AlbedoBoost: 1
|
||||||
|
m_EnvironmentLightingMode: 0
|
||||||
|
m_EnableBakedLightmaps: 0
|
||||||
|
m_EnableRealtimeLightmaps: 0
|
||||||
|
m_LightmapEditorSettings:
|
||||||
|
serializedVersion: 12
|
||||||
|
m_Resolution: 2
|
||||||
|
m_BakeResolution: 40
|
||||||
|
m_AtlasSize: 1024
|
||||||
|
m_AO: 0
|
||||||
|
m_AOMaxDistance: 1
|
||||||
|
m_CompAOExponent: 1
|
||||||
|
m_CompAOExponentDirect: 0
|
||||||
|
m_ExtractAmbientOcclusion: 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_PVREnvironmentSampleCount: 500
|
||||||
|
m_PVREnvironmentReferencePointCount: 2048
|
||||||
|
m_PVRFilteringMode: 2
|
||||||
|
m_PVRDenoiserTypeDirect: 0
|
||||||
|
m_PVRDenoiserTypeIndirect: 0
|
||||||
|
m_PVRDenoiserTypeAO: 0
|
||||||
|
m_PVRFilterTypeDirect: 0
|
||||||
|
m_PVRFilterTypeIndirect: 0
|
||||||
|
m_PVRFilterTypeAO: 0
|
||||||
|
m_PVREnvironmentMIS: 0
|
||||||
|
m_PVRCulling: 1
|
||||||
|
m_PVRFilteringGaussRadiusDirect: 1
|
||||||
|
m_PVRFilteringGaussRadiusIndirect: 5
|
||||||
|
m_PVRFilteringGaussRadiusAO: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||||
|
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||||
|
m_ExportTrainingData: 0
|
||||||
|
m_TrainingDataDestination: TrainingData
|
||||||
|
m_LightProbeSampleCountMultiplier: 4
|
||||||
|
m_LightingDataAsset: {fileID: 0}
|
||||||
|
m_LightingSettings: {fileID: 4890085278179872738, guid: f34de581ee6ab3743844c33f257a03c2,
|
||||||
|
type: 2}
|
||||||
|
--- !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
|
||||||
|
maxJobWorkers: 0
|
||||||
|
preserveTilesOutsideBounds: 0
|
||||||
|
debug:
|
||||||
|
m_Flags: 0
|
||||||
|
m_NavMeshData: {fileID: 0}
|
||||||
|
--- !u!1 &249891953
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 249891957}
|
||||||
|
- component: {fileID: 249891954}
|
||||||
|
- component: {fileID: 249891956}
|
||||||
|
- component: {fileID: 249891955}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: NetworkManager
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &249891954
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 249891953}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 6442dc8070ceb41f094e44de0bf87274, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
offsetX: 0
|
||||||
|
offsetY: 0
|
||||||
|
--- !u!114 &249891955
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 249891953}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 872fa23ef6e77334ca452ce16f6cd091, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
port: 7777
|
||||||
|
LogType: 1
|
||||||
|
DebugDisplay: 0
|
||||||
|
serverBindsAll: 1
|
||||||
|
serverBindAddress:
|
||||||
|
serverMaxPeerCapacity: 64
|
||||||
|
serverMaxNativeWaitTime: 1
|
||||||
|
serverStatusUpdateInterval: 0
|
||||||
|
clientMaxNativeWaitTime: 3
|
||||||
|
clientStatusUpdateInterval: 0
|
||||||
|
Channels: 0100000002000000
|
||||||
|
ClientDataBufferSize: 1000
|
||||||
|
ClientConnEventBufferSize: 10
|
||||||
|
ServerDataBufferSize: 5000
|
||||||
|
ServerConnEventBufferSize: 100
|
||||||
|
PacketBufferCapacity: 4096
|
||||||
|
MaxAllowedPacketSize: 33554432
|
||||||
|
--- !u!114 &249891956
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 249891953}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 20460c43f0320ed4baf8c1dcf953eafa, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
dontDestroyOnLoad: 0
|
||||||
|
runInBackground: 1
|
||||||
|
autoStartServerBuild: 1
|
||||||
|
serverTickRate: 30
|
||||||
|
offlineScene:
|
||||||
|
onlineScene:
|
||||||
|
transport: {fileID: 249891955}
|
||||||
|
networkAddress: localhost
|
||||||
|
maxConnections: 100
|
||||||
|
authenticator: {fileID: 0}
|
||||||
|
playerPrefab: {fileID: 897184729387425976, guid: dc2c4328591bef748abb8df795c17202,
|
||||||
|
type: 3}
|
||||||
|
autoCreatePlayer: 1
|
||||||
|
playerSpawnMethod: 1
|
||||||
|
spawnPrefabs: []
|
||||||
|
--- !u!4 &249891957
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 249891953}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -10, y: 4, z: 5}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 1
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &288173824
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 288173827}
|
||||||
|
- component: {fileID: 288173826}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Main Camera
|
||||||
|
m_TagString: MainCamera
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!20 &288173826
|
||||||
|
Camera:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 288173824}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 2
|
||||||
|
m_ClearFlags: 2
|
||||||
|
m_BackGroundColor: {r: 0, g: 0, b: 0, 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: 1
|
||||||
|
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 &288173827
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 288173824}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 1, z: -1}
|
||||||
|
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}
|
||||||
|
--- !u!1 &379082678
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 379082679}
|
||||||
|
- component: {fileID: 379082681}
|
||||||
|
- component: {fileID: 379082682}
|
||||||
|
- component: {fileID: 379082680}
|
||||||
|
- component: {fileID: 379082683}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: PlayersPanel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &379082679
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 379082678}
|
||||||
|
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_Children: []
|
||||||
|
m_Father: {fileID: 864730913}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 2.5}
|
||||||
|
m_SizeDelta: {x: -10, y: -15}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &379082680
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 379082678}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Padding:
|
||||||
|
m_Left: 5
|
||||||
|
m_Right: 5
|
||||||
|
m_Top: 5
|
||||||
|
m_Bottom: 5
|
||||||
|
m_ChildAlignment: 0
|
||||||
|
m_StartCorner: 0
|
||||||
|
m_StartAxis: 0
|
||||||
|
m_CellSize: {x: 120, y: 65}
|
||||||
|
m_Spacing: {x: 20, y: 20}
|
||||||
|
m_Constraint: 0
|
||||||
|
m_ConstraintCount: 2
|
||||||
|
--- !u!222 &379082681
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 379082678}
|
||||||
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!114 &379082682
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 379082678}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0, g: 0, b: 0, a: 0.039215688}
|
||||||
|
m_RaycastTarget: 0
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 0}
|
||||||
|
m_Type: 0
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!114 &379082683
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 379082678}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_ShowMaskGraphic: 0
|
||||||
|
--- !u!1 &533055200
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 533055204}
|
||||||
|
- component: {fileID: 533055203}
|
||||||
|
- component: {fileID: 533055202}
|
||||||
|
- component: {fileID: 533055201}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Canvas
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &533055201
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 533055200}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 266fac335be17a243af86e88de84766d, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
mainPanel: {fileID: 1712119861}
|
||||||
|
playersPanel: {fileID: 379082679}
|
||||||
|
--- !u!114 &533055202
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 533055200}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_UiScaleMode: 0
|
||||||
|
m_ReferencePixelsPerUnit: 100
|
||||||
|
m_ScaleFactor: 1
|
||||||
|
m_ReferenceResolution: {x: 800, y: 600}
|
||||||
|
m_ScreenMatchMode: 0
|
||||||
|
m_MatchWidthOrHeight: 0
|
||||||
|
m_PhysicalUnit: 3
|
||||||
|
m_FallbackScreenDPI: 96
|
||||||
|
m_DefaultSpriteDPI: 96
|
||||||
|
m_DynamicPixelsPerUnit: 1
|
||||||
|
m_PresetInfoIsWorld: 0
|
||||||
|
--- !u!223 &533055203
|
||||||
|
Canvas:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 533055200}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 3
|
||||||
|
m_RenderMode: 0
|
||||||
|
m_Camera: {fileID: 0}
|
||||||
|
m_PlaneDistance: 100
|
||||||
|
m_PixelPerfect: 0
|
||||||
|
m_ReceivesEvents: 1
|
||||||
|
m_OverrideSorting: 0
|
||||||
|
m_OverridePixelPerfect: 0
|
||||||
|
m_SortingBucketNormalizedSize: 0
|
||||||
|
m_AdditionalShaderChannelsFlag: 0
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_TargetDisplay: 0
|
||||||
|
--- !u!224 &533055204
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 533055200}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 1712119861}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 2
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0, y: 0}
|
||||||
|
--- !u!1 &864730912
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 864730913}
|
||||||
|
- component: {fileID: 864730916}
|
||||||
|
- component: {fileID: 864730914}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: BorderPanel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &864730913
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 864730912}
|
||||||
|
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_Children:
|
||||||
|
- {fileID: 379082679}
|
||||||
|
m_Father: {fileID: 1712119861}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: -55}
|
||||||
|
m_SizeDelta: {x: -40, y: -150}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &864730914
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 864730912}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 0
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_Type: 1
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 0
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!222 &864730916
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 864730912}
|
||||||
|
m_CullTransparentMesh: 0
|
||||||
|
--- !u!1 &1356257340
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1356257343}
|
||||||
|
- component: {fileID: 1356257342}
|
||||||
|
- component: {fileID: 1356257341}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: EventSystem
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!114 &1356257341
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1356257340}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_HorizontalAxis: Horizontal
|
||||||
|
m_VerticalAxis: Vertical
|
||||||
|
m_SubmitButton: Submit
|
||||||
|
m_CancelButton: Cancel
|
||||||
|
m_InputActionsPerSecond: 10
|
||||||
|
m_RepeatDelay: 0.5
|
||||||
|
m_ForceModuleActive: 0
|
||||||
|
--- !u!114 &1356257342
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1356257340}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_FirstSelected: {fileID: 0}
|
||||||
|
m_sendNavigationEvents: 1
|
||||||
|
m_DragThreshold: 10
|
||||||
|
--- !u!4 &1356257343
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1356257340}
|
||||||
|
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_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 3
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1 &1712119860
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 1712119861}
|
||||||
|
- component: {fileID: 1712119863}
|
||||||
|
- component: {fileID: 1712119862}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: MainPanel
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 0
|
||||||
|
--- !u!224 &1712119861
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1712119860}
|
||||||
|
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_Children:
|
||||||
|
- {fileID: 864730913}
|
||||||
|
m_Father: {fileID: 533055204}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 1, y: 1}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!114 &1712119862
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1712119860}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 0, g: 0, b: 0, a: 0}
|
||||||
|
m_RaycastTarget: 0
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Sprite: {fileID: 0}
|
||||||
|
m_Type: 0
|
||||||
|
m_PreserveAspect: 0
|
||||||
|
m_FillCenter: 1
|
||||||
|
m_FillMethod: 4
|
||||||
|
m_FillAmount: 1
|
||||||
|
m_FillClockwise: 1
|
||||||
|
m_FillOrigin: 0
|
||||||
|
m_UseSpriteMesh: 0
|
||||||
|
m_PixelsPerUnitMultiplier: 1
|
||||||
|
--- !u!222 &1712119863
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1712119860}
|
||||||
|
m_CullTransparentMesh: 0
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2db17f37f98c4cf4a88890358a4fa966
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!850595691 &4890085278179872738
|
||||||
|
LightingSettings:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: BasicWithIgnoranceSettings
|
||||||
|
serializedVersion: 3
|
||||||
|
m_GIWorkflowMode: 0
|
||||||
|
m_EnableBakedLightmaps: 0
|
||||||
|
m_EnableRealtimeLightmaps: 0
|
||||||
|
m_RealtimeEnvironmentLighting: 1
|
||||||
|
m_BounceScale: 1
|
||||||
|
m_AlbedoBoost: 1
|
||||||
|
m_IndirectOutputScale: 1
|
||||||
|
m_UsingShadowmask: 1
|
||||||
|
m_BakeBackend: 1
|
||||||
|
m_LightmapMaxSize: 1024
|
||||||
|
m_BakeResolution: 40
|
||||||
|
m_Padding: 2
|
||||||
|
m_TextureCompression: 1
|
||||||
|
m_AO: 0
|
||||||
|
m_AOMaxDistance: 1
|
||||||
|
m_CompAOExponent: 1
|
||||||
|
m_CompAOExponentDirect: 0
|
||||||
|
m_ExtractAO: 0
|
||||||
|
m_MixedBakeMode: 2
|
||||||
|
m_LightmapsBakeMode: 1
|
||||||
|
m_FilterMode: 1
|
||||||
|
m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_ExportTrainingData: 0
|
||||||
|
m_TrainingDataDestination: TrainingData
|
||||||
|
m_RealtimeResolution: 2
|
||||||
|
m_ForceWhiteAlbedo: 0
|
||||||
|
m_ForceUpdates: 0
|
||||||
|
m_FinalGather: 0
|
||||||
|
m_FinalGatherRayCount: 256
|
||||||
|
m_FinalGatherFiltering: 1
|
||||||
|
m_PVRCulling: 1
|
||||||
|
m_PVRSampling: 1
|
||||||
|
m_PVRDirectSampleCount: 32
|
||||||
|
m_PVRSampleCount: 500
|
||||||
|
m_PVREnvironmentSampleCount: 500
|
||||||
|
m_PVREnvironmentReferencePointCount: 2048
|
||||||
|
m_LightProbeSampleCountMultiplier: 4
|
||||||
|
m_PVRBounces: 2
|
||||||
|
m_PVRMinBounces: 2
|
||||||
|
m_PVREnvironmentMIS: 0
|
||||||
|
m_PVRFilteringMode: 2
|
||||||
|
m_PVRDenoiserTypeDirect: 0
|
||||||
|
m_PVRDenoiserTypeIndirect: 0
|
||||||
|
m_PVRDenoiserTypeAO: 0
|
||||||
|
m_PVRFilterTypeDirect: 0
|
||||||
|
m_PVRFilterTypeIndirect: 0
|
||||||
|
m_PVRFilterTypeAO: 0
|
||||||
|
m_PVRFilteringGaussRadiusDirect: 1
|
||||||
|
m_PVRFilteringGaussRadiusIndirect: 5
|
||||||
|
m_PVRFilteringGaussRadiusAO: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||||
|
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||||
|
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f34de581ee6ab3743844c33f257a03c2
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 4890085278179872738
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo/PongChamp.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 634f781b33ac69147bff9edd5829cfd6
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
188
Assets/Ignorance/Demo/PongChamp/AtariBall.prefab
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1080679924113744
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4700925592147096}
|
||||||
|
- component: {fileID: 212107498293566416}
|
||||||
|
- component: {fileID: 61279514624852186}
|
||||||
|
- component: {fileID: 50354248948880112}
|
||||||
|
- component: {fileID: 114290021321007948}
|
||||||
|
- component: {fileID: 2590138469697868697}
|
||||||
|
- component: {fileID: 114121325390084138}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: AtariBall
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4700925592147096
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -3, y: 0, z: 0}
|
||||||
|
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}
|
||||||
|
--- !u!212 &212107498293566416
|
||||||
|
SpriteRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 0
|
||||||
|
m_ReceiveShadows: 0
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 0
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 0
|
||||||
|
m_IgnoreNormalsForChartDetection: 0
|
||||||
|
m_ImportantGI: 0
|
||||||
|
m_StitchLightmapSeams: 0
|
||||||
|
m_SelectedEditorRenderState: 0
|
||||||
|
m_MinimumChartSize: 4
|
||||||
|
m_AutoUVMaxDistance: 0.5
|
||||||
|
m_AutoUVMaxAngle: 89
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingLayer: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_Sprite: {fileID: 21300000, guid: 4b66f21097323d44ab40669b2fb9c53d, type: 3}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_FlipX: 0
|
||||||
|
m_FlipY: 0
|
||||||
|
m_DrawMode: 0
|
||||||
|
m_Size: {x: 1, y: 1}
|
||||||
|
m_AdaptiveModeThreshold: 0.5
|
||||||
|
m_SpriteTileMode: 0
|
||||||
|
m_WasSpriteAssigned: 1
|
||||||
|
m_MaskInteraction: 0
|
||||||
|
m_SpriteSortPoint: 0
|
||||||
|
--- !u!61 &61279514624852186
|
||||||
|
BoxCollider2D:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Density: 1
|
||||||
|
m_Material: {fileID: 6200000, guid: 97a3e4cddb8635c4eba1265f44d106bf, type: 2}
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_UsedByEffector: 0
|
||||||
|
m_UsedByComposite: 0
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
m_SpriteTilingProperty:
|
||||||
|
border: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
pivot: {x: 0.5, y: 0.5}
|
||||||
|
oldSize: {x: 1, y: 1}
|
||||||
|
newSize: {x: 1, y: 1}
|
||||||
|
adaptiveTilingThreshold: 0.5
|
||||||
|
drawMode: 0
|
||||||
|
adaptiveTiling: 0
|
||||||
|
m_AutoTiling: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Size: {x: 1, y: 1}
|
||||||
|
m_EdgeRadius: 0
|
||||||
|
--- !u!50 &50354248948880112
|
||||||
|
Rigidbody2D:
|
||||||
|
serializedVersion: 4
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_BodyType: 0
|
||||||
|
m_Simulated: 0
|
||||||
|
m_UseFullKinematicContacts: 0
|
||||||
|
m_UseAutoMass: 0
|
||||||
|
m_Mass: 0.0001
|
||||||
|
m_LinearDrag: 0
|
||||||
|
m_AngularDrag: 0.05
|
||||||
|
m_GravityScale: 0
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Interpolate: 0
|
||||||
|
m_SleepingMode: 1
|
||||||
|
m_CollisionDetection: 0
|
||||||
|
m_Constraints: 4
|
||||||
|
--- !u!114 &114290021321007948
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
sceneId: 0
|
||||||
|
serverOnly: 0
|
||||||
|
visible: 0
|
||||||
|
m_AssetId:
|
||||||
|
hasSpawned: 0
|
||||||
|
--- !u!114 &2590138469697868697
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2a08d5ab1f59230458264367f00c54d8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0.1
|
||||||
|
speed: 100
|
||||||
|
--- !u!114 &114121325390084138
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1080679924113744}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0
|
||||||
|
clientAuthority: 0
|
||||||
|
localPositionSensitivity: 0.01
|
||||||
|
localRotationSensitivity: 0.01
|
||||||
|
localScaleSensitivity: 0.01
|
||||||
|
compressRotation: 1
|
||||||
|
interpolateScale: 0
|
||||||
|
syncScale: 0
|
||||||
8
Assets/Ignorance/Demo/PongChamp/AtariBall.prefab.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: da367a4c269be6d4a855ee1a9a68256b
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
190
Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1240244544407914
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4118252415362944}
|
||||||
|
- component: {fileID: 212641192162007874}
|
||||||
|
- component: {fileID: 61279767645666242}
|
||||||
|
- component: {fileID: 50389918509199184}
|
||||||
|
- component: {fileID: 114104497298166850}
|
||||||
|
- component: {fileID: -4874889082967523790}
|
||||||
|
- component: {fileID: 114398896143473162}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: AtariRacket
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4118252415362944
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
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_Children: []
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!212 &212641192162007874
|
||||||
|
SpriteRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 0
|
||||||
|
m_ReceiveShadows: 0
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 0
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 0
|
||||||
|
m_IgnoreNormalsForChartDetection: 0
|
||||||
|
m_ImportantGI: 0
|
||||||
|
m_StitchLightmapSeams: 0
|
||||||
|
m_SelectedEditorRenderState: 0
|
||||||
|
m_MinimumChartSize: 4
|
||||||
|
m_AutoUVMaxDistance: 0.5
|
||||||
|
m_AutoUVMaxAngle: 89
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingLayer: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_Sprite: {fileID: 21300000, guid: e11aad367beb44f4b8a3def9b8fc57ec, type: 3}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_FlipX: 0
|
||||||
|
m_FlipY: 0
|
||||||
|
m_DrawMode: 0
|
||||||
|
m_Size: {x: 2, y: 4}
|
||||||
|
m_AdaptiveModeThreshold: 0.5
|
||||||
|
m_SpriteTileMode: 0
|
||||||
|
m_WasSpriteAssigned: 1
|
||||||
|
m_MaskInteraction: 0
|
||||||
|
m_SpriteSortPoint: 0
|
||||||
|
--- !u!61 &61279767645666242
|
||||||
|
BoxCollider2D:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Density: 1
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_UsedByEffector: 0
|
||||||
|
m_UsedByComposite: 0
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
m_SpriteTilingProperty:
|
||||||
|
border: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
pivot: {x: 0.5, y: 0.5}
|
||||||
|
oldSize: {x: 2, y: 4}
|
||||||
|
newSize: {x: 2, y: 4}
|
||||||
|
adaptiveTilingThreshold: 0.5
|
||||||
|
drawMode: 0
|
||||||
|
adaptiveTiling: 0
|
||||||
|
m_AutoTiling: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Size: {x: 2, y: 4}
|
||||||
|
m_EdgeRadius: 0
|
||||||
|
--- !u!50 &50389918509199184
|
||||||
|
Rigidbody2D:
|
||||||
|
serializedVersion: 4
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_BodyType: 0
|
||||||
|
m_Simulated: 1
|
||||||
|
m_UseFullKinematicContacts: 0
|
||||||
|
m_UseAutoMass: 0
|
||||||
|
m_Mass: 1
|
||||||
|
m_LinearDrag: 0
|
||||||
|
m_AngularDrag: 0.05
|
||||||
|
m_GravityScale: 0
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Interpolate: 1
|
||||||
|
m_SleepingMode: 1
|
||||||
|
m_CollisionDetection: 1
|
||||||
|
m_Constraints: 4
|
||||||
|
--- !u!114 &114104497298166850
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
sceneId: 0
|
||||||
|
serverOnly: 0
|
||||||
|
visible: 0
|
||||||
|
m_AssetId: a85b24263182aae4bbc1829bb2b73d7a
|
||||||
|
hasSpawned: 0
|
||||||
|
--- !u!114 &-4874889082967523790
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: b68eb08343b29a54dbd5ed7830fb9211, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0.1
|
||||||
|
speed: 1500
|
||||||
|
--- !u!114 &114398896143473162
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1240244544407914}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0
|
||||||
|
clientAuthority: 1
|
||||||
|
localPositionSensitivity: 0.01
|
||||||
|
localRotationSensitivity: 0.01
|
||||||
|
localScaleSensitivity: 0.01
|
||||||
|
compressRotation: 1
|
||||||
|
interpolatePosition: 1
|
||||||
|
interpolateRotation: 1
|
||||||
|
interpolateScale: 0
|
||||||
|
syncScale: 0
|
||||||
8
Assets/Ignorance/Demo/PongChamp/AtariRacket.prefab.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a85b24263182aae4bbc1829bb2b73d7a
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 100100000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!62 &6200000
|
||||||
|
PhysicsMaterial2D:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: BallMaterial 1
|
||||||
|
friction: 0
|
||||||
|
bounciness: 1
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 315510c0721e82f4cad07c2669b863fa
|
||||||
|
timeCreated: 1426602119
|
||||||
|
licenseType: Store
|
||||||
|
NativeFormatImporter:
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1164
Assets/Ignorance/Demo/PongChamp/Demo.unity
Normal file
7
Assets/Ignorance/Demo/PongChamp/Demo.unity.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c63e1eea85874ae43a7fdd723a38741e
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo/PongChamp/Scripts.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e2898db03f0b9654498df19a98dc9503
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
67
Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongBall.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using Mirror;
|
||||||
|
|
||||||
|
namespace Ignorance.Examples.PongChamp
|
||||||
|
{
|
||||||
|
public class AtariPongBall : NetworkBehaviour
|
||||||
|
{
|
||||||
|
public float speed = 100;
|
||||||
|
private Rigidbody2D rigidbody2d;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
rigidbody2d = GetComponent<Rigidbody2D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStartServer()
|
||||||
|
{
|
||||||
|
base.OnStartServer();
|
||||||
|
|
||||||
|
// only simulate ball physics on server
|
||||||
|
rigidbody2d.simulated = true;
|
||||||
|
|
||||||
|
// Serve the ball from left player
|
||||||
|
rigidbody2d.velocity = Vector2.right * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
float HitFactor(Vector2 ballPos, Vector2 racketPos, float racketHeight)
|
||||||
|
{
|
||||||
|
// ascii art:
|
||||||
|
// || 1 <- at the top of the racket
|
||||||
|
// ||
|
||||||
|
// || 0 <- at the middle of the racket
|
||||||
|
// ||
|
||||||
|
// || -1 <- at the bottom of the racket
|
||||||
|
return (ballPos.y - racketPos.y) / racketHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only call this on server
|
||||||
|
[ServerCallback]
|
||||||
|
void OnCollisionEnter2D(Collision2D col)
|
||||||
|
{
|
||||||
|
// Note: 'col' holds the collision information. If the
|
||||||
|
// Ball collided with a racket, then:
|
||||||
|
// col.gameObject is the racket
|
||||||
|
// col.transform.position is the racket's position
|
||||||
|
// col.collider is the racket's collider
|
||||||
|
|
||||||
|
// did we hit a racket? then we need to calculate the hit factor
|
||||||
|
if (col.transform.GetComponent<AtariPongBall>())
|
||||||
|
{
|
||||||
|
// Calculate y direction via hit Factor
|
||||||
|
float y = HitFactor(transform.position,
|
||||||
|
col.transform.position,
|
||||||
|
col.collider.bounds.size.y);
|
||||||
|
|
||||||
|
// Calculate x direction via opposite collision
|
||||||
|
float x = col.relativeVelocity.x > 0 ? 1 : -1;
|
||||||
|
|
||||||
|
// Calculate direction, make length=1 via .normalized
|
||||||
|
Vector2 dir = new Vector2(x, y).normalized;
|
||||||
|
|
||||||
|
// Set Velocity with dir * speed
|
||||||
|
rigidbody2d.velocity = dir * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2a08d5ab1f59230458264367f00c54d8
|
||||||
|
timeCreated: 1426602353
|
||||||
|
licenseType: Store
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
25
Assets/Ignorance/Demo/PongChamp/Scripts/AtariPongRacket.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using Mirror;
|
||||||
|
|
||||||
|
namespace Ignorance.Examples.PongChamp
|
||||||
|
{
|
||||||
|
public class AtariPongRacket : NetworkBehaviour
|
||||||
|
{
|
||||||
|
public float speed = 1500;
|
||||||
|
private Rigidbody2D rigidbody2d;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
rigidbody2d = GetComponent<Rigidbody2D>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to use FixedUpdate for rigidbody
|
||||||
|
void FixedUpdate()
|
||||||
|
{
|
||||||
|
// only let the local player control the racket.
|
||||||
|
// don't control other player's rackets
|
||||||
|
if (isLocalPlayer)
|
||||||
|
rigidbody2d.velocity = new Vector2(0, Input.GetAxisRaw("Vertical")) * speed * Time.fixedDeltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b68eb08343b29a54dbd5ed7830fb9211
|
||||||
|
timeCreated: 1426597826
|
||||||
|
licenseType: Store
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
49
Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using Mirror;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
|
public class OnlineTimer : NetworkBehaviour
|
||||||
|
{
|
||||||
|
private Stopwatch stopwatch;
|
||||||
|
|
||||||
|
// Start is called before the first frame update
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
stopwatch = new Stopwatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStartClient()
|
||||||
|
{
|
||||||
|
stopwatch.Reset();
|
||||||
|
stopwatch.Start();
|
||||||
|
|
||||||
|
Debug.Log("Stopwatch started!");
|
||||||
|
|
||||||
|
base.OnStartClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDisable()
|
||||||
|
{
|
||||||
|
if(stopwatch.IsRunning)
|
||||||
|
{
|
||||||
|
System.TimeSpan ts = stopwatch.Elapsed;
|
||||||
|
stopwatch.Stop();
|
||||||
|
|
||||||
|
Debug.Log("Stopwatch stopped: duration " + string.Format("{0:00}:{1:00}:{2:00}.{3:00}",
|
||||||
|
ts.Hours, ts.Minutes, ts.Seconds,
|
||||||
|
ts.Milliseconds / 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
if (!stopwatch.IsRunning) return;
|
||||||
|
|
||||||
|
GUI.Box(new Rect(new Vector2(2, Screen.height - 36), new Vector2(320, 32)), "ONLINE TIME: " + string.Format("{0:00}:{1:00}:{2:00}.{3:00}",
|
||||||
|
stopwatch.Elapsed.Hours, stopwatch.Elapsed.Minutes, stopwatch.Elapsed.Seconds,
|
||||||
|
stopwatch.Elapsed.Milliseconds / 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Ignorance/Demo/PongChamp/Scripts/OnlineTimer.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d0996ec573094c24890a4d4233ee871e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
180
Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &542835289192032773
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 548291784780898253}
|
||||||
|
- component: {fileID: 394858453892616325}
|
||||||
|
- component: {fileID: 520653813702449573}
|
||||||
|
- component: {fileID: 440601958556739609}
|
||||||
|
- component: {fileID: 440842259441939327}
|
||||||
|
- component: {fileID: 8881572407762724401}
|
||||||
|
- component: {fileID: 5995301680282788937}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: TenryuuBall
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &548291784780898253
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: -3, y: 0, z: 0}
|
||||||
|
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}
|
||||||
|
--- !u!212 &394858453892616325
|
||||||
|
SpriteRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 0
|
||||||
|
m_ReceiveShadows: 0
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 0
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 0
|
||||||
|
m_IgnoreNormalsForChartDetection: 0
|
||||||
|
m_ImportantGI: 0
|
||||||
|
m_StitchLightmapSeams: 0
|
||||||
|
m_SelectedEditorRenderState: 0
|
||||||
|
m_MinimumChartSize: 4
|
||||||
|
m_AutoUVMaxDistance: 0.5
|
||||||
|
m_AutoUVMaxAngle: 89
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingLayer: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_Sprite: {fileID: 21300000, guid: 824ee62c0fc357b4081855e43253a948, type: 3}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_FlipX: 0
|
||||||
|
m_FlipY: 0
|
||||||
|
m_DrawMode: 0
|
||||||
|
m_Size: {x: 1, y: 1}
|
||||||
|
m_AdaptiveModeThreshold: 0.5
|
||||||
|
m_SpriteTileMode: 0
|
||||||
|
m_WasSpriteAssigned: 1
|
||||||
|
m_MaskInteraction: 0
|
||||||
|
m_SpriteSortPoint: 0
|
||||||
|
--- !u!50 &520653813702449573
|
||||||
|
Rigidbody2D:
|
||||||
|
serializedVersion: 4
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_BodyType: 0
|
||||||
|
m_Simulated: 1
|
||||||
|
m_UseFullKinematicContacts: 0
|
||||||
|
m_UseAutoMass: 0
|
||||||
|
m_Mass: 0.0001
|
||||||
|
m_LinearDrag: 0
|
||||||
|
m_AngularDrag: 0
|
||||||
|
m_GravityScale: 0
|
||||||
|
m_Material: {fileID: 6200000, guid: 315510c0721e82f4cad07c2669b863fa, type: 2}
|
||||||
|
m_Interpolate: 2
|
||||||
|
m_SleepingMode: 1
|
||||||
|
m_CollisionDetection: 1
|
||||||
|
m_Constraints: 4
|
||||||
|
--- !u!114 &440601958556739609
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 9b91ecbcc199f4492b9a91e820070131, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
sceneId: 0
|
||||||
|
serverOnly: 0
|
||||||
|
visible: 0
|
||||||
|
m_AssetId: 5339554c46006dd4e91cae9ff34c095d
|
||||||
|
hasSpawned: 0
|
||||||
|
--- !u!114 &440842259441939327
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2f74aedd71d9a4f55b3ce499326d45fb, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0.1
|
||||||
|
clientAuthority: 0
|
||||||
|
localPositionSensitivity: 0.01
|
||||||
|
localRotationSensitivity: 0.01
|
||||||
|
localScaleSensitivity: 0.01
|
||||||
|
compressRotation: 0
|
||||||
|
interpolatePosition: 1
|
||||||
|
interpolateRotation: 1
|
||||||
|
interpolateScale: 1
|
||||||
|
syncScale: 1
|
||||||
|
--- !u!58 &8881572407762724401
|
||||||
|
CircleCollider2D:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_Density: 1
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_UsedByEffector: 0
|
||||||
|
m_UsedByComposite: 0
|
||||||
|
m_Offset: {x: 0, y: 0}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Radius: 1.28
|
||||||
|
--- !u!114 &5995301680282788937
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 542835289192032773}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2a08d5ab1f59230458264367f00c54d8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
syncMode: 0
|
||||||
|
syncInterval: 0.1
|
||||||
|
speed: 70
|
||||||
7
Assets/Ignorance/Demo/PongChamp/TenryuuBall.prefab.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5339554c46006dd4e91cae9ff34c095d
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo/PongChamp/Textures.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 23b5913b9b8b2e1419a41acde1b49883
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
128
Assets/Ignorance/Demo/PongChamp/Textures/PoutRyuu.png.meta
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 824ee62c0fc357b4081855e43253a948
|
||||||
|
TextureImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 11
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: -1
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: -1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
applyGammaDecoding: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: iPhone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
- serializedVersion: 3
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 5e97eb03825dee720800000000000000
|
||||||
|
internalID: 0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
secondaryTextures: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Ignorance/Demo/PongChamp/Textures/Sprites.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0dbfc247338e79a4dbe7474f69b46503
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Ball.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,88 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 03167da12fa50334e8c8641a23df41b0
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: -3
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: 16
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 1
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: c5a291323e0d5f34883a55625f66ca70
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/Ignorance/Demo/PongChamp/Textures/Sprites/DottedLine.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,88 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 75254f20e37ff3640beccde38f796fed
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: -3
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: 16
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 1
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 98b4e2aa86aa3d843821adfe71dbbac0
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/Ignorance/Demo/PongChamp/Textures/Sprites/Racket.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,88 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e11aad367beb44f4b8a3def9b8fc57ec
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: -3
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: 16
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 1
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 09819c66a21defd49b2cfc87fea685d2
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,88 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 51f6a08479c829a49b6a15df6849e727
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: -3
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: 16
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 1
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 74c5541eed52f67428025c83260d8bec
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -0,0 +1,88 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b41679787bea72d419d10a6df7dc137f
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: -3
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: 0
|
||||||
|
aniso: 16
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: 1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 1
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 3a92f998f14389948aa928ac64e8e426
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
BIN
Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
121
Assets/Ignorance/Demo/PongChamp/Textures/pogchamp.png.meta
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 160d53f9f2b149c418d6d07e95438e53
|
||||||
|
TextureImporter:
|
||||||
|
fileIDToRecycleName: {}
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 9
|
||||||
|
mipmaps:
|
||||||
|
mipMapMode: 0
|
||||||
|
enableMipMap: 0
|
||||||
|
sRGBTexture: 1
|
||||||
|
linearTexture: 0
|
||||||
|
fadeOut: 0
|
||||||
|
borderMipMap: 0
|
||||||
|
mipMapsPreserveCoverage: 0
|
||||||
|
alphaTestReferenceValue: 0.5
|
||||||
|
mipMapFadeDistanceStart: 1
|
||||||
|
mipMapFadeDistanceEnd: 3
|
||||||
|
bumpmap:
|
||||||
|
convertToNormalMap: 0
|
||||||
|
externalNormalMap: 0
|
||||||
|
heightScale: 0.25
|
||||||
|
normalMapFilter: 0
|
||||||
|
isReadable: 0
|
||||||
|
streamingMipmaps: 0
|
||||||
|
streamingMipmapsPriority: 0
|
||||||
|
grayScaleToAlpha: 0
|
||||||
|
generateCubemap: 6
|
||||||
|
cubemapConvolution: 0
|
||||||
|
seamlessCubemap: 0
|
||||||
|
textureFormat: 1
|
||||||
|
maxTextureSize: 2048
|
||||||
|
textureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
filterMode: -1
|
||||||
|
aniso: -1
|
||||||
|
mipBias: -100
|
||||||
|
wrapU: 1
|
||||||
|
wrapV: 1
|
||||||
|
wrapW: -1
|
||||||
|
nPOTScale: 0
|
||||||
|
lightmap: 0
|
||||||
|
compressionQuality: 50
|
||||||
|
spriteMode: 1
|
||||||
|
spriteExtrude: 1
|
||||||
|
spriteMeshType: 1
|
||||||
|
alignment: 0
|
||||||
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
|
spritePixelsToUnits: 100
|
||||||
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
|
alphaUsage: 1
|
||||||
|
alphaIsTransparency: 1
|
||||||
|
spriteTessellationDetail: -1
|
||||||
|
textureType: 8
|
||||||
|
textureShape: 1
|
||||||
|
singleChannelComponent: 0
|
||||||
|
maxTextureSizeSet: 0
|
||||||
|
compressionQualitySet: 0
|
||||||
|
textureFormatSet: 0
|
||||||
|
platformSettings:
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: DefaultTexturePlatform
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: Standalone
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: Android
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
- serializedVersion: 2
|
||||||
|
buildTarget: WebGL
|
||||||
|
maxTextureSize: 2048
|
||||||
|
resizeAlgorithm: 0
|
||||||
|
textureFormat: -1
|
||||||
|
textureCompression: 1
|
||||||
|
compressionQuality: 50
|
||||||
|
crunchedCompression: 0
|
||||||
|
allowsAlphaSplitting: 0
|
||||||
|
overridden: 0
|
||||||
|
androidETC2FallbackOverride: 0
|
||||||
|
spriteSheet:
|
||||||
|
serializedVersion: 2
|
||||||
|
sprites: []
|
||||||
|
outline: []
|
||||||
|
physicsShape: []
|
||||||
|
bones: []
|
||||||
|
spriteID: 1a75587224e4a5f468c03dbd1af78d0b
|
||||||
|
vertices: []
|
||||||
|
indices:
|
||||||
|
edges: []
|
||||||
|
weights: []
|
||||||
|
spritePackingTag:
|
||||||
|
pSDRemoveMatte: 0
|
||||||
|
pSDShowRemoveMatteOption: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5cf8eb36be0834b3da408c694a41cb88
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/Authenticators.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1b2f9d254154cd942ba40b06b869b8f3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
192
Assets/Mirror/Authenticators/BasicAuthenticator.cs
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Authenticators
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Authenticators/Basic Authenticator")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-authenticators/basic-authenticator")]
|
||||||
|
public class BasicAuthenticator : NetworkAuthenticator
|
||||||
|
{
|
||||||
|
[Header("Server Credentials")]
|
||||||
|
public string serverUsername;
|
||||||
|
public string serverPassword;
|
||||||
|
|
||||||
|
[Header("Client Credentials")]
|
||||||
|
public string username;
|
||||||
|
public string password;
|
||||||
|
|
||||||
|
readonly HashSet<NetworkConnection> connectionsPendingDisconnect = new HashSet<NetworkConnection>();
|
||||||
|
|
||||||
|
#region Messages
|
||||||
|
|
||||||
|
public struct AuthRequestMessage : NetworkMessage
|
||||||
|
{
|
||||||
|
// use whatever credentials make sense for your game
|
||||||
|
// for example, you might want to pass the accessToken if using oauth
|
||||||
|
public string authUsername;
|
||||||
|
public string authPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AuthResponseMessage : NetworkMessage
|
||||||
|
{
|
||||||
|
public byte code;
|
||||||
|
public string message;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Server
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from StartServer to initialize the Authenticator
|
||||||
|
/// <para>Server message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStartServer()
|
||||||
|
{
|
||||||
|
// register a handler for the authentication request we expect from client
|
||||||
|
NetworkServer.RegisterHandler<AuthRequestMessage>(OnAuthRequestMessage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from StopServer to reset the Authenticator
|
||||||
|
/// <para>Server message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStopServer()
|
||||||
|
{
|
||||||
|
// unregister the handler for the authentication request
|
||||||
|
NetworkServer.UnregisterHandler<AuthRequestMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from OnServerConnectInternal when a client needs to authenticate
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">Connection to client.</param>
|
||||||
|
public override void OnServerAuthenticate(NetworkConnectionToClient conn)
|
||||||
|
{
|
||||||
|
// do nothing...wait for AuthRequestMessage from client
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server when the client's AuthRequestMessage arrives
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">Connection to client.</param>
|
||||||
|
/// <param name="msg">The message payload</param>
|
||||||
|
public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
|
||||||
|
{
|
||||||
|
//Debug.Log($"Authentication Request: {msg.authUsername} {msg.authPassword}");
|
||||||
|
|
||||||
|
if (connectionsPendingDisconnect.Contains(conn)) return;
|
||||||
|
|
||||||
|
// check the credentials by calling your web server, database table, playfab api, or any method appropriate.
|
||||||
|
if (msg.authUsername == serverUsername && msg.authPassword == serverPassword)
|
||||||
|
{
|
||||||
|
// create and send msg to client so it knows to proceed
|
||||||
|
AuthResponseMessage authResponseMessage = new AuthResponseMessage
|
||||||
|
{
|
||||||
|
code = 100,
|
||||||
|
message = "Success"
|
||||||
|
};
|
||||||
|
|
||||||
|
conn.Send(authResponseMessage);
|
||||||
|
|
||||||
|
// Accept the successful authentication
|
||||||
|
ServerAccept(conn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
connectionsPendingDisconnect.Add(conn);
|
||||||
|
|
||||||
|
// create and send msg to client so it knows to disconnect
|
||||||
|
AuthResponseMessage authResponseMessage = new AuthResponseMessage
|
||||||
|
{
|
||||||
|
code = 200,
|
||||||
|
message = "Invalid Credentials"
|
||||||
|
};
|
||||||
|
|
||||||
|
conn.Send(authResponseMessage);
|
||||||
|
|
||||||
|
// must set NetworkConnection isAuthenticated = false
|
||||||
|
conn.isAuthenticated = false;
|
||||||
|
|
||||||
|
// disconnect the client after 1 second so that response message gets delivered
|
||||||
|
StartCoroutine(DelayedDisconnect(conn, 1f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator DelayedDisconnect(NetworkConnectionToClient conn, float waitTime)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(waitTime);
|
||||||
|
|
||||||
|
// Reject the unsuccessful authentication
|
||||||
|
ServerReject(conn);
|
||||||
|
|
||||||
|
yield return null;
|
||||||
|
|
||||||
|
// remove conn from pending connections
|
||||||
|
connectionsPendingDisconnect.Remove(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Client
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from StartClient to initialize the Authenticator
|
||||||
|
/// <para>Client message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStartClient()
|
||||||
|
{
|
||||||
|
// register a handler for the authentication response we expect from server
|
||||||
|
NetworkClient.RegisterHandler<AuthResponseMessage>(OnAuthResponseMessage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from StopClient to reset the Authenticator
|
||||||
|
/// <para>Client message handlers should be unregistered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStopClient()
|
||||||
|
{
|
||||||
|
// unregister the handler for the authentication response
|
||||||
|
NetworkClient.UnregisterHandler<AuthResponseMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from OnClientConnectInternal when a client needs to authenticate
|
||||||
|
/// </summary>
|
||||||
|
public override void OnClientAuthenticate()
|
||||||
|
{
|
||||||
|
AuthRequestMessage authRequestMessage = new AuthRequestMessage
|
||||||
|
{
|
||||||
|
authUsername = username,
|
||||||
|
authPassword = password
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkClient.connection.Send(authRequestMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client when the server's AuthResponseMessage arrives
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">The message payload</param>
|
||||||
|
public void OnAuthResponseMessage(AuthResponseMessage msg)
|
||||||
|
{
|
||||||
|
if (msg.code == 100)
|
||||||
|
{
|
||||||
|
//Debug.Log($"Authentication Response: {msg.message}");
|
||||||
|
|
||||||
|
// Authentication has been accepted
|
||||||
|
ClientAccept();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"Authentication Response: {msg.message}");
|
||||||
|
|
||||||
|
// Authentication has been rejected
|
||||||
|
ClientReject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Authenticators/BasicAuthenticator.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28496b776660156428f00cf78289c1ec
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
129
Assets/Mirror/Authenticators/DeviceAuthenticator.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Authenticators
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An authenticator that identifies the user by their device.
|
||||||
|
/// <para>A GUID is used as a fallback when the platform doesn't support SystemInfo.deviceUniqueIdentifier.</para>
|
||||||
|
/// <para>Note: deviceUniqueIdentifier can be spoofed, so security is not guaranteed.</para>
|
||||||
|
/// <para>See https://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html for details.</para>
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("Network/ Authenticators/Device Authenticator")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-authenticators/device-authenticator")]
|
||||||
|
public class DeviceAuthenticator : NetworkAuthenticator
|
||||||
|
{
|
||||||
|
#region Messages
|
||||||
|
|
||||||
|
public struct AuthRequestMessage : NetworkMessage
|
||||||
|
{
|
||||||
|
public string clientDeviceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AuthResponseMessage : NetworkMessage { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Server
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from StartServer to initialize the Authenticator
|
||||||
|
/// <para>Server message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStartServer()
|
||||||
|
{
|
||||||
|
// register a handler for the authentication request we expect from client
|
||||||
|
NetworkServer.RegisterHandler<AuthRequestMessage>(OnAuthRequestMessage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from StopServer to reset the Authenticator
|
||||||
|
/// <para>Server message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStopServer()
|
||||||
|
{
|
||||||
|
// unregister the handler for the authentication request
|
||||||
|
NetworkServer.UnregisterHandler<AuthRequestMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on server from OnServerConnectInternal when a client needs to authenticate
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conn">Connection to client.</param>
|
||||||
|
public override void OnServerAuthenticate(NetworkConnectionToClient conn)
|
||||||
|
{
|
||||||
|
// do nothing, wait for client to send his id
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
|
||||||
|
{
|
||||||
|
Debug.Log($"connection {conn.connectionId} authenticated with id {msg.clientDeviceID}");
|
||||||
|
|
||||||
|
// Store the device id for later reference, e.g. when spawning the player
|
||||||
|
conn.authenticationData = msg.clientDeviceID;
|
||||||
|
|
||||||
|
// Send a response to client telling it to proceed as authenticated
|
||||||
|
conn.Send(new AuthResponseMessage());
|
||||||
|
|
||||||
|
// Accept the successful authentication
|
||||||
|
ServerAccept(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Client
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from StartClient to initialize the Authenticator
|
||||||
|
/// <para>Client message handlers should be registered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStartClient()
|
||||||
|
{
|
||||||
|
// register a handler for the authentication response we expect from server
|
||||||
|
NetworkClient.RegisterHandler<AuthResponseMessage>(OnAuthResponseMessage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from StopClient to reset the Authenticator
|
||||||
|
/// <para>Client message handlers should be unregistered in this method.</para>
|
||||||
|
/// </summary>
|
||||||
|
public override void OnStopClient()
|
||||||
|
{
|
||||||
|
// unregister the handler for the authentication response
|
||||||
|
NetworkClient.UnregisterHandler<AuthResponseMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client from OnClientConnectInternal when a client needs to authenticate
|
||||||
|
/// </summary>
|
||||||
|
public override void OnClientAuthenticate()
|
||||||
|
{
|
||||||
|
string deviceUniqueIdentifier = SystemInfo.deviceUniqueIdentifier;
|
||||||
|
|
||||||
|
// Not all platforms support this, so we use a GUID instead
|
||||||
|
if (deviceUniqueIdentifier == SystemInfo.unsupportedIdentifier)
|
||||||
|
{
|
||||||
|
// Get the value from PlayerPrefs if it exists, new GUID if it doesn't
|
||||||
|
deviceUniqueIdentifier = PlayerPrefs.GetString("deviceUniqueIdentifier", Guid.NewGuid().ToString());
|
||||||
|
|
||||||
|
// Store the deviceUniqueIdentifier to PlayerPrefs (in case we just made a new GUID)
|
||||||
|
PlayerPrefs.SetString("deviceUniqueIdentifier", deviceUniqueIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the deviceUniqueIdentifier to the server
|
||||||
|
NetworkClient.connection.Send(new AuthRequestMessage { clientDeviceID = deviceUniqueIdentifier } );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called on client when the server's AuthResponseMessage arrives
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">The message payload</param>
|
||||||
|
public void OnAuthResponseMessage(AuthResponseMessage msg)
|
||||||
|
{
|
||||||
|
Debug.Log("Authentication Success");
|
||||||
|
ClientAccept();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Authenticators/DeviceAuthenticator.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 60960a6ba81a842deb2fdcdc93788242
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
14
Assets/Mirror/Authenticators/Mirror.Authenticators.asmdef
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "Mirror.Authenticators",
|
||||||
|
"references": [
|
||||||
|
"Mirror"
|
||||||
|
],
|
||||||
|
"optionalUnityReferences": [],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": []
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e720aa64e3f58fb4880566a322584340
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
70
Assets/Mirror/Authenticators/TimeoutAuthenticator.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Authenticators
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An authenticator that disconnects connections if they don't
|
||||||
|
/// authenticate within a specified time limit.
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("Network/ Authenticators/Timeout Authenticator")]
|
||||||
|
public class TimeoutAuthenticator : NetworkAuthenticator
|
||||||
|
{
|
||||||
|
public NetworkAuthenticator authenticator;
|
||||||
|
|
||||||
|
[Range(0, 600), Tooltip("Timeout to auto-disconnect in seconds. Set to 0 for no timeout.")]
|
||||||
|
public float timeout = 60;
|
||||||
|
|
||||||
|
public void Awake()
|
||||||
|
{
|
||||||
|
authenticator.OnServerAuthenticated.AddListener(connection => OnServerAuthenticated.Invoke(connection));
|
||||||
|
authenticator.OnClientAuthenticated.AddListener(OnClientAuthenticated.Invoke);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStartServer()
|
||||||
|
{
|
||||||
|
authenticator.OnStartServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStopServer()
|
||||||
|
{
|
||||||
|
authenticator.OnStopServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStartClient()
|
||||||
|
{
|
||||||
|
authenticator.OnStartClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnStopClient()
|
||||||
|
{
|
||||||
|
authenticator.OnStopClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnServerAuthenticate(NetworkConnectionToClient conn)
|
||||||
|
{
|
||||||
|
authenticator.OnServerAuthenticate(conn);
|
||||||
|
if (timeout > 0)
|
||||||
|
StartCoroutine(BeginAuthentication(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnClientAuthenticate()
|
||||||
|
{
|
||||||
|
authenticator.OnClientAuthenticate();
|
||||||
|
if (timeout > 0)
|
||||||
|
StartCoroutine(BeginAuthentication(NetworkClient.connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator BeginAuthentication(NetworkConnection conn)
|
||||||
|
{
|
||||||
|
//Debug.Log($"Authentication countdown started {conn} {timeout}");
|
||||||
|
yield return new WaitForSecondsRealtime(timeout);
|
||||||
|
|
||||||
|
if (!conn.isAuthenticated)
|
||||||
|
{
|
||||||
|
Debug.LogError($"Authentication Timeout - Disconnecting {conn}");
|
||||||
|
conn.Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Authenticators/TimeoutAuthenticator.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 24d8269a07b8e4edfa374753a91c946e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/CompilerSymbols.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1f8b918bcd89f5c488b06f5574f34760
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
14
Assets/Mirror/CompilerSymbols/Mirror.CompilerSymbols.asmdef
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"name": "Mirror.CompilerSymbols",
|
||||||
|
"references": [],
|
||||||
|
"optionalUnityReferences": [],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": []
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 325984b52e4128546bc7558552f8b1d2
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
60
Assets/Mirror/CompilerSymbols/PreprocessorDefine.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
static class PreprocessorDefine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add define symbols as soon as Unity gets done compiling.
|
||||||
|
/// </summary>
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
public static void AddDefineSymbols()
|
||||||
|
{
|
||||||
|
string currentDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||||||
|
HashSet<string> defines = new HashSet<string>(currentDefines.Split(';'))
|
||||||
|
{
|
||||||
|
"MIRROR",
|
||||||
|
"MIRROR_17_0_OR_NEWER",
|
||||||
|
"MIRROR_18_0_OR_NEWER",
|
||||||
|
"MIRROR_24_0_OR_NEWER",
|
||||||
|
"MIRROR_26_0_OR_NEWER",
|
||||||
|
"MIRROR_27_0_OR_NEWER",
|
||||||
|
"MIRROR_28_0_OR_NEWER",
|
||||||
|
"MIRROR_29_0_OR_NEWER",
|
||||||
|
"MIRROR_30_0_OR_NEWER",
|
||||||
|
"MIRROR_30_5_2_OR_NEWER",
|
||||||
|
"MIRROR_32_1_2_OR_NEWER",
|
||||||
|
"MIRROR_32_1_4_OR_NEWER",
|
||||||
|
"MIRROR_35_0_OR_NEWER",
|
||||||
|
"MIRROR_35_1_OR_NEWER",
|
||||||
|
"MIRROR_37_0_OR_NEWER",
|
||||||
|
"MIRROR_38_0_OR_NEWER",
|
||||||
|
"MIRROR_39_0_OR_NEWER",
|
||||||
|
"MIRROR_40_0_OR_NEWER",
|
||||||
|
"MIRROR_41_0_OR_NEWER",
|
||||||
|
"MIRROR_42_0_OR_NEWER",
|
||||||
|
"MIRROR_43_0_OR_NEWER",
|
||||||
|
"MIRROR_44_0_OR_NEWER",
|
||||||
|
"MIRROR_46_0_OR_NEWER",
|
||||||
|
"MIRROR_47_0_OR_NEWER",
|
||||||
|
"MIRROR_53_0_OR_NEWER",
|
||||||
|
"MIRROR_55_0_OR_NEWER",
|
||||||
|
"MIRROR_57_0_OR_NEWER",
|
||||||
|
"MIRROR_58_0_OR_NEWER",
|
||||||
|
"MIRROR_65_0_OR_NEWER",
|
||||||
|
"MIRROR_66_0_OR_NEWER",
|
||||||
|
"MIRROR_2022_9_OR_NEWER",
|
||||||
|
"MIRROR_2022_10_OR_NEWER",
|
||||||
|
};
|
||||||
|
|
||||||
|
// only touch PlayerSettings if we actually modified it.
|
||||||
|
// otherwise it shows up as changed in git each time.
|
||||||
|
string newDefines = string.Join(";", defines);
|
||||||
|
if (newDefines != currentDefines)
|
||||||
|
{
|
||||||
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, newDefines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/CompilerSymbols/PreprocessorDefine.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f1d66fe74ec6f42dd974cba37d25d453
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/Components.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9bee879fbc8ef4b1a9a9f7088bfbf726
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
12
Assets/Mirror/Components/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests.Common")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests")]
|
||||||
|
// need to use Unity.*.CodeGen assembly name to import Unity.CompilationPipeline
|
||||||
|
// for ILPostProcessor tests.
|
||||||
|
[assembly: InternalsVisibleTo("Unity.Mirror.Tests.CodeGen")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests.Generated")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests.Runtime")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests.Performance.Editor")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Tests.Performance.Runtime")]
|
||||||
|
[assembly: InternalsVisibleTo("Mirror.Editor")]
|
||||||
11
Assets/Mirror/Components/AssemblyInfo.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a65b9283f7a724e70b8e17cb277f4c1e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/Components/Discovery.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b5dcf9618f5e14a4eb60bff5480284a6
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
111
Assets/Mirror/Components/Discovery/NetworkDiscovery.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Events;
|
||||||
|
|
||||||
|
namespace Mirror.Discovery
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ServerFoundUnityEvent : UnityEvent<ServerResponse> {};
|
||||||
|
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[AddComponentMenu("Network/Network Discovery")]
|
||||||
|
public class NetworkDiscovery : NetworkDiscoveryBase<ServerRequest, ServerResponse>
|
||||||
|
{
|
||||||
|
#region Server
|
||||||
|
|
||||||
|
public long ServerId { get; private set; }
|
||||||
|
|
||||||
|
[Tooltip("Transport to be advertised during discovery")]
|
||||||
|
public Transport transport;
|
||||||
|
|
||||||
|
[Tooltip("Invoked when a server is found")]
|
||||||
|
public ServerFoundUnityEvent OnServerFound;
|
||||||
|
|
||||||
|
public override void Start()
|
||||||
|
{
|
||||||
|
ServerId = RandomLong();
|
||||||
|
|
||||||
|
// active transport gets initialized in awake
|
||||||
|
// so make sure we set it here in Start() (after awakes)
|
||||||
|
// Or just let the user assign it in the inspector
|
||||||
|
if (transport == null)
|
||||||
|
transport = Transport.active;
|
||||||
|
|
||||||
|
base.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process the request from a client
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Override if you wish to provide more information to the clients
|
||||||
|
/// such as the name of the host player
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request">Request coming from client</param>
|
||||||
|
/// <param name="endpoint">Address of the client that sent the request</param>
|
||||||
|
/// <returns>The message to be sent back to the client or null</returns>
|
||||||
|
protected override ServerResponse ProcessRequest(ServerRequest request, IPEndPoint endpoint)
|
||||||
|
{
|
||||||
|
// In this case we don't do anything with the request
|
||||||
|
// but other discovery implementations might want to use the data
|
||||||
|
// in there, This way the client can ask for
|
||||||
|
// specific game mode or something
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// this is an example reply message, return your own
|
||||||
|
// to include whatever is relevant for your game
|
||||||
|
return new ServerResponse
|
||||||
|
{
|
||||||
|
serverId = ServerId,
|
||||||
|
uri = transport.ServerUri()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (NotImplementedException)
|
||||||
|
{
|
||||||
|
Debug.LogError($"Transport {transport} does not support network discovery");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Client
|
||||||
|
/// <summary>
|
||||||
|
/// Create a message that will be broadcasted on the network to discover servers
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Override if you wish to include additional data in the discovery message
|
||||||
|
/// such as desired game mode, language, difficulty, etc... </remarks>
|
||||||
|
/// <returns>An instance of ServerRequest with data to be broadcasted</returns>
|
||||||
|
protected override ServerRequest GetRequest() => new ServerRequest();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process the answer from a server
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A client receives a reply from a server, this method processes the
|
||||||
|
/// reply and raises an event
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="response">Response that came from the server</param>
|
||||||
|
/// <param name="endpoint">Address of the server that replied</param>
|
||||||
|
protected override void ProcessResponse(ServerResponse response, IPEndPoint endpoint)
|
||||||
|
{
|
||||||
|
// we received a message from the remote endpoint
|
||||||
|
response.EndPoint = endpoint;
|
||||||
|
|
||||||
|
// although we got a supposedly valid url, we may not be able to resolve
|
||||||
|
// the provided host
|
||||||
|
// However we know the real ip address of the server because we just
|
||||||
|
// received a packet from it, so use that as host.
|
||||||
|
UriBuilder realUri = new UriBuilder(response.uri)
|
||||||
|
{
|
||||||
|
Host = response.EndPoint.Address.ToString()
|
||||||
|
};
|
||||||
|
response.uri = realUri.Uri;
|
||||||
|
|
||||||
|
OnServerFound.Invoke(response);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Components/Discovery/NetworkDiscovery.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c761308e733c51245b2e8bb4201f46dc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
449
Assets/Mirror/Components/Discovery/NetworkDiscoveryBase.cs
Normal file
|
|
@ -0,0 +1,449 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
// Based on https://github.com/EnlightenedOne/MirrorNetworkDiscovery
|
||||||
|
// forked from https://github.com/in0finite/MirrorNetworkDiscovery
|
||||||
|
// Both are MIT Licensed
|
||||||
|
|
||||||
|
namespace Mirror.Discovery
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base implementation for Network Discovery. Extend this component
|
||||||
|
/// to provide custom discovery with game specific data
|
||||||
|
/// <see cref="NetworkDiscovery">NetworkDiscovery</see> for a sample implementation
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-discovery")]
|
||||||
|
public abstract class NetworkDiscoveryBase<Request, Response> : MonoBehaviour
|
||||||
|
where Request : NetworkMessage
|
||||||
|
where Response : NetworkMessage
|
||||||
|
{
|
||||||
|
public static bool SupportedOnThisPlatform { get { return Application.platform != RuntimePlatform.WebGLPlayer; } }
|
||||||
|
|
||||||
|
// each game should have a random unique handshake, this way you can tell if this is the same game or not
|
||||||
|
[HideInInspector]
|
||||||
|
public long secretHandshake;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("The UDP port the server will listen for multi-cast messages")]
|
||||||
|
protected int serverBroadcastListenPort = 47777;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("If true, broadcasts a discovery request every ActiveDiscoveryInterval seconds")]
|
||||||
|
public bool enableActiveDiscovery = true;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
[Tooltip("Time in seconds between multi-cast messages")]
|
||||||
|
[Range(1, 60)]
|
||||||
|
float ActiveDiscoveryInterval = 3;
|
||||||
|
|
||||||
|
// broadcast address needs to be configurable on iOS:
|
||||||
|
// https://github.com/vis2k/Mirror/pull/3255
|
||||||
|
public string BroadcastAddress = "";
|
||||||
|
|
||||||
|
protected UdpClient serverUdpClient;
|
||||||
|
protected UdpClient clientUdpClient;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
void OnValidate()
|
||||||
|
{
|
||||||
|
if (secretHandshake == 0)
|
||||||
|
{
|
||||||
|
secretHandshake = RandomLong();
|
||||||
|
UnityEditor.Undo.RecordObject(this, "Set secret handshake");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static long RandomLong()
|
||||||
|
{
|
||||||
|
int value1 = UnityEngine.Random.Range(int.MinValue, int.MaxValue);
|
||||||
|
int value2 = UnityEngine.Random.Range(int.MinValue, int.MaxValue);
|
||||||
|
return value1 + ((long)value2 << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// virtual so that inheriting classes' Start() can call base.Start() too
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Start()
|
||||||
|
{
|
||||||
|
// Server mode? then start advertising
|
||||||
|
#if UNITY_SERVER
|
||||||
|
AdvertiseServer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the ports are cleared no matter when Game/Unity UI exits
|
||||||
|
void OnApplicationQuit()
|
||||||
|
{
|
||||||
|
//Debug.Log("NetworkDiscoveryBase OnApplicationQuit");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDisable()
|
||||||
|
{
|
||||||
|
//Debug.Log("NetworkDiscoveryBase OnDisable");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
//Debug.Log("NetworkDiscoveryBase OnDestroy");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown()
|
||||||
|
{
|
||||||
|
EndpMulticastLock();
|
||||||
|
if (serverUdpClient != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serverUdpClient.Close();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// it is just close, swallow the error
|
||||||
|
}
|
||||||
|
|
||||||
|
serverUdpClient = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientUdpClient != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
clientUdpClient.Close();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// it is just close, swallow the error
|
||||||
|
}
|
||||||
|
|
||||||
|
clientUdpClient = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CancelInvoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Server
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advertise this server in the local network
|
||||||
|
/// </summary>
|
||||||
|
public void AdvertiseServer()
|
||||||
|
{
|
||||||
|
if (!SupportedOnThisPlatform)
|
||||||
|
throw new PlatformNotSupportedException("Network discovery not supported in this platform");
|
||||||
|
|
||||||
|
StopDiscovery();
|
||||||
|
|
||||||
|
// Setup port -- may throw exception
|
||||||
|
serverUdpClient = new UdpClient(serverBroadcastListenPort)
|
||||||
|
{
|
||||||
|
EnableBroadcast = true,
|
||||||
|
MulticastLoopback = false
|
||||||
|
};
|
||||||
|
|
||||||
|
// listen for client pings
|
||||||
|
_ = ServerListenAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ServerListenAsync()
|
||||||
|
{
|
||||||
|
BeginMulticastLock();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ReceiveRequestAsync(serverUdpClient);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// socket has been closed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task ReceiveRequestAsync(UdpClient udpClient)
|
||||||
|
{
|
||||||
|
// only proceed if there is available data in network buffer, or otherwise Receive() will block
|
||||||
|
// average time for UdpClient.Available : 10 us
|
||||||
|
|
||||||
|
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
|
||||||
|
|
||||||
|
using (NetworkReaderPooled networkReader = NetworkReaderPool.Get(udpReceiveResult.Buffer))
|
||||||
|
{
|
||||||
|
long handshake = networkReader.ReadLong();
|
||||||
|
if (handshake != secretHandshake)
|
||||||
|
{
|
||||||
|
// message is not for us
|
||||||
|
throw new ProtocolViolationException("Invalid handshake");
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = networkReader.Read<Request>();
|
||||||
|
|
||||||
|
ProcessClientRequest(request, udpReceiveResult.RemoteEndPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reply to the client to inform it of this server
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Override if you wish to ignore server requests based on
|
||||||
|
/// custom criteria such as language, full server game mode or difficulty
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request">Request coming from client</param>
|
||||||
|
/// <param name="endpoint">Address of the client that sent the request</param>
|
||||||
|
protected virtual void ProcessClientRequest(Request request, IPEndPoint endpoint)
|
||||||
|
{
|
||||||
|
Response info = ProcessRequest(request, endpoint);
|
||||||
|
|
||||||
|
if (info == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
using (NetworkWriterPooled writer = NetworkWriterPool.Get())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writer.WriteLong(secretHandshake);
|
||||||
|
|
||||||
|
writer.Write(info);
|
||||||
|
|
||||||
|
ArraySegment<byte> data = writer.ToArraySegment();
|
||||||
|
// signature matches
|
||||||
|
// send response
|
||||||
|
serverUdpClient.Send(data.Array, data.Count, endpoint);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogException(ex, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process the request from a client
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Override if you wish to provide more information to the clients
|
||||||
|
/// such as the name of the host player
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request">Request coming from client</param>
|
||||||
|
/// <param name="endpoint">Address of the client that sent the request</param>
|
||||||
|
/// <returns>The message to be sent back to the client or null</returns>
|
||||||
|
protected abstract Response ProcessRequest(Request request, IPEndPoint endpoint);
|
||||||
|
|
||||||
|
// Android Multicast fix: https://github.com/vis2k/Mirror/pull/2887
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
AndroidJavaObject multicastLock;
|
||||||
|
bool hasMulticastLock;
|
||||||
|
#endif
|
||||||
|
void BeginMulticastLock()
|
||||||
|
{
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
if (hasMulticastLock) return;
|
||||||
|
|
||||||
|
if (Application.platform == RuntimePlatform.Android)
|
||||||
|
{
|
||||||
|
using (AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"))
|
||||||
|
{
|
||||||
|
using (var wifiManager = activity.Call<AndroidJavaObject>("getSystemService", "wifi"))
|
||||||
|
{
|
||||||
|
multicastLock = wifiManager.Call<AndroidJavaObject>("createMulticastLock", "lock");
|
||||||
|
multicastLock.Call("acquire");
|
||||||
|
hasMulticastLock = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndpMulticastLock()
|
||||||
|
{
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
if (!hasMulticastLock) return;
|
||||||
|
|
||||||
|
multicastLock?.Call("release");
|
||||||
|
hasMulticastLock = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Client
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start Active Discovery
|
||||||
|
/// </summary>
|
||||||
|
public void StartDiscovery()
|
||||||
|
{
|
||||||
|
if (!SupportedOnThisPlatform)
|
||||||
|
throw new PlatformNotSupportedException("Network discovery not supported in this platform");
|
||||||
|
|
||||||
|
StopDiscovery();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Setup port
|
||||||
|
clientUdpClient = new UdpClient(0)
|
||||||
|
{
|
||||||
|
EnableBroadcast = true,
|
||||||
|
MulticastLoopback = false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Free the port if we took it
|
||||||
|
//Debug.LogError("NetworkDiscoveryBase StartDiscovery Exception");
|
||||||
|
Shutdown();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = ClientListenAsync();
|
||||||
|
|
||||||
|
if (enableActiveDiscovery) InvokeRepeating(nameof(BroadcastDiscoveryRequest), 0, ActiveDiscoveryInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop Active Discovery
|
||||||
|
/// </summary>
|
||||||
|
public void StopDiscovery()
|
||||||
|
{
|
||||||
|
//Debug.Log("NetworkDiscoveryBase StopDiscovery");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Awaits for server response
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ClientListenAsync Task</returns>
|
||||||
|
public async Task ClientListenAsync()
|
||||||
|
{
|
||||||
|
// while clientUpdClient to fix:
|
||||||
|
// https://github.com/vis2k/Mirror/pull/2908
|
||||||
|
//
|
||||||
|
// If, you cancel discovery the clientUdpClient is set to null.
|
||||||
|
// However, nothing cancels ClientListenAsync. If we change the if(true)
|
||||||
|
// to check if the client is null. You can properly cancel the discovery,
|
||||||
|
// and kill the listen thread.
|
||||||
|
//
|
||||||
|
// Prior to this fix, if you cancel the discovery search. It crashes the
|
||||||
|
// thread, and is super noisy in the output. As well as causes issues on
|
||||||
|
// the quest.
|
||||||
|
while (clientUdpClient != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await ReceiveGameBroadcastAsync(clientUdpClient);
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// socket was closed, no problem
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends discovery request from client
|
||||||
|
/// </summary>
|
||||||
|
public void BroadcastDiscoveryRequest()
|
||||||
|
{
|
||||||
|
if (clientUdpClient == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (NetworkClient.isConnected)
|
||||||
|
{
|
||||||
|
StopDiscovery();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, serverBroadcastListenPort);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(BroadcastAddress))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
endPoint = new IPEndPoint(IPAddress.Parse(BroadcastAddress), serverBroadcastListenPort);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (NetworkWriterPooled writer = NetworkWriterPool.Get())
|
||||||
|
{
|
||||||
|
writer.WriteLong(secretHandshake);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Request request = GetRequest();
|
||||||
|
|
||||||
|
writer.Write(request);
|
||||||
|
|
||||||
|
ArraySegment<byte> data = writer.ToArraySegment();
|
||||||
|
|
||||||
|
clientUdpClient.SendAsync(data.Array, data.Count, endPoint);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// It is ok if we can't broadcast to one of the addresses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a message that will be broadcasted on the network to discover servers
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Override if you wish to include additional data in the discovery message
|
||||||
|
/// such as desired game mode, language, difficulty, etc... </remarks>
|
||||||
|
/// <returns>An instance of ServerRequest with data to be broadcasted</returns>
|
||||||
|
protected virtual Request GetRequest() => default;
|
||||||
|
|
||||||
|
async Task ReceiveGameBroadcastAsync(UdpClient udpClient)
|
||||||
|
{
|
||||||
|
// only proceed if there is available data in network buffer, or otherwise Receive() will block
|
||||||
|
// average time for UdpClient.Available : 10 us
|
||||||
|
|
||||||
|
UdpReceiveResult udpReceiveResult = await udpClient.ReceiveAsync();
|
||||||
|
|
||||||
|
using (NetworkReaderPooled networkReader = NetworkReaderPool.Get(udpReceiveResult.Buffer))
|
||||||
|
{
|
||||||
|
if (networkReader.ReadLong() != secretHandshake)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Response response = networkReader.Read<Response>();
|
||||||
|
|
||||||
|
ProcessResponse(response, udpReceiveResult.RemoteEndPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process the answer from a server
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A client receives a reply from a server, this method processes the
|
||||||
|
/// reply and raises an event
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="response">Response that came from the server</param>
|
||||||
|
/// <param name="endpoint">Address of the server that replied</param>
|
||||||
|
protected abstract void ProcessResponse(Response response, IPEndPoint endpoint);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b9971d60ce61f4e39b07cd9e7e0c68fa
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
132
Assets/Mirror/Components/Discovery/NetworkDiscoveryHUD.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Discovery
|
||||||
|
{
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[AddComponentMenu("Network/Network Discovery HUD")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-discovery")]
|
||||||
|
[RequireComponent(typeof(NetworkDiscovery))]
|
||||||
|
public class NetworkDiscoveryHUD : MonoBehaviour
|
||||||
|
{
|
||||||
|
readonly Dictionary<long, ServerResponse> discoveredServers = new Dictionary<long, ServerResponse>();
|
||||||
|
Vector2 scrollViewPos = Vector2.zero;
|
||||||
|
|
||||||
|
public NetworkDiscovery networkDiscovery;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
void OnValidate()
|
||||||
|
{
|
||||||
|
if (networkDiscovery == null)
|
||||||
|
{
|
||||||
|
networkDiscovery = GetComponent<NetworkDiscovery>();
|
||||||
|
UnityEditor.Events.UnityEventTools.AddPersistentListener(networkDiscovery.OnServerFound, OnDiscoveredServer);
|
||||||
|
UnityEditor.Undo.RecordObjects(new Object[] { this, networkDiscovery }, "Set NetworkDiscovery");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
if (NetworkManager.singleton == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!NetworkClient.isConnected && !NetworkServer.active && !NetworkClient.active)
|
||||||
|
DrawGUI();
|
||||||
|
|
||||||
|
if (NetworkServer.active || NetworkClient.active)
|
||||||
|
StopButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawGUI()
|
||||||
|
{
|
||||||
|
GUILayout.BeginArea(new Rect(10, 10, 300, 500));
|
||||||
|
GUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Find Servers"))
|
||||||
|
{
|
||||||
|
discoveredServers.Clear();
|
||||||
|
networkDiscovery.StartDiscovery();
|
||||||
|
}
|
||||||
|
|
||||||
|
// LAN Host
|
||||||
|
if (GUILayout.Button("Start Host"))
|
||||||
|
{
|
||||||
|
discoveredServers.Clear();
|
||||||
|
NetworkManager.singleton.StartHost();
|
||||||
|
networkDiscovery.AdvertiseServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dedicated server
|
||||||
|
if (GUILayout.Button("Start Server"))
|
||||||
|
{
|
||||||
|
discoveredServers.Clear();
|
||||||
|
NetworkManager.singleton.StartServer();
|
||||||
|
networkDiscovery.AdvertiseServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
// show list of found server
|
||||||
|
|
||||||
|
GUILayout.Label($"Discovered Servers [{discoveredServers.Count}]:");
|
||||||
|
|
||||||
|
// servers
|
||||||
|
scrollViewPos = GUILayout.BeginScrollView(scrollViewPos);
|
||||||
|
|
||||||
|
foreach (ServerResponse info in discoveredServers.Values)
|
||||||
|
if (GUILayout.Button(info.EndPoint.Address.ToString()))
|
||||||
|
Connect(info);
|
||||||
|
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopButtons()
|
||||||
|
{
|
||||||
|
GUILayout.BeginArea(new Rect(10, 40, 100, 25));
|
||||||
|
|
||||||
|
// stop host if host mode
|
||||||
|
if (NetworkServer.active && NetworkClient.isConnected)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Stop Host"))
|
||||||
|
{
|
||||||
|
NetworkManager.singleton.StopHost();
|
||||||
|
networkDiscovery.StopDiscovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// stop client if client-only
|
||||||
|
else if (NetworkClient.isConnected)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Stop Client"))
|
||||||
|
{
|
||||||
|
NetworkManager.singleton.StopClient();
|
||||||
|
networkDiscovery.StopDiscovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// stop server if server-only
|
||||||
|
else if (NetworkServer.active)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Stop Server"))
|
||||||
|
{
|
||||||
|
NetworkManager.singleton.StopServer();
|
||||||
|
networkDiscovery.StopDiscovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.EndArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connect(ServerResponse info)
|
||||||
|
{
|
||||||
|
networkDiscovery.StopDiscovery();
|
||||||
|
NetworkManager.singleton.StartClient(info.uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDiscoveredServer(ServerResponse info)
|
||||||
|
{
|
||||||
|
// Note that you can check the versioning to decide if you can connect to the server or not using this method
|
||||||
|
discoveredServers[info.serverId] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 88c37d3deca7a834d80cfd8d3cfcc510
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
4
Assets/Mirror/Components/Discovery/ServerRequest.cs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
namespace Mirror.Discovery
|
||||||
|
{
|
||||||
|
public struct ServerRequest : NetworkMessage {}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Components/Discovery/ServerRequest.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ea7254bf7b9454da4adad881d94cd141
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
18
Assets/Mirror/Components/Discovery/ServerResponse.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace Mirror.Discovery
|
||||||
|
{
|
||||||
|
public struct ServerResponse : NetworkMessage
|
||||||
|
{
|
||||||
|
// The server that sent this
|
||||||
|
// this is a property so that it is not serialized, but the
|
||||||
|
// client fills this up after we receive it
|
||||||
|
public IPEndPoint EndPoint { get; set; }
|
||||||
|
|
||||||
|
public Uri uri;
|
||||||
|
|
||||||
|
// Prevent duplicate server appearance when a connection can be made via LAN on multiple NICs
|
||||||
|
public long serverId;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Components/Discovery/ServerResponse.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 36f97227fdf2d7a4e902db5bfc43039c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/Components/Experimental.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bfbf2a1f2b300c5489dcab219ef2846e
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Experimental
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Experimental/Network Lerp Rigidbody")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-lerp-rigidbody")]
|
||||||
|
public class NetworkLerpRigidbody : NetworkBehaviour
|
||||||
|
{
|
||||||
|
[Header("Settings")]
|
||||||
|
[SerializeField] internal Rigidbody target = null;
|
||||||
|
[Tooltip("How quickly current velocity approaches target velocity")]
|
||||||
|
[SerializeField] float lerpVelocityAmount = 0.5f;
|
||||||
|
[Tooltip("How quickly current position approaches target position")]
|
||||||
|
[SerializeField] float lerpPositionAmount = 0.5f;
|
||||||
|
|
||||||
|
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
||||||
|
[SerializeField] bool clientAuthority = false;
|
||||||
|
|
||||||
|
double nextSyncTime;
|
||||||
|
|
||||||
|
|
||||||
|
[SyncVar()]
|
||||||
|
Vector3 targetVelocity;
|
||||||
|
|
||||||
|
[SyncVar()]
|
||||||
|
Vector3 targetPosition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignore value if is host or client with Authority
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool IgnoreSync => isServer || ClientWithAuthority;
|
||||||
|
|
||||||
|
bool ClientWithAuthority => clientAuthority && isOwned;
|
||||||
|
|
||||||
|
void OnValidate()
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
target = GetComponent<Rigidbody>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (isServer)
|
||||||
|
{
|
||||||
|
SyncToClients();
|
||||||
|
}
|
||||||
|
else if (ClientWithAuthority)
|
||||||
|
{
|
||||||
|
SendToServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SyncToClients()
|
||||||
|
{
|
||||||
|
targetVelocity = target.velocity;
|
||||||
|
targetPosition = target.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendToServer()
|
||||||
|
{
|
||||||
|
double now = NetworkTime.localTime; // Unity 2019 doesn't have Time.timeAsDouble yet
|
||||||
|
if (now > nextSyncTime)
|
||||||
|
{
|
||||||
|
nextSyncTime = now + syncInterval;
|
||||||
|
CmdSendState(target.velocity, target.position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendState(Vector3 velocity, Vector3 position)
|
||||||
|
{
|
||||||
|
target.velocity = velocity;
|
||||||
|
target.position = position;
|
||||||
|
targetVelocity = velocity;
|
||||||
|
targetPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (IgnoreSync) { return; }
|
||||||
|
|
||||||
|
target.velocity = Vector3.Lerp(target.velocity, targetVelocity, lerpVelocityAmount);
|
||||||
|
target.position = Vector3.Lerp(target.position, targetPosition, lerpPositionAmount);
|
||||||
|
// add velocity to position as position would have moved on server at that velocity
|
||||||
|
target.position += target.velocity * Time.fixedDeltaTime;
|
||||||
|
|
||||||
|
// TODO does this also need to sync acceleration so and update velocity?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7f032128052c95a46afb0ddd97d994cc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
361
Assets/Mirror/Components/Experimental/NetworkRigidbody.cs
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Experimental
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Experimental/Network Rigidbody")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-rigidbody")]
|
||||||
|
public class NetworkRigidbody : NetworkBehaviour
|
||||||
|
{
|
||||||
|
[Header("Settings")]
|
||||||
|
[SerializeField] internal Rigidbody target = null;
|
||||||
|
|
||||||
|
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
||||||
|
public bool clientAuthority = false;
|
||||||
|
|
||||||
|
[Header("Velocity")]
|
||||||
|
|
||||||
|
[Tooltip("Syncs Velocity every SyncInterval")]
|
||||||
|
[SerializeField] bool syncVelocity = true;
|
||||||
|
|
||||||
|
[Tooltip("Set velocity to 0 each frame (only works if syncVelocity is false")]
|
||||||
|
[SerializeField] bool clearVelocity = false;
|
||||||
|
|
||||||
|
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
||||||
|
[SerializeField] float velocitySensitivity = 0.1f;
|
||||||
|
|
||||||
|
|
||||||
|
[Header("Angular Velocity")]
|
||||||
|
|
||||||
|
[Tooltip("Syncs AngularVelocity every SyncInterval")]
|
||||||
|
[SerializeField] bool syncAngularVelocity = true;
|
||||||
|
|
||||||
|
[Tooltip("Set angularVelocity to 0 each frame (only works if syncAngularVelocity is false")]
|
||||||
|
[SerializeField] bool clearAngularVelocity = false;
|
||||||
|
|
||||||
|
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
||||||
|
[SerializeField] float angularVelocitySensitivity = 0.1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Values sent on client with authority after they are sent to the server
|
||||||
|
/// </summary>
|
||||||
|
readonly ClientSyncState previousValue = new ClientSyncState();
|
||||||
|
|
||||||
|
void OnValidate()
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
target = GetComponent<Rigidbody>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Sync vars
|
||||||
|
[SyncVar(hook = nameof(OnVelocityChanged))]
|
||||||
|
Vector3 velocity;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnAngularVelocityChanged))]
|
||||||
|
Vector3 angularVelocity;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnIsKinematicChanged))]
|
||||||
|
bool isKinematic;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnUseGravityChanged))]
|
||||||
|
bool useGravity;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnuDragChanged))]
|
||||||
|
float drag;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnAngularDragChanged))]
|
||||||
|
float angularDrag;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignore value if is host or client with Authority
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool IgnoreSync => isServer || ClientWithAuthority;
|
||||||
|
|
||||||
|
bool ClientWithAuthority => clientAuthority && isOwned;
|
||||||
|
|
||||||
|
void OnVelocityChanged(Vector3 _, Vector3 newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.velocity = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OnAngularVelocityChanged(Vector3 _, Vector3 newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.angularVelocity = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnIsKinematicChanged(bool _, bool newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.isKinematic = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnUseGravityChanged(bool _, bool newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.useGravity = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnuDragChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.drag = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAngularDragChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.angularDrag = newValue;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
if (isServer)
|
||||||
|
{
|
||||||
|
SyncToClients();
|
||||||
|
}
|
||||||
|
else if (ClientWithAuthority)
|
||||||
|
{
|
||||||
|
SendToServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (clearAngularVelocity && !syncAngularVelocity)
|
||||||
|
{
|
||||||
|
target.angularVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearVelocity && !syncVelocity)
|
||||||
|
{
|
||||||
|
target.velocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates sync var values on server so that they sync to the client
|
||||||
|
/// </summary>
|
||||||
|
[Server]
|
||||||
|
void SyncToClients()
|
||||||
|
{
|
||||||
|
// only update if they have changed more than Sensitivity
|
||||||
|
|
||||||
|
Vector3 currentVelocity = syncVelocity ? target.velocity : default;
|
||||||
|
Vector3 currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
||||||
|
|
||||||
|
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
||||||
|
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
||||||
|
|
||||||
|
if (velocityChanged)
|
||||||
|
{
|
||||||
|
velocity = currentVelocity;
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angularVelocityChanged)
|
||||||
|
{
|
||||||
|
angularVelocity = currentAngularVelocity;
|
||||||
|
previousValue.angularVelocity = currentAngularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// other rigidbody settings
|
||||||
|
isKinematic = target.isKinematic;
|
||||||
|
useGravity = target.useGravity;
|
||||||
|
drag = target.drag;
|
||||||
|
angularDrag = target.angularDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uses Command to send values to server
|
||||||
|
/// </summary>
|
||||||
|
[Client]
|
||||||
|
void SendToServer()
|
||||||
|
{
|
||||||
|
if (!isOwned)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("SendToServer called without authority");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendVelocity();
|
||||||
|
SendRigidBodySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
void SendVelocity()
|
||||||
|
{
|
||||||
|
double now = NetworkTime.localTime; // Unity 2019 doesn't have Time.timeAsDouble yet
|
||||||
|
if (now < previousValue.nextSyncTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 currentVelocity = syncVelocity ? target.velocity : default;
|
||||||
|
Vector3 currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
||||||
|
|
||||||
|
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
||||||
|
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
||||||
|
|
||||||
|
// if angularVelocity has changed it is likely that velocity has also changed so just sync both values
|
||||||
|
// however if only velocity has changed just send velocity
|
||||||
|
if (angularVelocityChanged)
|
||||||
|
{
|
||||||
|
CmdSendVelocityAndAngular(currentVelocity, currentAngularVelocity);
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
previousValue.angularVelocity = currentAngularVelocity;
|
||||||
|
}
|
||||||
|
else if (velocityChanged)
|
||||||
|
{
|
||||||
|
CmdSendVelocity(currentVelocity);
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// only update syncTime if either has changed
|
||||||
|
if (angularVelocityChanged || velocityChanged)
|
||||||
|
{
|
||||||
|
previousValue.nextSyncTime = now + syncInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
void SendRigidBodySettings()
|
||||||
|
{
|
||||||
|
// These shouldn't change often so it is ok to send in their own Command
|
||||||
|
if (previousValue.isKinematic != target.isKinematic)
|
||||||
|
{
|
||||||
|
CmdSendIsKinematic(target.isKinematic);
|
||||||
|
previousValue.isKinematic = target.isKinematic;
|
||||||
|
}
|
||||||
|
if (previousValue.useGravity != target.useGravity)
|
||||||
|
{
|
||||||
|
CmdSendUseGravity(target.useGravity);
|
||||||
|
previousValue.useGravity = target.useGravity;
|
||||||
|
}
|
||||||
|
if (previousValue.drag != target.drag)
|
||||||
|
{
|
||||||
|
CmdSendDrag(target.drag);
|
||||||
|
previousValue.drag = target.drag;
|
||||||
|
}
|
||||||
|
if (previousValue.angularDrag != target.angularDrag)
|
||||||
|
{
|
||||||
|
CmdSendAngularDrag(target.angularDrag);
|
||||||
|
previousValue.angularDrag = target.angularDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when only Velocity has changed on the client
|
||||||
|
/// </summary>
|
||||||
|
[Command]
|
||||||
|
void CmdSendVelocity(Vector3 velocity)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.velocity = velocity;
|
||||||
|
target.velocity = velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when angularVelocity has changed on the client
|
||||||
|
/// </summary>
|
||||||
|
[Command]
|
||||||
|
void CmdSendVelocityAndAngular(Vector3 velocity, Vector3 angularVelocity)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (syncVelocity)
|
||||||
|
{
|
||||||
|
this.velocity = velocity;
|
||||||
|
|
||||||
|
target.velocity = velocity;
|
||||||
|
|
||||||
|
}
|
||||||
|
this.angularVelocity = angularVelocity;
|
||||||
|
target.angularVelocity = angularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendIsKinematic(bool isKinematic)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.isKinematic = isKinematic;
|
||||||
|
target.isKinematic = isKinematic;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendUseGravity(bool useGravity)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.useGravity = useGravity;
|
||||||
|
target.useGravity = useGravity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendDrag(float drag)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.drag = drag;
|
||||||
|
target.drag = drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendAngularDrag(float angularDrag)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.angularDrag = angularDrag;
|
||||||
|
target.angularDrag = angularDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// holds previously synced values
|
||||||
|
/// </summary>
|
||||||
|
public class ClientSyncState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Next sync time that velocity will be synced, based on syncInterval.
|
||||||
|
/// </summary>
|
||||||
|
public double nextSyncTime;
|
||||||
|
public Vector3 velocity;
|
||||||
|
public Vector3 angularVelocity;
|
||||||
|
public bool isKinematic;
|
||||||
|
public bool useGravity;
|
||||||
|
public float drag;
|
||||||
|
public float angularDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 83392ae5c1b731446909f252fd494ae4
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
360
Assets/Mirror/Components/Experimental/NetworkRigidbody2D.cs
Normal file
|
|
@ -0,0 +1,360 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror.Experimental
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Experimental/Network Rigidbody 2D")]
|
||||||
|
public class NetworkRigidbody2D : NetworkBehaviour
|
||||||
|
{
|
||||||
|
[Header("Settings")]
|
||||||
|
[SerializeField] internal Rigidbody2D target = null;
|
||||||
|
|
||||||
|
[Tooltip("Set to true if moves come from owner client, set to false if moves always come from server")]
|
||||||
|
public bool clientAuthority = false;
|
||||||
|
|
||||||
|
[Header("Velocity")]
|
||||||
|
|
||||||
|
[Tooltip("Syncs Velocity every SyncInterval")]
|
||||||
|
[SerializeField] bool syncVelocity = true;
|
||||||
|
|
||||||
|
[Tooltip("Set velocity to 0 each frame (only works if syncVelocity is false")]
|
||||||
|
[SerializeField] bool clearVelocity = false;
|
||||||
|
|
||||||
|
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
||||||
|
[SerializeField] float velocitySensitivity = 0.1f;
|
||||||
|
|
||||||
|
|
||||||
|
[Header("Angular Velocity")]
|
||||||
|
|
||||||
|
[Tooltip("Syncs AngularVelocity every SyncInterval")]
|
||||||
|
[SerializeField] bool syncAngularVelocity = true;
|
||||||
|
|
||||||
|
[Tooltip("Set angularVelocity to 0 each frame (only works if syncAngularVelocity is false")]
|
||||||
|
[SerializeField] bool clearAngularVelocity = false;
|
||||||
|
|
||||||
|
[Tooltip("Only Syncs Value if distance between previous and current is great than sensitivity")]
|
||||||
|
[SerializeField] float angularVelocitySensitivity = 0.1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Values sent on client with authority after they are sent to the server
|
||||||
|
/// </summary>
|
||||||
|
readonly ClientSyncState previousValue = new ClientSyncState();
|
||||||
|
|
||||||
|
void OnValidate()
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
{
|
||||||
|
target = GetComponent<Rigidbody2D>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Sync vars
|
||||||
|
[SyncVar(hook = nameof(OnVelocityChanged))]
|
||||||
|
Vector2 velocity;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnAngularVelocityChanged))]
|
||||||
|
float angularVelocity;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnIsKinematicChanged))]
|
||||||
|
bool isKinematic;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnGravityScaleChanged))]
|
||||||
|
float gravityScale;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnuDragChanged))]
|
||||||
|
float drag;
|
||||||
|
|
||||||
|
[SyncVar(hook = nameof(OnAngularDragChanged))]
|
||||||
|
float angularDrag;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ignore value if is host or client with Authority
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool IgnoreSync => isServer || ClientWithAuthority;
|
||||||
|
|
||||||
|
bool ClientWithAuthority => clientAuthority && isOwned;
|
||||||
|
|
||||||
|
void OnVelocityChanged(Vector2 _, Vector2 newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.velocity = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OnAngularVelocityChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.angularVelocity = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnIsKinematicChanged(bool _, bool newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.isKinematic = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGravityScaleChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.gravityScale = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnuDragChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.drag = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAngularDragChanged(float _, float newValue)
|
||||||
|
{
|
||||||
|
if (IgnoreSync)
|
||||||
|
return;
|
||||||
|
|
||||||
|
target.angularDrag = newValue;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
if (isServer)
|
||||||
|
{
|
||||||
|
SyncToClients();
|
||||||
|
}
|
||||||
|
else if (ClientWithAuthority)
|
||||||
|
{
|
||||||
|
SendToServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (clearAngularVelocity && !syncAngularVelocity)
|
||||||
|
{
|
||||||
|
target.angularVelocity = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearVelocity && !syncVelocity)
|
||||||
|
{
|
||||||
|
target.velocity = Vector2.zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates sync var values on server so that they sync to the client
|
||||||
|
/// </summary>
|
||||||
|
[Server]
|
||||||
|
void SyncToClients()
|
||||||
|
{
|
||||||
|
// only update if they have changed more than Sensitivity
|
||||||
|
|
||||||
|
Vector2 currentVelocity = syncVelocity ? target.velocity : default;
|
||||||
|
float currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
||||||
|
|
||||||
|
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
||||||
|
bool angularVelocityChanged = syncAngularVelocity && ((previousValue.angularVelocity - currentAngularVelocity) > angularVelocitySensitivity);
|
||||||
|
|
||||||
|
if (velocityChanged)
|
||||||
|
{
|
||||||
|
velocity = currentVelocity;
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (angularVelocityChanged)
|
||||||
|
{
|
||||||
|
angularVelocity = currentAngularVelocity;
|
||||||
|
previousValue.angularVelocity = currentAngularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// other rigidbody settings
|
||||||
|
isKinematic = target.isKinematic;
|
||||||
|
gravityScale = target.gravityScale;
|
||||||
|
drag = target.drag;
|
||||||
|
angularDrag = target.angularDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uses Command to send values to server
|
||||||
|
/// </summary>
|
||||||
|
[Client]
|
||||||
|
void SendToServer()
|
||||||
|
{
|
||||||
|
if (!isOwned)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("SendToServer called without authority");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendVelocity();
|
||||||
|
SendRigidBodySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
void SendVelocity()
|
||||||
|
{
|
||||||
|
float now = Time.time;
|
||||||
|
if (now < previousValue.nextSyncTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector2 currentVelocity = syncVelocity ? target.velocity : default;
|
||||||
|
float currentAngularVelocity = syncAngularVelocity ? target.angularVelocity : default;
|
||||||
|
|
||||||
|
bool velocityChanged = syncVelocity && ((previousValue.velocity - currentVelocity).sqrMagnitude > velocitySensitivity * velocitySensitivity);
|
||||||
|
bool angularVelocityChanged = syncAngularVelocity && previousValue.angularVelocity != currentAngularVelocity;//((previousValue.angularVelocity - currentAngularVelocity).sqrMagnitude > angularVelocitySensitivity * angularVelocitySensitivity);
|
||||||
|
|
||||||
|
// if angularVelocity has changed it is likely that velocity has also changed so just sync both values
|
||||||
|
// however if only velocity has changed just send velocity
|
||||||
|
if (angularVelocityChanged)
|
||||||
|
{
|
||||||
|
CmdSendVelocityAndAngular(currentVelocity, currentAngularVelocity);
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
previousValue.angularVelocity = currentAngularVelocity;
|
||||||
|
}
|
||||||
|
else if (velocityChanged)
|
||||||
|
{
|
||||||
|
CmdSendVelocity(currentVelocity);
|
||||||
|
previousValue.velocity = currentVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// only update syncTime if either has changed
|
||||||
|
if (angularVelocityChanged || velocityChanged)
|
||||||
|
{
|
||||||
|
previousValue.nextSyncTime = now + syncInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Client]
|
||||||
|
void SendRigidBodySettings()
|
||||||
|
{
|
||||||
|
// These shouldn't change often so it is ok to send in their own Command
|
||||||
|
if (previousValue.isKinematic != target.isKinematic)
|
||||||
|
{
|
||||||
|
CmdSendIsKinematic(target.isKinematic);
|
||||||
|
previousValue.isKinematic = target.isKinematic;
|
||||||
|
}
|
||||||
|
if (previousValue.gravityScale != target.gravityScale)
|
||||||
|
{
|
||||||
|
CmdChangeGravityScale(target.gravityScale);
|
||||||
|
previousValue.gravityScale = target.gravityScale;
|
||||||
|
}
|
||||||
|
if (previousValue.drag != target.drag)
|
||||||
|
{
|
||||||
|
CmdSendDrag(target.drag);
|
||||||
|
previousValue.drag = target.drag;
|
||||||
|
}
|
||||||
|
if (previousValue.angularDrag != target.angularDrag)
|
||||||
|
{
|
||||||
|
CmdSendAngularDrag(target.angularDrag);
|
||||||
|
previousValue.angularDrag = target.angularDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when only Velocity has changed on the client
|
||||||
|
/// </summary>
|
||||||
|
[Command]
|
||||||
|
void CmdSendVelocity(Vector2 velocity)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.velocity = velocity;
|
||||||
|
target.velocity = velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when angularVelocity has changed on the client
|
||||||
|
/// </summary>
|
||||||
|
[Command]
|
||||||
|
void CmdSendVelocityAndAngular(Vector2 velocity, float angularVelocity)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (syncVelocity)
|
||||||
|
{
|
||||||
|
this.velocity = velocity;
|
||||||
|
|
||||||
|
target.velocity = velocity;
|
||||||
|
|
||||||
|
}
|
||||||
|
this.angularVelocity = angularVelocity;
|
||||||
|
target.angularVelocity = angularVelocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendIsKinematic(bool isKinematic)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.isKinematic = isKinematic;
|
||||||
|
target.isKinematic = isKinematic;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdChangeGravityScale(float gravityScale)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.gravityScale = gravityScale;
|
||||||
|
target.gravityScale = gravityScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendDrag(float drag)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.drag = drag;
|
||||||
|
target.drag = drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command]
|
||||||
|
void CmdSendAngularDrag(float angularDrag)
|
||||||
|
{
|
||||||
|
// Ignore messages from client if not in client authority mode
|
||||||
|
if (!clientAuthority)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.angularDrag = angularDrag;
|
||||||
|
target.angularDrag = angularDrag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// holds previously synced values
|
||||||
|
/// </summary>
|
||||||
|
public class ClientSyncState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Next sync time that velocity will be synced, based on syncInterval.
|
||||||
|
/// </summary>
|
||||||
|
public float nextSyncTime;
|
||||||
|
public Vector2 velocity;
|
||||||
|
public float angularVelocity;
|
||||||
|
public bool isKinematic;
|
||||||
|
public float gravityScale;
|
||||||
|
public float drag;
|
||||||
|
public float angularDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ab2cbc52526ea384ba280d13cd1a57b9
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
115
Assets/Mirror/Components/GUIConsole.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
// People should be able to see and report errors to the developer very easily.
|
||||||
|
//
|
||||||
|
// Unity's Developer Console only works in development builds and it only shows
|
||||||
|
// errors. This class provides a console that works in all builds and also shows
|
||||||
|
// log and warnings in development builds.
|
||||||
|
//
|
||||||
|
// Note: we don't include the stack trace, because that can also be grabbed from
|
||||||
|
// the log files if needed.
|
||||||
|
//
|
||||||
|
// Note: there is no 'hide' button because we DO want people to see those errors
|
||||||
|
// and report them back to us.
|
||||||
|
//
|
||||||
|
// Note: normal Debug.Log messages can be shown by building in Debug/Development
|
||||||
|
// mode.
|
||||||
|
using UnityEngine;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
struct LogEntry
|
||||||
|
{
|
||||||
|
public string message;
|
||||||
|
public LogType type;
|
||||||
|
|
||||||
|
public LogEntry(string message, LogType type)
|
||||||
|
{
|
||||||
|
this.message = message;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GUIConsole : MonoBehaviour
|
||||||
|
{
|
||||||
|
public int height = 150;
|
||||||
|
|
||||||
|
// only keep the recent 'n' entries. otherwise memory would grow forever
|
||||||
|
// and drawing would get slower and slower.
|
||||||
|
public int maxLogCount = 50;
|
||||||
|
|
||||||
|
// log as queue so we can remove the first entry easily
|
||||||
|
Queue<LogEntry> log = new Queue<LogEntry>();
|
||||||
|
|
||||||
|
// hotkey to show/hide at runtime for easier debugging
|
||||||
|
// (sometimes we need to temporarily hide/show it)
|
||||||
|
// => F12 makes sense. nobody can find ^ in other games.
|
||||||
|
public KeyCode hotKey = KeyCode.F12;
|
||||||
|
|
||||||
|
// GUI
|
||||||
|
bool visible;
|
||||||
|
Vector2 scroll = Vector2.zero;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
Application.logMessageReceived += OnLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnLog logs everything, even Debug.Log messages in release builds
|
||||||
|
// => this makes a lot of things easier. e.g. addon initialization logs.
|
||||||
|
// => it's really better to have than not to have those
|
||||||
|
void OnLog(string message, string stackTrace, LogType type)
|
||||||
|
{
|
||||||
|
// is this important?
|
||||||
|
// => always show exceptions & errors
|
||||||
|
// => usually a good idea to show warnings too, otherwise it's too
|
||||||
|
// easy to miss OnDeserialize warnings etc. in builds
|
||||||
|
bool isImportant = type == LogType.Error || type == LogType.Exception || type == LogType.Warning;
|
||||||
|
|
||||||
|
// use stack trace only if important
|
||||||
|
// (otherwise users would have to find and search the log file.
|
||||||
|
// seeing it in the console directly is way easier to deal with.)
|
||||||
|
// => only add \n if stack trace is available (only in debug builds)
|
||||||
|
if (isImportant && !string.IsNullOrWhiteSpace(stackTrace))
|
||||||
|
message += $"\n{stackTrace}";
|
||||||
|
|
||||||
|
// add to queue
|
||||||
|
log.Enqueue(new LogEntry(message, type));
|
||||||
|
|
||||||
|
// respect max entries
|
||||||
|
if (log.Count > maxLogCount)
|
||||||
|
log.Dequeue();
|
||||||
|
|
||||||
|
// become visible if it was important
|
||||||
|
// (no need to become visible for regular log. let the user decide.)
|
||||||
|
if (isImportant)
|
||||||
|
visible = true;
|
||||||
|
|
||||||
|
// auto scroll
|
||||||
|
scroll.y = float.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (Input.GetKeyDown(hotKey))
|
||||||
|
visible = !visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnGUI()
|
||||||
|
{
|
||||||
|
if (!visible) return;
|
||||||
|
|
||||||
|
scroll = GUILayout.BeginScrollView(scroll, "Box", GUILayout.Width(Screen.width), GUILayout.Height(height));
|
||||||
|
foreach (LogEntry entry in log)
|
||||||
|
{
|
||||||
|
if (entry.type == LogType.Error || entry.type == LogType.Exception)
|
||||||
|
GUI.color = Color.red;
|
||||||
|
else if (entry.type == LogType.Warning)
|
||||||
|
GUI.color = Color.yellow;
|
||||||
|
|
||||||
|
GUILayout.Label(entry.message);
|
||||||
|
GUI.color = Color.white;
|
||||||
|
}
|
||||||
|
GUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Mirror/Components/GUIConsole.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9021b6cc314944290986ab6feb48db79
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
8
Assets/Mirror/Components/InterestManagement.meta
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c66f27e006ab94253b39a55a3b213651
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fa4cbc6b9c584db4971985cb9f369077
|
||||||
|
timeCreated: 1613110605
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
// straight forward Vector3.Distance based interest management.
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Interest Management/ Distance/Distance Interest Management")]
|
||||||
|
public class DistanceInterestManagement : InterestManagement
|
||||||
|
{
|
||||||
|
[Tooltip("The maximum range that objects will be visible at. Add DistanceInterestManagementCustomRange onto NetworkIdentities for custom ranges.")]
|
||||||
|
public int visRange = 10;
|
||||||
|
|
||||||
|
[Tooltip("Rebuild all every 'rebuildInterval' seconds.")]
|
||||||
|
public float rebuildInterval = 1;
|
||||||
|
double lastRebuildTime;
|
||||||
|
|
||||||
|
// helper function to get vis range for a given object, or default.
|
||||||
|
int GetVisRange(NetworkIdentity identity)
|
||||||
|
{
|
||||||
|
return identity.TryGetComponent(out DistanceInterestManagementCustomRange custom) ? custom.visRange : visRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ServerCallback]
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
lastRebuildTime = 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver)
|
||||||
|
{
|
||||||
|
int range = GetVisRange(identity);
|
||||||
|
return Vector3.Distance(identity.transform.position, newObserver.identity.transform.position) < range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnectionToClient> newObservers)
|
||||||
|
{
|
||||||
|
// cache range and .transform because both call GetComponent.
|
||||||
|
int range = GetVisRange(identity);
|
||||||
|
Vector3 position = identity.transform.position;
|
||||||
|
|
||||||
|
// brute force distance check
|
||||||
|
// -> only player connections can be observers, so it's enough if we
|
||||||
|
// go through all connections instead of all spawned identities.
|
||||||
|
// -> compared to UNET's sphere cast checking, this one is orders of
|
||||||
|
// magnitude faster. if we have 10k monsters and run a sphere
|
||||||
|
// cast 10k times, we will see a noticeable lag even with physics
|
||||||
|
// layers. but checking to every connection is fast.
|
||||||
|
foreach (NetworkConnectionToClient conn in NetworkServer.connections.Values)
|
||||||
|
{
|
||||||
|
// authenticated and joined world with a player?
|
||||||
|
if (conn != null && conn.isAuthenticated && conn.identity != null)
|
||||||
|
{
|
||||||
|
// check distance
|
||||||
|
if (Vector3.Distance(conn.identity.transform.position, position) < range)
|
||||||
|
{
|
||||||
|
newObservers.Add(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal so we can update from tests
|
||||||
|
[ServerCallback]
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
// rebuild all spawned NetworkIdentity's observers every interval
|
||||||
|
if (NetworkTime.localTime >= lastRebuildTime + rebuildInterval)
|
||||||
|
{
|
||||||
|
RebuildAll();
|
||||||
|
lastRebuildTime = NetworkTime.localTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8f60becab051427fbdd3c8ac9ab4712b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// add this to NetworkIdentities for custom range if needed.
|
||||||
|
// only works with DistanceInterestManagement.
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[AddComponentMenu("Network/ Interest Management/ Distance/Distance Custom Range")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/guides/interest-management")]
|
||||||
|
public class DistanceInterestManagementCustomRange : NetworkBehaviour
|
||||||
|
{
|
||||||
|
[Tooltip("The maximum range that objects will be visible at.")]
|
||||||
|
public int visRange = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b2e242ee38a14076a39934172a19079b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
3
Assets/Mirror/Components/InterestManagement/Match.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5eca5245ae6bb460e9a92f7e14d5493a
|
||||||
|
timeCreated: 1622649517
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Interest Management/ Match/Match Interest Management")]
|
||||||
|
public class MatchInterestManagement : InterestManagement
|
||||||
|
{
|
||||||
|
readonly Dictionary<Guid, HashSet<NetworkIdentity>> matchObjects =
|
||||||
|
new Dictionary<Guid, HashSet<NetworkIdentity>>();
|
||||||
|
|
||||||
|
readonly Dictionary<NetworkIdentity, Guid> lastObjectMatch =
|
||||||
|
new Dictionary<NetworkIdentity, Guid>();
|
||||||
|
|
||||||
|
readonly HashSet<Guid> dirtyMatches = new HashSet<Guid>();
|
||||||
|
|
||||||
|
public override void OnSpawned(NetworkIdentity identity)
|
||||||
|
{
|
||||||
|
if (!identity.TryGetComponent<NetworkMatch>(out NetworkMatch networkMatch))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Guid currentMatch = networkMatch.matchId;
|
||||||
|
lastObjectMatch[identity] = currentMatch;
|
||||||
|
|
||||||
|
// Guid.Empty is never a valid matchId...do not add to matchObjects collection
|
||||||
|
if (currentMatch == Guid.Empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Debug.Log($"MatchInterestManagement.OnSpawned({identity.name}) currentMatch: {currentMatch}");
|
||||||
|
if (!matchObjects.TryGetValue(currentMatch, out HashSet<NetworkIdentity> objects))
|
||||||
|
{
|
||||||
|
objects = new HashSet<NetworkIdentity>();
|
||||||
|
matchObjects.Add(currentMatch, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
objects.Add(identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDestroyed(NetworkIdentity identity)
|
||||||
|
{
|
||||||
|
lastObjectMatch.TryGetValue(identity, out Guid currentMatch);
|
||||||
|
lastObjectMatch.Remove(identity);
|
||||||
|
if (currentMatch != Guid.Empty && matchObjects.TryGetValue(currentMatch, out HashSet<NetworkIdentity> objects) && objects.Remove(identity))
|
||||||
|
RebuildMatchObservers(currentMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal so we can update from tests
|
||||||
|
[ServerCallback]
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
// for each spawned:
|
||||||
|
// if match changed:
|
||||||
|
// add previous to dirty
|
||||||
|
// add new to dirty
|
||||||
|
foreach (NetworkIdentity netIdentity in NetworkServer.spawned.Values)
|
||||||
|
{
|
||||||
|
// Ignore objects that don't have a NetworkMatch component
|
||||||
|
if (!netIdentity.TryGetComponent<NetworkMatch>(out NetworkMatch networkMatch))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Guid newMatch = networkMatch.matchId;
|
||||||
|
lastObjectMatch.TryGetValue(netIdentity, out Guid currentMatch);
|
||||||
|
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
// Nothing to do if matchId hasn't changed
|
||||||
|
if (newMatch == Guid.Empty || newMatch == currentMatch)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Mark new/old matches as dirty so they get rebuilt
|
||||||
|
UpdateDirtyMatches(newMatch, currentMatch);
|
||||||
|
|
||||||
|
// This object is in a new match so observers in the prior match
|
||||||
|
// and the new match need to rebuild their respective observers lists.
|
||||||
|
UpdateMatchObjects(netIdentity, newMatch, currentMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebuild all dirty matches
|
||||||
|
foreach (Guid dirtyMatch in dirtyMatches)
|
||||||
|
RebuildMatchObservers(dirtyMatch);
|
||||||
|
|
||||||
|
dirtyMatches.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDirtyMatches(Guid newMatch, Guid currentMatch)
|
||||||
|
{
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
if (currentMatch != Guid.Empty)
|
||||||
|
dirtyMatches.Add(currentMatch);
|
||||||
|
|
||||||
|
dirtyMatches.Add(newMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateMatchObjects(NetworkIdentity netIdentity, Guid newMatch, Guid currentMatch)
|
||||||
|
{
|
||||||
|
// Remove this object from the hashset of the match it just left
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
if (currentMatch != Guid.Empty)
|
||||||
|
matchObjects[currentMatch].Remove(netIdentity);
|
||||||
|
|
||||||
|
// Set this to the new match this object just entered
|
||||||
|
lastObjectMatch[netIdentity] = newMatch;
|
||||||
|
|
||||||
|
// Make sure this new match is in the dictionary
|
||||||
|
if (!matchObjects.ContainsKey(newMatch))
|
||||||
|
matchObjects.Add(newMatch, new HashSet<NetworkIdentity>());
|
||||||
|
|
||||||
|
// Add this object to the hashset of the new match
|
||||||
|
matchObjects[newMatch].Add(netIdentity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RebuildMatchObservers(Guid matchId)
|
||||||
|
{
|
||||||
|
foreach (NetworkIdentity netIdentity in matchObjects[matchId])
|
||||||
|
if (netIdentity != null)
|
||||||
|
NetworkServer.RebuildObservers(netIdentity, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver)
|
||||||
|
{
|
||||||
|
// Never observed if no NetworkMatch component
|
||||||
|
if (!identity.TryGetComponent<NetworkMatch>(out NetworkMatch identityNetworkMatch))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
if (identityNetworkMatch.matchId == Guid.Empty)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Never observed if no NetworkMatch component
|
||||||
|
if (!newObserver.identity.TryGetComponent<NetworkMatch>(out NetworkMatch newObserverNetworkMatch))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
if (newObserverNetworkMatch.matchId == Guid.Empty)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return identityNetworkMatch.matchId == newObserverNetworkMatch.matchId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnectionToClient> newObservers)
|
||||||
|
{
|
||||||
|
if (!identity.TryGetComponent<NetworkMatch>(out NetworkMatch networkMatch))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Guid matchId = networkMatch.matchId;
|
||||||
|
|
||||||
|
// Guid.Empty is never a valid matchId
|
||||||
|
if (matchId == Guid.Empty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!matchObjects.TryGetValue(matchId, out HashSet<NetworkIdentity> objects))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add everything in the hashset for this object's current match
|
||||||
|
foreach (NetworkIdentity networkIdentity in objects)
|
||||||
|
if (networkIdentity != null && networkIdentity.connectionToClient != null)
|
||||||
|
newObservers.Add(networkIdentity.connectionToClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d09f5c8bf2f4747b7a9284ef5d9ce2a7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// simple component that holds match information
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[AddComponentMenu("Network/ Interest Management/ Match/Network Match")]
|
||||||
|
[HelpURL("https://mirror-networking.gitbook.io/docs/guides/interest-management")]
|
||||||
|
public class NetworkMatch : NetworkBehaviour
|
||||||
|
{
|
||||||
|
///<summary>Set this to the same value on all networked objects that belong to a given match</summary>
|
||||||
|
public Guid matchId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5d17e718851449a6879986e45c458fb7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
3
Assets/Mirror/Components/InterestManagement/Scene.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7655d309a46a4bd4860edf964228b3f6
|
||||||
|
timeCreated: 1622649517
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
[AddComponentMenu("Network/ Interest Management/ Scene/Scene Interest Management")]
|
||||||
|
public class SceneInterestManagement : InterestManagement
|
||||||
|
{
|
||||||
|
// Use Scene instead of string scene.name because when additively
|
||||||
|
// loading multiples of a subscene the name won't be unique
|
||||||
|
readonly Dictionary<Scene, HashSet<NetworkIdentity>> sceneObjects =
|
||||||
|
new Dictionary<Scene, HashSet<NetworkIdentity>>();
|
||||||
|
|
||||||
|
readonly Dictionary<NetworkIdentity, Scene> lastObjectScene =
|
||||||
|
new Dictionary<NetworkIdentity, Scene>();
|
||||||
|
|
||||||
|
HashSet<Scene> dirtyScenes = new HashSet<Scene>();
|
||||||
|
|
||||||
|
public override void OnSpawned(NetworkIdentity identity)
|
||||||
|
{
|
||||||
|
Scene currentScene = identity.gameObject.scene;
|
||||||
|
lastObjectScene[identity] = currentScene;
|
||||||
|
// Debug.Log($"SceneInterestManagement.OnSpawned({identity.name}) currentScene: {currentScene}");
|
||||||
|
if (!sceneObjects.TryGetValue(currentScene, out HashSet<NetworkIdentity> objects))
|
||||||
|
{
|
||||||
|
objects = new HashSet<NetworkIdentity>();
|
||||||
|
sceneObjects.Add(currentScene, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
objects.Add(identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDestroyed(NetworkIdentity identity)
|
||||||
|
{
|
||||||
|
Scene currentScene = lastObjectScene[identity];
|
||||||
|
lastObjectScene.Remove(identity);
|
||||||
|
if (sceneObjects.TryGetValue(currentScene, out HashSet<NetworkIdentity> objects) && objects.Remove(identity))
|
||||||
|
RebuildSceneObservers(currentScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal so we can update from tests
|
||||||
|
[ServerCallback]
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
// for each spawned:
|
||||||
|
// if scene changed:
|
||||||
|
// add previous to dirty
|
||||||
|
// add new to dirty
|
||||||
|
foreach (NetworkIdentity identity in NetworkServer.spawned.Values)
|
||||||
|
{
|
||||||
|
Scene currentScene = lastObjectScene[identity];
|
||||||
|
Scene newScene = identity.gameObject.scene;
|
||||||
|
if (newScene == currentScene)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Mark new/old scenes as dirty so they get rebuilt
|
||||||
|
dirtyScenes.Add(currentScene);
|
||||||
|
dirtyScenes.Add(newScene);
|
||||||
|
|
||||||
|
// This object is in a new scene so observers in the prior scene
|
||||||
|
// and the new scene need to rebuild their respective observers lists.
|
||||||
|
|
||||||
|
// Remove this object from the hashset of the scene it just left
|
||||||
|
sceneObjects[currentScene].Remove(identity);
|
||||||
|
|
||||||
|
// Set this to the new scene this object just entered
|
||||||
|
lastObjectScene[identity] = newScene;
|
||||||
|
|
||||||
|
// Make sure this new scene is in the dictionary
|
||||||
|
if (!sceneObjects.ContainsKey(newScene))
|
||||||
|
sceneObjects.Add(newScene, new HashSet<NetworkIdentity>());
|
||||||
|
|
||||||
|
// Add this object to the hashset of the new scene
|
||||||
|
sceneObjects[newScene].Add(identity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebuild all dirty scenes
|
||||||
|
foreach (Scene dirtyScene in dirtyScenes)
|
||||||
|
RebuildSceneObservers(dirtyScene);
|
||||||
|
|
||||||
|
dirtyScenes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RebuildSceneObservers(Scene scene)
|
||||||
|
{
|
||||||
|
foreach (NetworkIdentity netIdentity in sceneObjects[scene])
|
||||||
|
if (netIdentity != null)
|
||||||
|
NetworkServer.RebuildObservers(netIdentity, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver)
|
||||||
|
{
|
||||||
|
return identity.gameObject.scene == newObserver.identity.gameObject.scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRebuildObservers(NetworkIdentity identity, HashSet<NetworkConnectionToClient> newObservers)
|
||||||
|
{
|
||||||
|
if (!sceneObjects.TryGetValue(identity.gameObject.scene, out HashSet<NetworkIdentity> objects))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add everything in the hashset for this object's current scene
|
||||||
|
foreach (NetworkIdentity networkIdentity in objects)
|
||||||
|
if (networkIdentity != null && networkIdentity.connectionToClient != null)
|
||||||
|
newObservers.Add(networkIdentity.connectionToClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b979f26c95d34324ba005bfacfa9c4fc
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cfa12b73503344d49b398b01bcb07967
|
||||||
|
timeCreated: 1613110634
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
// Grid2D from uMMORPG: get/set values of type T at any point
|
||||||
|
// -> not named 'Grid' because Unity already has a Grid type. causes warnings.
|
||||||
|
// -> struct to avoid memory indirection. it's accessed a lot.
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Mirror
|
||||||
|
{
|
||||||
|
// struct to avoid memory indirection. it's accessed a lot.
|
||||||
|
public struct Grid2D<T>
|
||||||
|
{
|
||||||
|
// the grid
|
||||||
|
// note that we never remove old keys.
|
||||||
|
// => over time, HashSet<T>s will be allocated for every possible
|
||||||
|
// grid position in the world
|
||||||
|
// => Clear() doesn't clear them so we don't constantly reallocate the
|
||||||
|
// entries when populating the grid in every Update() call
|
||||||
|
// => makes the code a lot easier too
|
||||||
|
// => this is FINE because in the worst case, every grid position in the
|
||||||
|
// game world is filled with a player anyway!
|
||||||
|
readonly Dictionary<Vector2Int, HashSet<T>> grid;
|
||||||
|
|
||||||
|
// cache a 9 neighbor grid of vector2 offsets so we can use them more easily
|
||||||
|
readonly Vector2Int[] neighbourOffsets;
|
||||||
|
|
||||||
|
public Grid2D(int initialCapacity)
|
||||||
|
{
|
||||||
|
grid = new Dictionary<Vector2Int, HashSet<T>>(initialCapacity);
|
||||||
|
|
||||||
|
neighbourOffsets = new[] {
|
||||||
|
Vector2Int.up,
|
||||||
|
Vector2Int.up + Vector2Int.left,
|
||||||
|
Vector2Int.up + Vector2Int.right,
|
||||||
|
Vector2Int.left,
|
||||||
|
Vector2Int.zero,
|
||||||
|
Vector2Int.right,
|
||||||
|
Vector2Int.down,
|
||||||
|
Vector2Int.down + Vector2Int.left,
|
||||||
|
Vector2Int.down + Vector2Int.right
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function so we can add an entry without worrying
|
||||||
|
public void Add(Vector2Int position, T value)
|
||||||
|
{
|
||||||
|
// initialize set in grid if it's not in there yet
|
||||||
|
if (!grid.TryGetValue(position, out HashSet<T> hashSet))
|
||||||
|
{
|
||||||
|
// each grid entry may hold hundreds of entities.
|
||||||
|
// let's create the HashSet with a large initial capacity
|
||||||
|
// in order to avoid resizing & allocations.
|
||||||
|
#if !UNITY_2021_3_OR_NEWER
|
||||||
|
// Unity 2019 doesn't have "new HashSet(capacity)" yet
|
||||||
|
hashSet = new HashSet<T>();
|
||||||
|
#else
|
||||||
|
hashSet = new HashSet<T>(128);
|
||||||
|
#endif
|
||||||
|
grid[position] = hashSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to it
|
||||||
|
hashSet.Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to get set at position without worrying
|
||||||
|
// -> result is passed as parameter to avoid allocations
|
||||||
|
// -> result is not cleared before. this allows us to pass the HashSet from
|
||||||
|
// GetWithNeighbours and avoid .UnionWith which is very expensive.
|
||||||
|
void GetAt(Vector2Int position, HashSet<T> result)
|
||||||
|
{
|
||||||
|
// return the set at position
|
||||||
|
if (grid.TryGetValue(position, out HashSet<T> hashSet))
|
||||||
|
{
|
||||||
|
foreach (T entry in hashSet)
|
||||||
|
result.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to get at position and it's 8 neighbors without worrying
|
||||||
|
// -> result is passed as parameter to avoid allocations
|
||||||
|
public void GetWithNeighbours(Vector2Int position, HashSet<T> result)
|
||||||
|
{
|
||||||
|
// clear result first
|
||||||
|
result.Clear();
|
||||||
|
|
||||||
|
// add neighbours
|
||||||
|
foreach (Vector2Int offset in neighbourOffsets)
|
||||||
|
GetAt(position + offset, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear: clears the whole grid
|
||||||
|
// IMPORTANT: we already allocated HashSet<T>s and don't want to do
|
||||||
|
// reallocate every single update when we rebuild the grid.
|
||||||
|
// => so simply remove each position's entries, but keep
|
||||||
|
// every position in there
|
||||||
|
// => see 'grid' comments above!
|
||||||
|
// => named ClearNonAlloc to make it more obvious!
|
||||||
|
public void ClearNonAlloc()
|
||||||
|
{
|
||||||
|
foreach (HashSet<T> hashSet in grid.Values)
|
||||||
|
hashSet.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7c5232a4d2854116a35d52b80ec07752
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||