This commit is contained in:
sewmina7@gmail.com 2023-11-28 11:41:03 +05:30
commit da3b6cf083
1281 changed files with 97466 additions and 0 deletions

72
.gitignore vendored Normal file
View 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
View 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
View 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
View File

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

8
Assets/Ignorance.meta Normal file
View File

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

View File

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

View File

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

View 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

View File

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

View File

@ -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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f34de581ee6ab3743844c33f257a03c2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:

View File

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

View 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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: da367a4c269be6d4a855ee1a9a68256b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

View 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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a85b24263182aae4bbc1829bb2b73d7a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 315510c0721e82f4cad07c2669b863fa
timeCreated: 1426602119
licenseType: Store
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View 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;
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2a08d5ab1f59230458264367f00c54d8
timeCreated: 1426602353
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b68eb08343b29a54dbd5ed7830fb9211
timeCreated: 1426597826
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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));
}
}

View File

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

View 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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View 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:

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -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:

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

View 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
View File

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

View File

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

View 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
}
}

View 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:

View 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
}
}

View 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:

View File

@ -0,0 +1,14 @@
{
"name": "Mirror.Authenticators",
"references": [
"Mirror"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

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

View 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();
}
}
}
}

View 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:

View File

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

View File

@ -0,0 +1,14 @@
{
"name": "Mirror.CompilerSymbols",
"references": [],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 325984b52e4128546bc7558552f8b1d2
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}
}

View 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:

View File

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

View 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")]

View 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:

View File

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

View 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
}
}

View 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:

View 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
}
}

View File

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

View 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;
}
}
}

View File

@ -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:

View File

@ -0,0 +1,4 @@
namespace Mirror.Discovery
{
public struct ServerRequest : NetworkMessage {}
}

View File

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

View 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;
}
}

View File

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

View File

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

View File

@ -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?
}
}
}

View File

@ -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:

View 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;
}
}
}

View File

@ -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:

View 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;
}
}
}

View File

@ -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:

View 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();
}
}
}

View 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:

View File

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

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fa4cbc6b9c584db4971985cb9f369077
timeCreated: 1613110605

View File

@ -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;
}
}
}
}

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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:

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5eca5245ae6bb460e9a92f7e14d5493a
timeCreated: 1622649517

View File

@ -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);
}
}
}

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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:

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7655d309a46a4bd4860edf964228b3f6
timeCreated: 1622649517

View File

@ -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);
}
}
}

View File

@ -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:

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cfa12b73503344d49b398b01bcb07967
timeCreated: 1613110634

View File

@ -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();
}
}
}

View File

@ -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:

Some files were not shown because too many files have changed in this diff Show More