some effort on the editor
This commit is contained in:
parent
1a4b2443ff
commit
e9d7d39f2b
18
Assets/# Prototype/Prefab Table.asset
Normal file
18
Assets/# Prototype/Prefab Table.asset
Normal file
@ -0,0 +1,18 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f70bf8524ee54f76ba35bd5c28995d83, type: 3}
|
||||
m_Name: Prefab Table
|
||||
m_EditorClassIdentifier: Assembly-CSharp-Editor::Editor.GardensStageEditor.PrefabTable
|
||||
groundSlabPrefab: {fileID: 4088177062756800262, guid: 761db1bde191e401fa6ec87acd053bbf, type: 3}
|
||||
groundRampFrontPrefab: {fileID: 116909126457648545, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
groundRampLeftPrefab: {fileID: 1762350532007512996, guid: 378324f09bdf84db99e602efb4b23fa3, type: 3}
|
||||
groundRampRightPrefab: {fileID: 778490509801794073, guid: d5e0f7c6e96fe4425a061863751bc639, type: 3}
|
||||
8
Assets/# Prototype/Prefab Table.asset.meta
Normal file
8
Assets/# Prototype/Prefab Table.asset.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef963f234702846efa75432cf0bb519f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
4196
Assets/# Prototype/Stages/stage-test.stage-definition.asset
Normal file
4196
Assets/# Prototype/Stages/stage-test.stage-definition.asset
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb896366809bc439b8be4d0f1158dc6f
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -90,7 +90,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Ground_Ramp_Prototype
|
||||
value: Ground_Ramp_Front_Prototype
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
63
Assets/Prefabs/Prototypes/Ground_Ramp_Left_Prototype.prefab
Normal file
63
Assets/Prefabs/Prototypes/Ground_Ramp_Left_Prototype.prefab
Normal file
@ -0,0 +1,63 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &1867437227332939269
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 2829319849928503959, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_Mesh
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: -90
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 9140983697215042600, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Ground_Ramp_Left_Prototype
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 378324f09bdf84db99e602efb4b23fa3
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
63
Assets/Prefabs/Prototypes/Ground_Ramp_Right_Prototype.prefab
Normal file
63
Assets/Prefabs/Prototypes/Ground_Ramp_Right_Prototype.prefab
Normal file
@ -0,0 +1,63 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &815882455729688504
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 2829319849928503959, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_Mesh
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0.7071068
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 90
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4113289733881740216, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 9140983697215042600, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Ground_Ramp_Right_Prototype
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 321f39f98806c4db7a3deff6d508bde1, type: 3}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5e0f7c6e96fe4425a061863751bc639
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
140
Assets/Prefabs/Prototypes/Ground_Stair_Front_Prototype.prefab
Normal file
140
Assets/Prefabs/Prototypes/Ground_Stair_Front_Prototype.prefab
Normal file
@ -0,0 +1,140 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &3530962555909840662
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
serializedVersion: 3
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications:
|
||||
- target: {fileID: 221717111884494654, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Mesh
|
||||
value:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 2109134711161568785, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352223124200162652, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352223124200162652, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3352223124200162652, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4990331727855981778, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 0.9238795
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4990331727855981778, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0.38268346
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4990331727855981778, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4990331727855981778, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6392326082573612157, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Size.y
|
||||
value: 0.05
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6392326082573612157, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Size.z
|
||||
value: 1.4142
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6392326082573612157, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Center.y
|
||||
value: -0.025
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Ground_Stair_Front_Prototype
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 2575929596551944822}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
--- !u!114 &3525235759526726985 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 138583005792719455, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
m_PrefabInstance: {fileID: 3530962555909840662}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f20bd3bb11c64d00a0429af5fe4bd33f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.PrototypeModel
|
||||
--- !u!1 &7749360569717010071 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||
m_PrefabInstance: {fileID: 3530962555909840662}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &2575929596551944822
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7749360569717010071}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 3a3b1270c87c4456bdc61721ca19132f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.GroundStairModelPrototype
|
||||
displayDebug: 1
|
||||
prototypeModel: {fileID: 3525235759526726985}
|
||||
sizeX: 1
|
||||
sizeZ: 1
|
||||
x: 1
|
||||
z: 1
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da66eef8ff1ce4c3eaf46c09ad26e70b
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -10,23 +10,31 @@ PrefabInstance:
|
||||
m_Modifications:
|
||||
- target: {fileID: 369205274101430871, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0.5
|
||||
value: 1.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Size.x
|
||||
value: 2
|
||||
value: 3
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Size.y
|
||||
value: 1
|
||||
value: 3
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Size.z
|
||||
value: 2
|
||||
value: 3.5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Center.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Center.z
|
||||
value: 0.25
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5094209182163755379, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Enabled
|
||||
value: 0
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6166895172714925370, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Mesh
|
||||
@ -74,7 +82,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 8449749668273782584, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Obstacle_Cube_Prototype
|
||||
value: Obstacle_Wall_Prototype
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
@ -101,16 +109,18 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: ccf30362a82f4d67958b61569d4cf1b4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.ContactCubeModelPrototype
|
||||
displayDebug: 0
|
||||
displayDebug: 1
|
||||
prototypeModel: {fileID: 8402728050198132523}
|
||||
sizeX: 1
|
||||
sizeY: 1
|
||||
sizeY: 3
|
||||
sizeZ: 1
|
||||
offset: 1
|
||||
offset_x: {x: 1, y: 1}
|
||||
offset_y: {x: 1.5, y: 1}
|
||||
x: 1
|
||||
y: 1
|
||||
y: 3
|
||||
z: 1
|
||||
contact_offset: 1
|
||||
contact_offset_x: {x: 1, y: 1}
|
||||
contact_offset_y: {x: 1.5, y: 1}
|
||||
--- !u!114 &8402728050198132523 stripped
|
||||
MonoBehaviour:
|
||||
m_CorrespondingSourceObject: {fileID: 3563105585321411375, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||
File diff suppressed because one or more lines are too long
3
Assets/Scripts/Editor/GardensStageEditor/Baker.meta
Normal file
3
Assets/Scripts/Editor/GardensStageEditor/Baker.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6846a45a2ff48599d8e2a83e5a5d0e3
|
||||
timeCreated: 1781601092
|
||||
75
Assets/Scripts/Editor/GardensStageEditor/Baker/StageBaker.cs
Normal file
75
Assets/Scripts/Editor/GardensStageEditor/Baker/StageBaker.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using Intrepid.Diagnostics;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Editor.GardensStageEditor.Baker
|
||||
{
|
||||
namespace Editor.GardensStageEditor
|
||||
{
|
||||
public static class StageBaker
|
||||
{
|
||||
private const string GeneratedRootName = "Generated";
|
||||
|
||||
public static GameObject Bake(StageDefinition stage, PrefabTable prefabTable)
|
||||
{
|
||||
if (stage.IsNull())
|
||||
{
|
||||
DLogger.LogWarn("Cannot bake: no StageDefinition selected.");
|
||||
return null;
|
||||
}
|
||||
|
||||
stage.EnsureDefaults();
|
||||
|
||||
var scene = SceneManager.GetActiveScene();
|
||||
var generatedRoot = EnsureGeneratedRoot(scene);
|
||||
Undo.RegisterCreatedObjectUndo(generatedRoot, "Create Generated Root");
|
||||
var stageRoot = EnsureStageRoot(stage, generatedRoot);
|
||||
StageBuilder.BuildStage(new StageBuilderRequest
|
||||
{
|
||||
Stage = stage,
|
||||
Root = stageRoot,
|
||||
PrefabTable = prefabTable
|
||||
});
|
||||
Undo.RegisterCreatedObjectUndo(stageRoot, "Create Stage Root");
|
||||
|
||||
EditorSceneManager.MarkSceneDirty(scene);
|
||||
Selection.activeGameObject = stageRoot;
|
||||
DLogger.LogDebug($"Bake started for stage '{stage.Id}'. State root is ready.");
|
||||
|
||||
return stageRoot;
|
||||
}
|
||||
|
||||
private static GameObject EnsureStageRoot(StageDefinition stage, GameObject generatedRoot)
|
||||
{
|
||||
foreach (Transform goTransform in generatedRoot.transform)
|
||||
{
|
||||
if (goTransform.gameObject.name == stage.Id)
|
||||
{
|
||||
goTransform.gameObject.name = $"{goTransform.gameObject.name}_bkp";
|
||||
goTransform.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
var go = new GameObject(stage.Id);
|
||||
go.transform.SetParent(generatedRoot.transform);
|
||||
return go;
|
||||
}
|
||||
|
||||
private static GameObject EnsureGeneratedRoot(Scene scene)
|
||||
{
|
||||
foreach (var gameObject in scene.GetRootGameObjects())
|
||||
{
|
||||
if (gameObject.name == GeneratedRootName)
|
||||
{
|
||||
return gameObject;
|
||||
}
|
||||
}
|
||||
|
||||
return new GameObject(GeneratedRootName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e84387a0ce04c489edeca68df66e1c4
|
||||
timeCreated: 1781549085
|
||||
135
Assets/Scripts/Editor/GardensStageEditor/Baker/StageBuilder.cs
Normal file
135
Assets/Scripts/Editor/GardensStageEditor/Baker/StageBuilder.cs
Normal file
@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Intrepid.Diagnostics;
|
||||
using Intrepid.Gameplay.Prototyping;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Editor.GardensStageEditor.Baker
|
||||
{
|
||||
public struct StageBuilderRequest
|
||||
{
|
||||
public StageDefinition Stage { get; set; }
|
||||
public GameObject Root { get; set; }
|
||||
public PrefabTable PrefabTable { get; set; }
|
||||
}
|
||||
|
||||
public static class StageBuilder
|
||||
{
|
||||
public static void BuildStage(StageBuilderRequest request)
|
||||
{
|
||||
foreach (var stageFloorDefinition in request.Stage.floors)
|
||||
{
|
||||
var cellsGS = new HashSet<Vector2Int>();
|
||||
var cellsGRF = new HashSet<Vector2Int>();
|
||||
var cellsGRR = new HashSet<Vector2Int>();
|
||||
var cellsGRL = new HashSet<Vector2Int>();
|
||||
|
||||
foreach (var logicalCell in stageFloorDefinition.Cells)
|
||||
{
|
||||
switch (logicalCell.structural)
|
||||
{
|
||||
case StructuralCellKind.Empty:
|
||||
break;
|
||||
case StructuralCellKind.Ground_Slab:
|
||||
cellsGS.Add(new Vector2Int(logicalCell.x, logicalCell.y));
|
||||
break;
|
||||
case StructuralCellKind.Ground_Ramp_Front:
|
||||
cellsGRF.Add(new Vector2Int(logicalCell.x, logicalCell.y));
|
||||
break;
|
||||
case StructuralCellKind.Ground_Ramp_Left:
|
||||
cellsGRL.Add(new Vector2Int(logicalCell.x, logicalCell.y));
|
||||
break;
|
||||
case StructuralCellKind.Ground_Ramp_Right:
|
||||
cellsGRR.Add(new Vector2Int(logicalCell.x, logicalCell.y));
|
||||
break;
|
||||
case StructuralCellKind.Wall:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
var floorRootTransform = new GameObject(stageFloorDefinition.floorId)
|
||||
{
|
||||
transform =
|
||||
{
|
||||
parent = request.Root.transform,
|
||||
position = new Vector3(0, stageFloorDefinition.FloorHeight, 0)
|
||||
}
|
||||
}.transform;
|
||||
|
||||
InstantiateGround(
|
||||
request.PrefabTable.GroundSlabPrefab,
|
||||
floorRootTransform,
|
||||
cellsGS,
|
||||
StraightAddressSize
|
||||
);
|
||||
InstantiateGround(
|
||||
request.PrefabTable.GroundRampFrontPrefab,
|
||||
floorRootTransform,
|
||||
cellsGRF,
|
||||
StraightAddressSize
|
||||
);
|
||||
InstantiateGround(
|
||||
request.PrefabTable.GroundRampLeftPrefab,
|
||||
floorRootTransform,
|
||||
cellsGRL,
|
||||
InverseAddressSize
|
||||
);
|
||||
InstantiateGround(
|
||||
request.PrefabTable.GroundRampRightPrefab,
|
||||
floorRootTransform,
|
||||
cellsGRR,
|
||||
InverseAddressSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2Int StraightAddressSize(RectInt rect)
|
||||
{
|
||||
return new Vector2Int(rect.width, rect.height);
|
||||
}
|
||||
|
||||
private static Vector2Int InverseAddressSize(RectInt rect)
|
||||
{
|
||||
return new Vector2Int(rect.height, rect.width);
|
||||
}
|
||||
|
||||
|
||||
private static void InstantiateGround<G>(
|
||||
G prefab, Transform parent,
|
||||
HashSet<Vector2Int> set,
|
||||
Func<RectInt, Vector2Int> addressSize
|
||||
) where G: GroundModelPrototype
|
||||
{
|
||||
var releaseName = new string(typeof(G).Name.Where(char.IsUpper).ToArray());
|
||||
|
||||
if (prefab.IsNull())
|
||||
{
|
||||
DLogger.LogError($"Prefab is not configured in PrefabTable: {releaseName}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var rect in StageBuilderHelpers.BuildRectanglesFromCellsBest(set))
|
||||
{
|
||||
if (PrefabUtility.InstantiatePrefab(prefab, parent) is not G g)
|
||||
{
|
||||
DLogger.LogError($"Failed to instantiate prefab: {prefab.name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
StageBuilderHelpers.ResetTransform(g.transform);
|
||||
g.name = $"{releaseName} ({rect.x}, {rect.y}) {rect.width}x{rect.height}";
|
||||
g.transform.localPosition = new Vector3(
|
||||
rect.x + (rect.width - 1) * 0.5f,
|
||||
0,
|
||||
-(rect.y + (rect.height - 1) * 0.5f)
|
||||
);
|
||||
g.SetSize(addressSize(rect));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 571d9dd73a024147b211247e52b60a2a
|
||||
timeCreated: 1781593722
|
||||
@ -0,0 +1,153 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Editor.GardensStageEditor.Baker
|
||||
{
|
||||
public static class StageBuilderHelpers
|
||||
{
|
||||
public static void ResetTransform(Transform transform)
|
||||
{
|
||||
// transform.rotation = Quaternion.identity;
|
||||
transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
public static List<RectInt> BuildRectanglesFromCellsBest(HashSet<Vector2Int> cells)
|
||||
{
|
||||
var result = new List<RectInt>();
|
||||
var remaining = new HashSet<Vector2Int>(cells);
|
||||
|
||||
while (remaining.Count > 0)
|
||||
{
|
||||
var rect = FindLargestRectGlobal(remaining);
|
||||
result.Add(rect);
|
||||
|
||||
RemoveRectCells(rect, remaining);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<RectInt> BuildRectanglesFromCells(HashSet<Vector2Int> cells)
|
||||
{
|
||||
var result = new List<RectInt>();
|
||||
var remaining = new HashSet<Vector2Int>(cells);
|
||||
|
||||
while (remaining.Count > 0)
|
||||
{
|
||||
var start = FindTopLeftMostCell(remaining);
|
||||
|
||||
var rect = FindBestRectFromStart(start, remaining);
|
||||
result.Add(rect);
|
||||
|
||||
RemoveRectCells(rect, remaining);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static RectInt FindLargestRectGlobal(HashSet<Vector2Int> remaining)
|
||||
{
|
||||
var best = new RectInt();
|
||||
var bestArea = 0;
|
||||
|
||||
foreach (var cell in remaining)
|
||||
{
|
||||
var rect = FindBestRectFromStart(cell, remaining);
|
||||
var area = rect.width * rect.height;
|
||||
|
||||
if (area > bestArea)
|
||||
{
|
||||
best = rect;
|
||||
bestArea = area;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
private static RectInt FindBestRectFromStart(Vector2Int start, HashSet<Vector2Int> remaining)
|
||||
{
|
||||
var bestWidth = 1;
|
||||
var bestHeight = 1;
|
||||
var bestArea = 1;
|
||||
|
||||
var currentMinWidth = int.MaxValue;
|
||||
var height = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var rowWidth = FindRowWidth(start.x, start.y + height, remaining);
|
||||
|
||||
if (rowWidth == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
currentMinWidth = Mathf.Min(currentMinWidth, rowWidth);
|
||||
height++;
|
||||
|
||||
var area = currentMinWidth * height;
|
||||
|
||||
if (area > bestArea)
|
||||
{
|
||||
bestArea = area;
|
||||
bestWidth = currentMinWidth;
|
||||
bestHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
return new RectInt(start.x, start.y, bestWidth, bestHeight);
|
||||
}
|
||||
|
||||
private static int FindRowWidth(int x, int y, HashSet<Vector2Int> remaining)
|
||||
{
|
||||
var width = 0;
|
||||
|
||||
while (remaining.Contains(new Vector2Int(x + width, y)))
|
||||
{
|
||||
width++;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
private static Vector2Int FindTopLeftMostCell(HashSet<Vector2Int> cells)
|
||||
{
|
||||
var found = false;
|
||||
var best = Vector2Int.zero;
|
||||
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
if (!found)
|
||||
{
|
||||
best = cell;
|
||||
found = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell.y < best.y)
|
||||
{
|
||||
best = cell;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cell.y == best.y && cell.x < best.x)
|
||||
{
|
||||
best = cell;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
private static void RemoveRectCells(RectInt rect, HashSet<Vector2Int> remaining)
|
||||
{
|
||||
for (var y = rect.yMin; y < rect.yMax; y++)
|
||||
{
|
||||
for (var x = rect.xMin; x < rect.xMax; x++)
|
||||
{
|
||||
remaining.Remove(new Vector2Int(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3cf864dedfb4a929e087eba87cfd7f5
|
||||
timeCreated: 1781598891
|
||||
20
Assets/Scripts/Editor/GardensStageEditor/PrefabTable.cs
Normal file
20
Assets/Scripts/Editor/GardensStageEditor/PrefabTable.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Intrepid.Gameplay.Prototyping;
|
||||
using Intrepid.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Editor.GardensStageEditor
|
||||
{
|
||||
[CreateAssetMenu(fileName = "New Prefab Table", menuName = "GON/Editor/Prefab Table")]
|
||||
public class PrefabTable : ScriptableObject
|
||||
{
|
||||
[GroupInjections, SerializeField] private GroundSlabModelPrototype groundSlabPrefab;
|
||||
[GroupInjections, SerializeField] private GroundRampModelPrototype groundRampFrontPrefab;
|
||||
[GroupInjections, SerializeField] private GroundRampModelPrototype groundRampLeftPrefab;
|
||||
[GroupInjections, SerializeField] private GroundRampModelPrototype groundRampRightPrefab;
|
||||
|
||||
public GroundSlabModelPrototype GroundSlabPrefab => groundSlabPrefab;
|
||||
public GroundRampModelPrototype GroundRampFrontPrefab => groundRampFrontPrefab;
|
||||
public GroundRampModelPrototype GroundRampLeftPrefab => groundRampLeftPrefab;
|
||||
public GroundRampModelPrototype GroundRampRightPrefab => groundRampRightPrefab;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f70bf8524ee54f76ba35bd5c28995d83
|
||||
timeCreated: 1781596138
|
||||
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Utilities;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Editor.GardensStageEditor
|
||||
@ -15,8 +17,12 @@ namespace Editor.GardensStageEditor
|
||||
public enum StructuralCellKind
|
||||
{
|
||||
Empty = 0,
|
||||
Ground = 1,
|
||||
Wall = 2
|
||||
Ground_Slab = 10,
|
||||
Ground_Ramp_Front = 11,
|
||||
Ground_Ramp_Left = 12,
|
||||
Ground_Ramp_Right = 13,
|
||||
|
||||
Wall = 20,
|
||||
}
|
||||
|
||||
public enum StageObjectKind
|
||||
@ -38,9 +44,8 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
|
||||
[CreateAssetMenu(menuName = "GON/Editor/Stage Definition", fileName = "StageDefinition")]
|
||||
public sealed class StageDefinition : ScriptableObject
|
||||
public sealed class StageDefinition : SOIdentification
|
||||
{
|
||||
public string stageId = "stage_new";
|
||||
public float cellSize = 1f;
|
||||
public float floorHeight = 6f;
|
||||
public int activeFloorIndex;
|
||||
@ -135,7 +140,8 @@ namespace Editor.GardensStageEditor
|
||||
public sealed class StageFloorDefinition
|
||||
{
|
||||
public string floorId = "F0";
|
||||
|
||||
public float FloorHeight;
|
||||
|
||||
[SerializeField]
|
||||
private List<LogicalCell> cells = new();
|
||||
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 778f9d79eb2c410482efdc25b248dd46
|
||||
@ -28,7 +28,10 @@ namespace Editor.GardensStageEditor
|
||||
{
|
||||
return kind switch
|
||||
{
|
||||
StructuralCellKind.Ground => FromHtml("55E0FF"),
|
||||
StructuralCellKind.Ground_Slab => FromHtml("55E0FF"),
|
||||
StructuralCellKind.Ground_Ramp_Front => FromHtml("55E0FF"),
|
||||
StructuralCellKind.Ground_Ramp_Left => FromHtml("55E0FF"),
|
||||
StructuralCellKind.Ground_Ramp_Right => FromHtml("55E0FF"),
|
||||
StructuralCellKind.Wall => FromHtml("668B93"),
|
||||
_ => new Color(0f, 0f, 0f, 0f)
|
||||
};
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Gameplay.Prototyping;
|
||||
using System.IO;
|
||||
using Editor.GardensStageEditor.Baker.Editor.GardensStageEditor;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine;
|
||||
@ -9,6 +11,7 @@ namespace Editor.GardensStageEditor
|
||||
{
|
||||
public sealed class StageEditorWindow : EditorWindow
|
||||
{
|
||||
private PrefabTable prefabTable;
|
||||
private StageDefinition stage;
|
||||
private StageEditorState state;
|
||||
private List<StagePaletteEntry> palette;
|
||||
@ -92,7 +95,7 @@ namespace Editor.GardensStageEditor
|
||||
RebuildTopBar();
|
||||
}
|
||||
|
||||
public void MutateStage(string undoName, System.Action mutation)
|
||||
public void MutateStage(string undoName, Action mutation)
|
||||
{
|
||||
if (stage is null || mutation is null)
|
||||
{
|
||||
@ -119,6 +122,21 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
|
||||
topBar.Clear();
|
||||
|
||||
var prefabTableField = new ObjectField("Prefab Table")
|
||||
{
|
||||
objectType = typeof(PrefabTable),
|
||||
value = prefabTable,
|
||||
style =
|
||||
{
|
||||
minWidth = 200
|
||||
}
|
||||
};
|
||||
prefabTableField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
SetPrefabTable(evt.newValue as PrefabTable);
|
||||
});
|
||||
topBar.Add(prefabTableField);
|
||||
|
||||
var stageField = new ObjectField("Stage")
|
||||
{
|
||||
@ -126,7 +144,7 @@ namespace Editor.GardensStageEditor
|
||||
value = stage,
|
||||
style =
|
||||
{
|
||||
minWidth = 300
|
||||
minWidth = 200
|
||||
}
|
||||
};
|
||||
stageField.RegisterValueChangedCallback(evt =>
|
||||
@ -192,7 +210,7 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
};
|
||||
topBar.Add(validate);
|
||||
|
||||
|
||||
var save = new Button(delegate
|
||||
{
|
||||
EditorUtility.SetDirty(stage);
|
||||
@ -207,16 +225,19 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
};
|
||||
topBar.Add(save);
|
||||
}
|
||||
|
||||
var spacer = new VisualElement
|
||||
{
|
||||
style =
|
||||
|
||||
var bake = new Button(BakeStage)
|
||||
{
|
||||
flexGrow = 1f
|
||||
}
|
||||
};
|
||||
topBar.Add(spacer);
|
||||
text = "Bake",
|
||||
style =
|
||||
{
|
||||
marginLeft = 4
|
||||
}
|
||||
};
|
||||
topBar.Add(bake);
|
||||
}
|
||||
|
||||
topBar.Add(AddSpacer());
|
||||
|
||||
mouseCellLabel = new Label("Mouse: —")
|
||||
{
|
||||
@ -238,6 +259,17 @@ namespace Editor.GardensStageEditor
|
||||
topBar.Add(hint);
|
||||
}
|
||||
|
||||
private static VisualElement AddSpacer()
|
||||
{
|
||||
return new VisualElement
|
||||
{
|
||||
style =
|
||||
{
|
||||
flexGrow = 1f
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void SetMouseCell(Vector2Int? cell)
|
||||
{
|
||||
@ -261,12 +293,19 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
RebuildTopBar();
|
||||
}
|
||||
|
||||
private void SetPrefabTable(PrefabTable newPrefabTable)
|
||||
{
|
||||
prefabTable = newPrefabTable;
|
||||
|
||||
RebuildTopBar();
|
||||
}
|
||||
|
||||
private void CreateNewStageAsset()
|
||||
{
|
||||
var path = EditorUtility.SaveFilePanelInProject(
|
||||
"Create Stage Definition",
|
||||
"StageDefinition",
|
||||
"new-stage.stage-definition",
|
||||
"asset",
|
||||
"Choose where to create the new StageDefinition asset."
|
||||
);
|
||||
@ -277,7 +316,7 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
|
||||
var asset = CreateInstance<StageDefinition>();
|
||||
asset.stageId = System.IO.Path.GetFileNameWithoutExtension(path).ToLowerInvariant();
|
||||
asset.Id = Path.GetFileNameWithoutExtension(path).ToLowerInvariant();
|
||||
asset.EnsureDefaults();
|
||||
|
||||
AssetDatabase.CreateAsset(asset, path);
|
||||
@ -300,7 +339,8 @@ namespace Editor.GardensStageEditor
|
||||
var index = stage.floors.Count;
|
||||
var floor = new StageFloorDefinition
|
||||
{
|
||||
floorId = "F" + index
|
||||
floorId = "F" + index,
|
||||
FloorHeight = stage.floors.Count == 0 ? 0.0f : stage.floors[^1].FloorHeight
|
||||
};
|
||||
|
||||
stage.floors.Add(floor);
|
||||
@ -315,5 +355,32 @@ namespace Editor.GardensStageEditor
|
||||
Debug.Log(report);
|
||||
EditorUtility.DisplayDialog("Stage Validation", report, "OK");
|
||||
}
|
||||
|
||||
private void BakeStage()
|
||||
{
|
||||
if (stage is null)
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Bake Stage",
|
||||
"Select or create a StageDefinition before baking.",
|
||||
"OK"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefabTable is null)
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Bake Stage",
|
||||
"Select a PrefabTable before baking.",
|
||||
"OK"
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
StageBaker.Bake(stage, prefabTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7065bab1fc14f53909281036dbb6368
|
||||
@ -77,14 +77,7 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
};
|
||||
Add(section);
|
||||
|
||||
var stageId = new TextField("Stage Id")
|
||||
{
|
||||
value = stage.stageId
|
||||
};
|
||||
stageId.RegisterValueChangedCallback(evt => owner.MutateStage("Change stage id", delegate { stage.stageId = evt.newValue; }));
|
||||
Add(stageId);
|
||||
|
||||
|
||||
var cellSize = new FloatField("Cell Size")
|
||||
{
|
||||
value = stage.cellSize
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1b3226b742b4e5e94cab859de25494a
|
||||
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
@ -45,6 +46,7 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
focusable = true;
|
||||
style.flexGrow = 1f;
|
||||
style.overflow = Overflow.Hidden;
|
||||
style.backgroundColor = StageEditorColors.Background;
|
||||
|
||||
generateVisualContent += OnGenerateVisualContent;
|
||||
@ -185,20 +187,31 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
evt.StopPropagation();
|
||||
return;
|
||||
case DragMode.None:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseUp(MouseUpEvent evt)
|
||||
{
|
||||
if (dragMode == DragMode.None)
|
||||
switch (dragMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dragMode == DragMode.Paint && evt.button == 0)
|
||||
{
|
||||
var rect = GetDragRect();
|
||||
ApplyPalette(rect);
|
||||
case DragMode.None:
|
||||
return;
|
||||
case DragMode.Paint when evt.button == 0:
|
||||
{
|
||||
var rect = GetDragRect();
|
||||
ApplyPalette(rect);
|
||||
break;
|
||||
}
|
||||
case DragMode.Pan:
|
||||
case DragMode.MoveObject:
|
||||
case DragMode.ResizeObject:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
EndDrag();
|
||||
@ -349,10 +362,8 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
if (entry.paintsStructural)
|
||||
{
|
||||
owner.MutateStage("Paint " + entry.displayName, delegate
|
||||
{
|
||||
floor.FillRect(rect, entry.structuralKind);
|
||||
});
|
||||
owner.MutateStage("Paint " + entry.displayName,
|
||||
delegate { floor.FillRect(rect, entry.structuralKind); });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -392,13 +403,15 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
if (!StageObjectDefinition.IsKindResizable(entry.objectKind))
|
||||
{
|
||||
return new RectInt(paintedRect.x, paintedRect.y, Mathf.Max(1, defaultSize.x), Mathf.Max(1, defaultSize.y));
|
||||
return new RectInt(paintedRect.x, paintedRect.y, Mathf.Max(1, defaultSize.x),
|
||||
Mathf.Max(1, defaultSize.y));
|
||||
}
|
||||
|
||||
var objectRect = paintedRect;
|
||||
if (paintedRect is { width: 1, height: 1 })
|
||||
{
|
||||
objectRect = new RectInt(paintedRect.x, paintedRect.y, Mathf.Max(1, defaultSize.x), Mathf.Max(1, defaultSize.y));
|
||||
objectRect = new RectInt(paintedRect.x, paintedRect.y, Mathf.Max(1, defaultSize.x),
|
||||
Mathf.Max(1, defaultSize.y));
|
||||
}
|
||||
|
||||
var min = StageObjectDefinition.GetMinSize(entry.objectKind);
|
||||
@ -440,7 +453,8 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
private bool CanEditObjectOnActiveFloor(StageObjectDefinition obj)
|
||||
{
|
||||
return stage is not null && obj is not null && stage.ActiveFloor is not null && obj.floorId == stage.ActiveFloor.floorId;
|
||||
return stage is not null && obj is not null && stage.ActiveFloor is not null &&
|
||||
obj.floorId == stage.ActiveFloor.floorId;
|
||||
}
|
||||
|
||||
private void UpdateHoverCell(Vector2 localMousePosition)
|
||||
@ -480,14 +494,74 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
|
||||
DrawInfiniteGrid(p);
|
||||
DrawCells(p, floor);
|
||||
DrawObjects(p, floor.floorId);
|
||||
|
||||
DrawLowerFloors(p);
|
||||
|
||||
DrawCells(p, floor, 1f);
|
||||
DrawObjects(p, floor.floorId, 1f, true);
|
||||
|
||||
DrawOriginAxes(p);
|
||||
DrawHoverCell(p);
|
||||
DrawPreview(p);
|
||||
}
|
||||
|
||||
private void DrawLowerFloors(Painter2D p)
|
||||
{
|
||||
if (stage is null || stage.floors is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void DrawCells(Painter2D p, StageFloorDefinition floor)
|
||||
var activeIndex = Mathf.Clamp(stage.activeFloorIndex, 0, stage.floors.Count - 1);
|
||||
|
||||
for (var i = 0; i < activeIndex; i++)
|
||||
{
|
||||
var lowerFloor = stage.floors[i];
|
||||
if (lowerFloor is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var alpha = GetLowerFloorAlpha(i, activeIndex);
|
||||
|
||||
DrawCells(p, lowerFloor, alpha);
|
||||
DrawObjects(p, lowerFloor.floorId, alpha, false);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetLowerFloorAlpha(int floorIndex, int activeFloorIndex)
|
||||
{
|
||||
var distance = activeFloorIndex - floorIndex;
|
||||
|
||||
// Floor imediatamente abaixo aparece mais forte.
|
||||
// Floors mais distantes ficam mais apagados.
|
||||
return Mathf.Clamp(0.38f - ((distance - 1) * 0.10f), 0.10f, 0.38f);
|
||||
}
|
||||
|
||||
private void FillTriangle(Painter2D p, Vector2 a, Vector2 b, Vector2 c, Color color)
|
||||
{
|
||||
p.fillColor = color;
|
||||
p.BeginPath();
|
||||
p.MoveTo(a);
|
||||
p.LineTo(b);
|
||||
p.LineTo(c);
|
||||
p.ClosePath();
|
||||
p.Fill();
|
||||
}
|
||||
|
||||
private void StrokeTriangle(Painter2D p, Vector2 a, Vector2 b, Vector2 c, Color color, float width)
|
||||
{
|
||||
p.strokeColor = color;
|
||||
p.lineWidth = width;
|
||||
p.BeginPath();
|
||||
p.MoveTo(a);
|
||||
p.LineTo(b);
|
||||
p.LineTo(c);
|
||||
p.ClosePath();
|
||||
p.Stroke();
|
||||
}
|
||||
|
||||
private void DrawCells(Painter2D p, StageFloorDefinition floor, float alphaMultiplier)
|
||||
{
|
||||
foreach (var cell in floor.Cells)
|
||||
{
|
||||
@ -497,12 +571,103 @@ namespace Editor.GardensStageEditor
|
||||
continue;
|
||||
}
|
||||
|
||||
color = color.WithAlpha(color.a * alphaMultiplier);
|
||||
|
||||
var rect = CellRect(cell.x, cell.y);
|
||||
FillRect(p, rect, color);
|
||||
|
||||
DrawStructuralIcon(p, cell.structural, rect);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawObjects(Painter2D p, string floorId)
|
||||
private void DrawStructuralIcon(Painter2D p, StructuralCellKind kind, Rect rect)
|
||||
{
|
||||
if (cellPixels < 18f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pad = Mathf.Clamp(rect.width * 0.18f, 3f, 8f);
|
||||
var inner = rect.Expanded(-pad);
|
||||
var ink = Color.black.WithAlpha(0.55f);
|
||||
var light = Color.white.WithAlpha(0.45f);
|
||||
var line = Mathf.Clamp(cellPixels * 0.08f, 1.5f, 4f);
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case StructuralCellKind.Ground_Slab:
|
||||
StrokeRect(p, inner, ink, line);
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.center.y), new Vector2(inner.xMax, inner.center.y), light,
|
||||
line);
|
||||
break;
|
||||
|
||||
case StructuralCellKind.Ground_Ramp_Front:
|
||||
FillTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMin, inner.yMax),
|
||||
new Vector2(inner.xMax, inner.yMax),
|
||||
new Vector2(inner.center.x, inner.yMin),
|
||||
light
|
||||
);
|
||||
StrokeTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMin, inner.yMax),
|
||||
new Vector2(inner.xMax, inner.yMax),
|
||||
new Vector2(inner.center.x, inner.yMin),
|
||||
ink,
|
||||
line
|
||||
);
|
||||
break;
|
||||
|
||||
case StructuralCellKind.Ground_Ramp_Left:
|
||||
FillTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMax, inner.yMin),
|
||||
new Vector2(inner.xMin, inner.center.y),
|
||||
new Vector2(inner.xMax, inner.yMax),
|
||||
light
|
||||
);
|
||||
StrokeTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMax, inner.yMin),
|
||||
new Vector2(inner.xMin, inner.center.y),
|
||||
new Vector2(inner.xMax, inner.yMax),
|
||||
ink,
|
||||
line
|
||||
);
|
||||
break;
|
||||
|
||||
case StructuralCellKind.Ground_Ramp_Right:
|
||||
FillTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMin, inner.yMin),
|
||||
new Vector2(inner.xMax, inner.center.y),
|
||||
new Vector2(inner.xMin, inner.yMax),
|
||||
light
|
||||
);
|
||||
StrokeTriangle(
|
||||
p,
|
||||
new Vector2(inner.xMin, inner.yMin),
|
||||
new Vector2(inner.xMax, inner.center.y),
|
||||
new Vector2(inner.xMin, inner.yMax),
|
||||
ink,
|
||||
line
|
||||
);
|
||||
break;
|
||||
|
||||
case StructuralCellKind.Wall:
|
||||
StrokeRect(p, inner, ink, line);
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.yMin), new Vector2(inner.xMax, inner.yMax), ink, line);
|
||||
DrawLine(p, new Vector2(inner.xMax, inner.yMin), new Vector2(inner.xMin, inner.yMax), ink, line);
|
||||
break;
|
||||
case StructuralCellKind.Empty:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawObjects(Painter2D p, string floorId, float alphaMultiplier, bool allowSelection)
|
||||
{
|
||||
foreach (var obj in stage.objects)
|
||||
{
|
||||
@ -513,10 +678,13 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
var rect = GridRect(obj.Bounds);
|
||||
var color = StageEditorColors.Layer(obj.layer);
|
||||
FillRect(p, rect, color);
|
||||
StrokeRect(p, rect, color.WithAlpha(Mathf.Min(1f, color.a + 0.25f)), 2f);
|
||||
color = color.WithAlpha(color.a * alphaMultiplier);
|
||||
|
||||
if (state.selectedObject == obj)
|
||||
FillRect(p, rect, color);
|
||||
StrokeRect(p, rect, color.WithAlpha(Mathf.Min(1f, color.a + 0.25f * alphaMultiplier)), 2f);
|
||||
DrawObjectIcon(p, obj.kind, rect);
|
||||
|
||||
if (allowSelection && state.selectedObject == obj)
|
||||
{
|
||||
StrokeRect(p, rect.Expanded(2f), StageEditorColors.SelectionStroke, 3f);
|
||||
|
||||
@ -528,6 +696,65 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawObjectIcon(Painter2D p, StageObjectKind kind, Rect rect)
|
||||
{
|
||||
if (cellPixels < 18f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pad = Mathf.Clamp(Mathf.Min(rect.width, rect.height) * 0.2f, 4f, 12f);
|
||||
var inner = rect.Expanded(-pad);
|
||||
var ink = Color.black.WithAlpha(0.65f);
|
||||
var light = Color.white.WithAlpha(0.7f);
|
||||
var line = Mathf.Clamp(cellPixels * 0.08f, 1.5f, 4f);
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
case StageObjectKind.Trap_FallingFloor:
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.center.y), new Vector2(inner.center.x, inner.yMin), ink,
|
||||
line);
|
||||
DrawLine(p, new Vector2(inner.center.x, inner.yMin), new Vector2(inner.xMax, inner.yMax), ink,
|
||||
line);
|
||||
break;
|
||||
|
||||
case StageObjectKind.DoorHorizontal:
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.center.y), new Vector2(inner.xMax, inner.center.y), light,
|
||||
line);
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.yMin), new Vector2(inner.xMin, inner.yMax), ink, line);
|
||||
DrawLine(p, new Vector2(inner.xMax, inner.yMin), new Vector2(inner.xMax, inner.yMax), ink, line);
|
||||
break;
|
||||
|
||||
case StageObjectKind.DoorVertical:
|
||||
DrawLine(p, new Vector2(inner.center.x, inner.yMin), new Vector2(inner.center.x, inner.yMax), light,
|
||||
line);
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.yMin), new Vector2(inner.xMax, inner.yMin), ink, line);
|
||||
DrawLine(p, new Vector2(inner.xMin, inner.yMax), new Vector2(inner.xMax, inner.yMax), ink, line);
|
||||
break;
|
||||
|
||||
case StageObjectKind.CameraBoundary:
|
||||
DrawCornerBrackets(p, inner, ink, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCornerBrackets(Painter2D p, Rect rect, Color color, float width)
|
||||
{
|
||||
var l = Mathf.Min(rect.width, rect.height) * 0.25f;
|
||||
|
||||
DrawLine(p, new Vector2(rect.xMin, rect.yMin), new Vector2(rect.xMin + l, rect.yMin), color, width);
|
||||
DrawLine(p, new Vector2(rect.xMin, rect.yMin), new Vector2(rect.xMin, rect.yMin + l), color, width);
|
||||
|
||||
DrawLine(p, new Vector2(rect.xMax, rect.yMin), new Vector2(rect.xMax - l, rect.yMin), color, width);
|
||||
DrawLine(p, new Vector2(rect.xMax, rect.yMin), new Vector2(rect.xMax, rect.yMin + l), color, width);
|
||||
|
||||
DrawLine(p, new Vector2(rect.xMin, rect.yMax), new Vector2(rect.xMin + l, rect.yMax), color, width);
|
||||
DrawLine(p, new Vector2(rect.xMin, rect.yMax), new Vector2(rect.xMin, rect.yMax - l), color, width);
|
||||
|
||||
DrawLine(p, new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax - l, rect.yMax), color, width);
|
||||
DrawLine(p, new Vector2(rect.xMax, rect.yMax), new Vector2(rect.xMax, rect.yMax - l), color, width);
|
||||
}
|
||||
|
||||
private void DrawResizeHandle(Painter2D p, StageObjectDefinition obj)
|
||||
{
|
||||
var handle = GetResizeHandleRect(obj);
|
||||
@ -634,7 +861,8 @@ namespace Editor.GardensStageEditor
|
||||
|
||||
private Rect GridRect(RectInt rect)
|
||||
{
|
||||
return new Rect(pan.x + rect.x * cellPixels, pan.y + rect.y * cellPixels, rect.width * cellPixels, rect.height * cellPixels);
|
||||
return new Rect(pan.x + rect.x * cellPixels, pan.y + rect.y * cellPixels, rect.width * cellPixels,
|
||||
rect.height * cellPixels);
|
||||
}
|
||||
|
||||
private Rect GetResizeHandleRect(StageObjectDefinition obj)
|
||||
@ -693,4 +921,4 @@ namespace Editor.GardensStageEditor
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c584058841343debb04c00199a79393
|
||||
@ -73,9 +73,14 @@ namespace Editor.GardensStageEditor
|
||||
{
|
||||
var entries = new List<StagePaletteEntry>
|
||||
{
|
||||
Structural("struct_ground", "Ground", StructuralCellKind.Ground),
|
||||
Structural("struct_ground_slab", "Ground - Slab", StructuralCellKind.Ground_Slab),
|
||||
Structural("struct_ground_ramp_front", "Ground - RF", StructuralCellKind.Ground_Ramp_Front),
|
||||
Structural("struct_ground_ramp_left", "Ground - RL", StructuralCellKind.Ground_Ramp_Left),
|
||||
Structural("struct_ground_ramp_right", "Ground - RR", StructuralCellKind.Ground_Ramp_Right),
|
||||
Structural("struct_wall", "Wall", StructuralCellKind.Wall),
|
||||
Structural("struct_empty", "Erase Structural", StructuralCellKind.Empty)
|
||||
|
||||
// leave it as last as possible
|
||||
Structural("struct_empty", "Erase Structural", StructuralCellKind.Empty),
|
||||
};
|
||||
|
||||
var trapFallingFloor = Object("trap_falling_floor",
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e7ed87816264200a12fcc4bf3584153
|
||||
@ -40,12 +40,7 @@ namespace Editor.GardensStageEditor
|
||||
}
|
||||
|
||||
stage.EnsureDefaults();
|
||||
|
||||
if (string.IsNullOrEmpty(stage.stageId))
|
||||
{
|
||||
messages.Add(new StageValidationMessage(StageValidationSeverity.Warning, "Stage id is empty."));
|
||||
}
|
||||
|
||||
|
||||
if (stage.floors.Count == 0)
|
||||
{
|
||||
messages.Add(new StageValidationMessage(StageValidationSeverity.Error, "Stage has no floors."));
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Core.Entities.Messages;
|
||||
using Intrepid.Core.Grounding;
|
||||
using Intrepid.Diagnostics;
|
||||
@ -11,6 +12,8 @@ namespace Intrepid.Core.Entities
|
||||
{
|
||||
public sealed class EntityMotorTopDown : MonoBehaviour
|
||||
{
|
||||
private const float FlatGroundNormalThreshold = 0.999f;
|
||||
|
||||
[GroupInjections, SerializeField] private Entity entity;
|
||||
[GroupConfigurations, SerializeField] private LayerMask groundMask;
|
||||
|
||||
@ -29,32 +32,42 @@ namespace Intrepid.Core.Entities
|
||||
[GroupConfigurations, SerializeField] private float fallAcceleration = 35f;
|
||||
[GroupConfigurations, SerializeField] private float maxFallSpeed = 18f;
|
||||
|
||||
private readonly List<RaycastHit> _groundHits = new(16);
|
||||
private RaycastHit _groundHit;
|
||||
private Vector3 Origin { get; set; }
|
||||
private Vector3 End { get; set; }
|
||||
private bool HasHit { get; set; }
|
||||
private Vector3 _inheritedGroundVelocity;
|
||||
private float _fallVerticalSpeed;
|
||||
private RaycastHit _groundHit;
|
||||
|
||||
private float GroundProbeRadius => IsFalling || IsFallingToAbyss
|
||||
? groundProbeRadiusFalling
|
||||
: groundProbeRadiusGrounded;
|
||||
|
||||
|
||||
public GroundProfiles CurrentGroundProfiles { get; private set; } = GroundProfiles.None;
|
||||
public float MaxSlopeAngle => maxSlopeAngle;
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public Vector3 LastSafeGroundPosition { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public bool HasStableGroundNormal { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public Vector3 StableGroundNormal { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public bool IsFalling { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public bool IsFallingToAbyss { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public bool IsGrounded { get; private set; }
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public Vector3 InheritedGroundVelocity => _inheritedGroundVelocity;
|
||||
|
||||
[GroupDebug, ShowInInspector, ReadOnly]
|
||||
public float InheritedGroundVelocityTimer { get; private set; }
|
||||
|
||||
@ -392,55 +405,134 @@ namespace Intrepid.Core.Entities
|
||||
return TryGetGroundSurfaceAt(position, out _, out _, out _);
|
||||
}
|
||||
|
||||
private bool TryGetBestGroundSurfaceHit(
|
||||
Vector3 position,
|
||||
float checkDistance,
|
||||
out RaycastHit hit,
|
||||
out Vector3 normal,
|
||||
out GroundProfiles groundProfiles)
|
||||
{
|
||||
hit = default;
|
||||
normal = default;
|
||||
groundProfiles = GroundProfiles.None;
|
||||
|
||||
Origin = position + Vector3.up * groundCheckHeight;
|
||||
End = Origin + Vector3.down * checkDistance;
|
||||
|
||||
_groundHits.Clear();
|
||||
|
||||
var hitCount = PhysicUtils.SphereCast3DAll(
|
||||
Origin,
|
||||
GroundProbeRadius,
|
||||
Vector3.down,
|
||||
_groundHits,
|
||||
tags: null,
|
||||
maxDistance: checkDistance,
|
||||
layerMask: groundMask,
|
||||
query: QueryTriggerInteraction.Ignore
|
||||
);
|
||||
|
||||
HasHit = hitCount > 0;
|
||||
|
||||
if (hitCount == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var found = false;
|
||||
|
||||
var bestHit = default(RaycastHit);
|
||||
var bestNormal = Vector3.zero;
|
||||
var bestProfiles = GroundProfiles.None;
|
||||
|
||||
var bestIsSlope = false;
|
||||
var bestDistance = float.PositiveInfinity;
|
||||
|
||||
foreach (var candidateHit in _groundHits)
|
||||
{
|
||||
if (candidateHit.collider.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var surface = candidateHit.collider.GetComponentInParent<GroundSurface>();
|
||||
|
||||
if (surface.IsNull())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var candidateNormal = surface.Normal;
|
||||
|
||||
if (!IsWalkable(candidateNormal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var candidateIsSlope = IsSlope(candidateNormal);
|
||||
var candidateDistance = candidateHit.distance;
|
||||
|
||||
var shouldReplace =
|
||||
!found ||
|
||||
|
||||
// any walkable slope wins a plane
|
||||
candidateIsSlope && !bestIsSlope ||
|
||||
|
||||
// if both are slopes or planes take the closest one
|
||||
candidateIsSlope == bestIsSlope &&
|
||||
candidateDistance < bestDistance;
|
||||
|
||||
if (!shouldReplace)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
found = true;
|
||||
|
||||
bestHit = candidateHit;
|
||||
bestNormal = candidateNormal;
|
||||
bestProfiles = surface.GroundProfiles;
|
||||
|
||||
bestIsSlope = candidateIsSlope;
|
||||
bestDistance = candidateDistance;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
hit = bestHit;
|
||||
normal = bestNormal;
|
||||
groundProfiles = bestProfiles;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryGetGroundSurfaceAt(
|
||||
Vector3 position,
|
||||
out RaycastHit hit,
|
||||
out Vector3 normal,
|
||||
out GroundProfiles groundProfiles)
|
||||
{
|
||||
normal = default;
|
||||
groundProfiles = GroundProfiles.None;
|
||||
|
||||
if (!TryGetGroundAt(position, out hit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var surface = hit.collider.GetComponentInParent<GroundSurface>();
|
||||
|
||||
if (surface.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
normal = surface.Normal;
|
||||
|
||||
if (!IsWalkable(normal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
groundProfiles = surface.GroundProfiles;
|
||||
|
||||
return true;
|
||||
return TryGetBestGroundSurfaceHit(
|
||||
position,
|
||||
groundCheckDistance,
|
||||
out hit,
|
||||
out normal,
|
||||
out groundProfiles
|
||||
);
|
||||
}
|
||||
|
||||
private bool TryGetGroundAt(Vector3 position, out RaycastHit hit)
|
||||
{
|
||||
Origin = position + Vector3.up * groundCheckHeight;
|
||||
End = Origin + Vector3.down * groundCheckDistance;
|
||||
|
||||
HasHit = Physics.SphereCast(
|
||||
Origin,
|
||||
GroundProbeRadius,
|
||||
Vector3.down,
|
||||
out hit,
|
||||
return TryGetBestGroundSurfaceHit(
|
||||
position,
|
||||
groundCheckDistance,
|
||||
groundMask,
|
||||
QueryTriggerInteraction.Ignore
|
||||
out hit,
|
||||
out _,
|
||||
out _
|
||||
);
|
||||
|
||||
return HasHit;
|
||||
}
|
||||
|
||||
private bool TryAnyGroundSurfaceBelowAt(
|
||||
@ -449,43 +541,18 @@ namespace Intrepid.Core.Entities
|
||||
out Vector3 normal,
|
||||
out GroundProfiles groundProfiles)
|
||||
{
|
||||
normal = default;
|
||||
groundProfiles = GroundProfiles.None;
|
||||
|
||||
var origin = position + Vector3.up * groundCheckHeight;
|
||||
|
||||
HasHit = Physics.SphereCast(
|
||||
origin,
|
||||
GroundProbeRadius,
|
||||
Vector3.down,
|
||||
out hit,
|
||||
return TryGetBestGroundSurfaceHit(
|
||||
position,
|
||||
fallingGroundCheckDistance,
|
||||
groundMask,
|
||||
QueryTriggerInteraction.Ignore
|
||||
out hit,
|
||||
out normal,
|
||||
out groundProfiles
|
||||
);
|
||||
}
|
||||
|
||||
if (!HasHit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var surface = hit.collider.GetComponentInParent<GroundSurface>();
|
||||
|
||||
if (surface.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
normal = surface.Normal;
|
||||
|
||||
if (!IsWalkable(normal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
groundProfiles = surface.GroundProfiles;
|
||||
|
||||
return true;
|
||||
private static bool IsSlope(Vector3 normal)
|
||||
{
|
||||
return normal.y < FlatGroundNormalThreshold;
|
||||
}
|
||||
|
||||
private bool IsWalkable(Vector3 normal)
|
||||
|
||||
@ -12,19 +12,24 @@ namespace Intrepid.Gameplay.Prototyping
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeX = 1;
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeY = 1;
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeZ = 1;
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private float offset = 1f;
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private Vector2 offset_x = new(1f, 1.5f);
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private Vector2 offset_y = new(1f, 1.5f);
|
||||
|
||||
[GroupDebug, SerializeField, Min(1)] private int x = 1;
|
||||
[GroupDebug, SerializeField, Min(1)] private int y = 1;
|
||||
[GroupDebug, SerializeField, Min(1)] private int z = 1;
|
||||
[GroupDebug, SerializeField, Range(0f, 1f)] private float contact_offset = 1f;
|
||||
[GroupDebug, SerializeField] private Vector2 contact_offset_x = new(1f, 1.5f);
|
||||
[GroupDebug, SerializeField] private Vector2 contact_offset_y = new(1f, 1.5f);
|
||||
|
||||
protected override void DebugResize()
|
||||
{
|
||||
sizeX = Mathf.Max(1, x);
|
||||
sizeY = Mathf.Max(1, y);
|
||||
sizeZ = Mathf.Max(1, z);
|
||||
offset = Mathf.Clamp01(contact_offset);
|
||||
offset_x.x = Mathf.Clamp(contact_offset_x.x, 0f, 2f);
|
||||
offset_x.y = Mathf.Clamp(contact_offset_x.y, 0f, 2f);
|
||||
offset_y.x = Mathf.Clamp(contact_offset_y.x, 0f, 2f);
|
||||
offset_y.y = Mathf.Clamp(contact_offset_y.y, 0f, 2f);
|
||||
}
|
||||
|
||||
protected override void Generate()
|
||||
@ -41,9 +46,11 @@ namespace Intrepid.Gameplay.Prototyping
|
||||
vertices.ToArray(),
|
||||
triangles.ToArray(),
|
||||
uvs.ToArray()));
|
||||
|
||||
PrototypeModel.BoxCollider.size = new Vector3(sizeX + offset, sizeY, sizeZ + offset);
|
||||
PrototypeModel.BoxCollider.center = Vector3.zero;
|
||||
|
||||
var offsetX = offset_x.x + offset_x.y;
|
||||
var offsetY = offset_y.x + offset_y.y;
|
||||
PrototypeModel.BoxCollider.size = new Vector3(sizeX + offsetX, sizeY, sizeZ + offsetY);
|
||||
PrototypeModel.BoxCollider.center = new Vector3((offset_x.x - offset_x.y) / 2f, 0f, (offset_y.x - offset_y.y) / 2f);
|
||||
PrototypeModel.transform.localPosition = new Vector3(0f, sizeY / 2f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Intrepid.Gameplay.Prototyping
|
||||
{
|
||||
public abstract class GroundModelPrototype : ModelPrototype
|
||||
{
|
||||
public abstract void SetSize(Vector2Int size);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Utilities;
|
||||
using Sirenix.OdinInspector;
|
||||
@ -14,6 +13,13 @@ namespace Intrepid.Gameplay.Prototyping
|
||||
[GroupDebug, SerializeField, Min(1)] private int x = 1;
|
||||
[GroupDebug, SerializeField, Min(1)] private int z = 1;
|
||||
|
||||
public override void SetSize(Vector2Int size)
|
||||
{
|
||||
x = size.x;
|
||||
z = size.y;
|
||||
SizeFitting();
|
||||
}
|
||||
|
||||
protected override void DebugResize()
|
||||
{
|
||||
sizeX = Mathf.Max(1, x);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Utilities;
|
||||
using Sirenix.OdinInspector;
|
||||
@ -16,6 +15,13 @@ namespace Intrepid.Gameplay.Prototyping
|
||||
[GroupDebug, SerializeField, Min(1)] private int x = 1;
|
||||
[GroupDebug, SerializeField, Min(1)] private int z = 1;
|
||||
|
||||
public override void SetSize(Vector2Int size)
|
||||
{
|
||||
x = size.x;
|
||||
z = size.y;
|
||||
SizeFitting();
|
||||
}
|
||||
|
||||
protected override void DebugResize()
|
||||
{
|
||||
sizeX = Mathf.Max(1, x);
|
||||
|
||||
@ -0,0 +1,116 @@
|
||||
using System.Collections.Generic;
|
||||
using Intrepid.Utilities;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Intrepid.Gameplay.Prototyping
|
||||
{
|
||||
public class GroundStairModelPrototype : GroundModelPrototype
|
||||
{
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeX = 1;
|
||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeZ = 1;
|
||||
|
||||
[GroupDebug, SerializeField, Min(1)] private int x = 1;
|
||||
[GroupDebug, SerializeField, Min(1)] private int z = 1;
|
||||
|
||||
public override void SetSize(Vector2Int size)
|
||||
{
|
||||
x = size.x;
|
||||
z = size.y;
|
||||
SizeFitting();
|
||||
}
|
||||
|
||||
protected override void DebugResize()
|
||||
{
|
||||
x = Mathf.Max(1, x);
|
||||
z = Mathf.Max(1, z);
|
||||
sizeX = x;
|
||||
sizeZ = z;
|
||||
}
|
||||
|
||||
protected override void Generate()
|
||||
{
|
||||
// PrototypeModel.BuildMesh(BuildRampMeshData(new Vector3(sizeX, sizeZ * .75f, sizeZ)));
|
||||
//
|
||||
// PrototypeModel.BoxCollider.transform.localEulerAngles = new Vector3(-36.87f, 0f, 0f);
|
||||
// PrototypeModel.BoxCollider.center = new Vector3(0f, -0.025f, 0f);
|
||||
// PrototypeModel.BoxCollider.size = new Vector3(sizeX, 0.05f, sizeZ * 1.25f);
|
||||
//
|
||||
// PrototypeModel.transform.localPosition = new Vector3(0f, sizeZ * .5f, 0f);
|
||||
PrototypeModel.BuildMesh(BuildRampMeshData(new Vector3(sizeX, sizeZ, sizeZ)));
|
||||
|
||||
PrototypeModel.BoxCollider.transform.localEulerAngles = new Vector3(-45f, 0f, 0f);
|
||||
PrototypeModel.BoxCollider.center = new Vector3(0f, -0.025f, 0f);
|
||||
PrototypeModel.BoxCollider.size = new Vector3(sizeX, 0.05f, sizeZ * 1.4142f);
|
||||
|
||||
PrototypeModel.transform.localPosition = new Vector3(0f, sizeZ * .5f, 0f);
|
||||
}
|
||||
|
||||
private static MeshData BuildRampMeshData(Vector3 size)
|
||||
{
|
||||
var halfX = size.x * 0.5f;
|
||||
var halfY = size.y * 0.5f;
|
||||
var halfZ = size.z * 0.5f;
|
||||
|
||||
var bottomY = -halfY;
|
||||
var topY = halfY;
|
||||
|
||||
var countX = Mathf.Max(1, Mathf.RoundToInt(size.x));
|
||||
var countZ = Mathf.Max(1, Mathf.RoundToInt(size.z));
|
||||
|
||||
var vertices = new List<Vector3>();
|
||||
var triangles = new List<int>();
|
||||
var uvs = new List<Vector2>();
|
||||
|
||||
var rampStep = new Vector3(
|
||||
0f,
|
||||
size.y / countZ,
|
||||
size.z / countZ
|
||||
);
|
||||
|
||||
// Ramp surface
|
||||
MeshUtils.AddGridFace(
|
||||
vertices,
|
||||
triangles,
|
||||
uvs,
|
||||
origin: new Vector3(halfX, bottomY, -halfZ),
|
||||
axisU: Vector3.left,
|
||||
axisV: rampStep,
|
||||
countU: countX,
|
||||
countV: countZ
|
||||
);
|
||||
|
||||
// Left
|
||||
MeshUtils.AddTriangle(
|
||||
vertices,
|
||||
triangles,
|
||||
uvs,
|
||||
new Vector3(-halfX, bottomY, -halfZ),
|
||||
new Vector3(-halfX, bottomY, halfZ),
|
||||
new Vector3(-halfX, topY, halfZ),
|
||||
new Vector2(0f, 0f),
|
||||
new Vector2(size.z, 0f),
|
||||
new Vector2(size.z, size.y)
|
||||
);
|
||||
|
||||
// Right
|
||||
MeshUtils.AddTriangle(
|
||||
vertices,
|
||||
triangles,
|
||||
uvs,
|
||||
new Vector3(halfX, bottomY, -halfZ),
|
||||
new Vector3(halfX, topY, halfZ),
|
||||
new Vector3(halfX, bottomY, halfZ),
|
||||
new Vector2(0f, 0f),
|
||||
new Vector2(size.z, size.y),
|
||||
new Vector2(size.z, 0f)
|
||||
);
|
||||
|
||||
return new MeshData(
|
||||
vertices.ToArray(),
|
||||
triangles.ToArray(),
|
||||
uvs.ToArray()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a3b1270c87c4456bdc61721ca19132f
|
||||
timeCreated: 1781674851
|
||||
@ -43,7 +43,7 @@ namespace Intrepid.Gameplay.Prototyping
|
||||
}
|
||||
|
||||
[GroupDebug, Button(ButtonSizes.Medium, ButtonStyle.FoldoutButton)]
|
||||
private void SetSize()
|
||||
protected void SizeFitting()
|
||||
{
|
||||
DebugResize();
|
||||
if (PrototypeModel.IsNull()) return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user