Compare commits
3 Commits
bfd4e450e1
...
2a23d4cf9c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a23d4cf9c | ||
|
|
e9d7d39f2b | ||
|
|
1a4b2443ff |
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:
|
||||||
@ -5,7 +5,7 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace __Prototype.Scripts
|
namespace __Prototype.Scripts
|
||||||
{
|
{
|
||||||
public class TestGroundMorion : GroundProfileMotion
|
public class TestGroundMorion : GroundProfileMotionBehaviour
|
||||||
{
|
{
|
||||||
[GroupConfigurations, SerializeField] private Vector3 localDirection = Vector3.right;
|
[GroupConfigurations, SerializeField] private Vector3 localDirection = Vector3.right;
|
||||||
[GroupConfigurations, SerializeField] private float speed = 2f;
|
[GroupConfigurations, SerializeField] private float speed = 2f;
|
||||||
@ -13,10 +13,26 @@ namespace __Prototype.Scripts
|
|||||||
[GroupConfigurations, SerializeField] private bool pingPong = true;
|
[GroupConfigurations, SerializeField] private bool pingPong = true;
|
||||||
[GroupConfigurations, SerializeField] private bool moveOnStart;
|
[GroupConfigurations, SerializeField] private bool moveOnStart;
|
||||||
|
|
||||||
public override Vector3 Velocity { get; protected set; }
|
public Vector3 Velocity
|
||||||
public override Vector3 DeltaPosition { get; protected set; }
|
{
|
||||||
public override bool IsMoving { get; protected set; }
|
get => GroundProfileMotion.Velocity;
|
||||||
public override bool IsStatic { get; protected set; } = false;
|
private set => GroundProfileMotion.Velocity = value;
|
||||||
|
}
|
||||||
|
public Vector3 DeltaPosition
|
||||||
|
{
|
||||||
|
get => GroundProfileMotion.DeltaPosition;
|
||||||
|
private set => GroundProfileMotion.DeltaPosition = value;
|
||||||
|
}
|
||||||
|
public bool IsMoving
|
||||||
|
{
|
||||||
|
get => GroundProfileMotion.IsMoving;
|
||||||
|
private set => GroundProfileMotion.IsMoving = value;
|
||||||
|
}
|
||||||
|
public bool IsStatic
|
||||||
|
{
|
||||||
|
get => GroundProfileMotion.IsStatic;
|
||||||
|
private set => GroundProfileMotion.IsStatic = value;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector3 _startPosition;
|
private Vector3 _startPosition;
|
||||||
private Vector3 _lastPosition;
|
private Vector3 _lastPosition;
|
||||||
@ -69,7 +85,7 @@ namespace __Prototype.Scripts
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
next = _startPosition + worldDirection * Mathf.Sign(distanceFromStart) * maxDistance;
|
next = _startPosition + worldDirection * (Mathf.Sign(distanceFromStart) * maxDistance);
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
%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: 778f9d79eb2c410482efdc25b248dd46, type: 3}
|
|
||||||
m_Name: StageDefinition
|
|
||||||
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.StageDefinition
|
|
||||||
stageId: stagedefinition
|
|
||||||
cellSize: 1
|
|
||||||
floorHeight: 6
|
|
||||||
activeFloorIndex: 0
|
|
||||||
floors:
|
|
||||||
- floorId: F0
|
|
||||||
cells: []
|
|
||||||
objects: []
|
|
||||||
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
@ -8,6 +8,14 @@ PrefabInstance:
|
|||||||
serializedVersion: 3
|
serializedVersion: 3
|
||||||
m_TransformParent: {fileID: 0}
|
m_TransformParent: {fileID: 0}
|
||||||
m_Modifications:
|
m_Modifications:
|
||||||
|
- target: {fileID: 101776470001583037, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
propertyPath: movementProfiles.Array.size
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 101776470001583037, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
propertyPath: 'movementProfiles.Array.data[0]'
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 5801231790879681971}
|
||||||
- target: {fileID: 221717111884494654, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
- target: {fileID: 221717111884494654, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
propertyPath: m_Mesh
|
propertyPath: m_Mesh
|
||||||
value:
|
value:
|
||||||
@ -90,7 +98,7 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
- target: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Ground_Ramp_Prototype
|
value: Ground_Ramp_Front_Prototype
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_RemovedGameObjects: []
|
m_RemovedGameObjects: []
|
||||||
@ -99,6 +107,9 @@ PrefabInstance:
|
|||||||
- targetCorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 116909126457648545}
|
addedObject: {fileID: 116909126457648545}
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 5801231790879681971}
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
--- !u!114 &2719093777726527478 stripped
|
--- !u!114 &2719093777726527478 stripped
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
@ -134,3 +145,23 @@ MonoBehaviour:
|
|||||||
sizeZ: 1
|
sizeZ: 1
|
||||||
x: 1
|
x: 1
|
||||||
z: 1
|
z: 1
|
||||||
|
--- !u!114 &5801231790879681971
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 9140983697215042600}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: bdd4ad30e2d149b58a2f84fa9a5b5fbc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Core.Grounding.GroundProfileMovementBehaviour
|
||||||
|
id: 9d7dfeaecb7e4204ba7dd29dede5075d
|
||||||
|
groundProfileMovement:
|
||||||
|
speedMultiplier: 1
|
||||||
|
accelerationMultiplier: 1
|
||||||
|
decelerationMultiplier: 1
|
||||||
|
uphillSpeedMultiplier: 0.75
|
||||||
|
downhillSpeedMultiplier: 1
|
||||||
|
sidewaysSpeedMultiplier: 0.9
|
||||||
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:
|
||||||
171
Assets/Prefabs/Prototypes/Ground_Stair_Front_Prototype.prefab
Normal file
171
Assets/Prefabs/Prototypes/Ground_Stair_Front_Prototype.prefab
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
%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: 101776470001583037, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
propertyPath: movementProfiles.Array.size
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 101776470001583037, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
propertyPath: 'movementProfiles.Array.data[0]'
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 1964621128587179894}
|
||||||
|
- 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}
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 6524376507900539265, guid: 84ef2ec4df393420d973aa876a8778b6, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: 1964621128587179894}
|
||||||
|
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
|
||||||
|
--- !u!114 &1964621128587179894
|
||||||
|
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: bdd4ad30e2d149b58a2f84fa9a5b5fbc, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Core.Grounding.GroundProfileMovementBehaviour
|
||||||
|
id: afbca706aa91413387e401bb77925f70
|
||||||
|
groundProfileMovement:
|
||||||
|
speedMultiplier: 1
|
||||||
|
accelerationMultiplier: 1
|
||||||
|
decelerationMultiplier: 1
|
||||||
|
uphillSpeedMultiplier: 0.5
|
||||||
|
downhillSpeedMultiplier: 1
|
||||||
|
sidewaysSpeedMultiplier: 0.9
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: da66eef8ff1ce4c3eaf46c09ad26e70b
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
63
Assets/Prefabs/Prototypes/Ground_Stair_Left_Prototype.prefab
Normal file
63
Assets/Prefabs/Prototypes/Ground_Stair_Left_Prototype.prefab
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &3382806052188099058
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 0.7071068
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: -0.7071068
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: -90
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3608453355090094120, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_Mesh
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 7749360569717010071, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: Ground_Stair_Left_Prototype
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c11973af2c21642658a917c1253a53f4
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1001 &8988140421347768202
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
serializedVersion: 3
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 0.7071068
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0.7071068
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 90
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3190054200416215303, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 3608453355090094120, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_Mesh
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 7749360569717010071, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: Ground_Stair_Right_Prototype
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_RemovedGameObjects: []
|
||||||
|
m_AddedGameObjects: []
|
||||||
|
m_AddedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: da66eef8ff1ce4c3eaf46c09ad26e70b, type: 3}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3e0d56cfe99b4417a8f7c924adc9581e
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -10,23 +10,31 @@ PrefabInstance:
|
|||||||
m_Modifications:
|
m_Modifications:
|
||||||
- target: {fileID: 369205274101430871, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 369205274101430871, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 0.5
|
value: 1.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Size.x
|
propertyPath: m_Size.x
|
||||||
value: 2
|
value: 3
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Size.y
|
propertyPath: m_Size.y
|
||||||
value: 1
|
value: 3
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 3020532133659471693, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Size.z
|
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}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 5094209182163755379, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 5094209182163755379, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Enabled
|
propertyPath: m_Enabled
|
||||||
value: 0
|
value: 1
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6166895172714925370, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 6166895172714925370, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Mesh
|
propertyPath: m_Mesh
|
||||||
@ -74,7 +82,7 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 8449749668273782584, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
- target: {fileID: 8449749668273782584, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Obstacle_Cube_Prototype
|
value: Obstacle_Wall_Prototype
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_RemovedGameObjects: []
|
m_RemovedGameObjects: []
|
||||||
@ -101,16 +109,18 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: ccf30362a82f4d67958b61569d4cf1b4, type: 3}
|
m_Script: {fileID: 11500000, guid: ccf30362a82f4d67958b61569d4cf1b4, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.ContactCubeModelPrototype
|
m_EditorClassIdentifier: Assembly-CSharp::Intrepid.Gameplay.Prototyping.ContactCubeModelPrototype
|
||||||
displayDebug: 0
|
displayDebug: 1
|
||||||
prototypeModel: {fileID: 8402728050198132523}
|
prototypeModel: {fileID: 8402728050198132523}
|
||||||
sizeX: 1
|
sizeX: 1
|
||||||
sizeY: 1
|
sizeY: 3
|
||||||
sizeZ: 1
|
sizeZ: 1
|
||||||
offset: 1
|
offset_x: {x: 1, y: 1}
|
||||||
|
offset_y: {x: 1.5, y: 1}
|
||||||
x: 1
|
x: 1
|
||||||
y: 1
|
y: 3
|
||||||
z: 1
|
z: 1
|
||||||
contact_offset: 1
|
contact_offset_x: {x: 1, y: 1}
|
||||||
|
contact_offset_y: {x: 1.5, y: 1}
|
||||||
--- !u!114 &8402728050198132523 stripped
|
--- !u!114 &8402728050198132523 stripped
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_CorrespondingSourceObject: {fileID: 3563105585321411375, guid: 64620cfd283d648b5b4d9c9a4fac7751, type: 3}
|
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,109 +0,0 @@
|
|||||||
# Gardens Stage Editor Starter Kit
|
|
||||||
|
|
||||||
Starter kit para um editor lógico de stages do **Gardens of Nil** dentro da Unity.
|
|
||||||
|
|
||||||
Este pacote contém somente:
|
|
||||||
|
|
||||||
- modelo de dados (`StageDefinition`, floors, células estruturais e objetos lógicos);
|
|
||||||
- janela de editor com UI Toolkit;
|
|
||||||
- grid 1x1 com pan/zoom;
|
|
||||||
- paleta por layer;
|
|
||||||
- criação/seleção/remoção de elementos lógicos;
|
|
||||||
- inspector simples;
|
|
||||||
- validação básica.
|
|
||||||
|
|
||||||
Não contém bake/rebake de scene, geração de colliders ou integração com Tiled.
|
|
||||||
|
|
||||||
## Instalação
|
|
||||||
|
|
||||||
Descompacte a pasta `GardensStageEditor` dentro de:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Assets/Editor/
|
|
||||||
```
|
|
||||||
|
|
||||||
O resultado deve ficar parecido com:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Assets/Editor/GardensStageEditor/
|
|
||||||
Data/
|
|
||||||
Editor/
|
|
||||||
README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
Depois espere a Unity recompilar.
|
|
||||||
|
|
||||||
## Abrir o editor
|
|
||||||
|
|
||||||
Na Unity:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Gardens > Stage Editor
|
|
||||||
```
|
|
||||||
|
|
||||||
Na janela:
|
|
||||||
|
|
||||||
1. Clique em `New` para criar um `StageDefinition.asset`.
|
|
||||||
2. Escolha a layer na paleta inferior.
|
|
||||||
3. Use `Paint`, `Select`, `Erase` ou `Pan`.
|
|
||||||
4. Pinte o mapa lógico no canvas central.
|
|
||||||
5. Edite o elemento selecionado no inspector à direita.
|
|
||||||
6. Use `Validate` para checagens básicas.
|
|
||||||
|
|
||||||
## Controles
|
|
||||||
|
|
||||||
```txt
|
|
||||||
LMB: pintar / selecionar
|
|
||||||
RMB ou MMB: pan
|
|
||||||
Mouse wheel: zoom
|
|
||||||
```
|
|
||||||
|
|
||||||
## Modelo mental
|
|
||||||
|
|
||||||
O editor trabalha em um plano lógico 2D:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Editor X/Y
|
|
||||||
```
|
|
||||||
|
|
||||||
Mais tarde, o baker pode mapear isso para o mundo Unity:
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Editor X -> Unity X
|
|
||||||
Editor Y -> Unity Z
|
|
||||||
Floor index -> Unity Y offset
|
|
||||||
```
|
|
||||||
|
|
||||||
## Layers iniciais
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Structural: Ground, Wall, Hole, Erase Structural
|
|
||||||
Design: Falling Floor, Door, Interactable, Portal
|
|
||||||
Camera: Camera Zone
|
|
||||||
Markers: Player Spawn, Elevator, Marker
|
|
||||||
```
|
|
||||||
|
|
||||||
## Filosofia
|
|
||||||
|
|
||||||
A scene não é fonte da verdade.
|
|
||||||
|
|
||||||
```txt
|
|
||||||
StageDefinition.asset = source of truth
|
|
||||||
Generated scene/prefab = output futuro do baker
|
|
||||||
```
|
|
||||||
|
|
||||||
Este pacote só cuida do primeiro lado: autoria visual e dados lógicos.
|
|
||||||
|
|
||||||
## Próximos passos sugeridos
|
|
||||||
|
|
||||||
1. Transformar `StagePaletteEntry` em assets configuráveis, se necessário.
|
|
||||||
2. Adicionar hotkeys e melhor seleção/move/resize visual.
|
|
||||||
3. Adicionar overlays de erro no canvas.
|
|
||||||
4. Implementar o baker separado consumindo `StageDefinition`.
|
|
||||||
5. Depois, se fizer sentido, criar import/export Tiled apenas para o mapa lógico.
|
|
||||||
|
|
||||||
## Requisitos recomendados
|
|
||||||
|
|
||||||
Unity 2022.3 LTS ou superior. Unity 6 também deve funcionar.
|
|
||||||
|
|
||||||
O canvas usa UI Toolkit custom drawing (`Painter2D`). Em versões muito antigas da Unity, pode ser necessário trocar o canvas por IMGUI ou SceneView Handles.
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 494fb84451f94e218111409283a7f795
|
|
||||||
timeCreated: 1781500522
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
# Stage Model Notes
|
|
||||||
|
|
||||||
## StageDefinition
|
|
||||||
|
|
||||||
Fonte da verdade do stage lógico.
|
|
||||||
|
|
||||||
Contém:
|
|
||||||
|
|
||||||
- `stageId`
|
|
||||||
- `cellSize`
|
|
||||||
- `floorHeight`
|
|
||||||
- `floors`
|
|
||||||
- `objects`
|
|
||||||
|
|
||||||
## StageFloorDefinition
|
|
||||||
|
|
||||||
Um andar lógico do stage.
|
|
||||||
|
|
||||||
Contém:
|
|
||||||
|
|
||||||
- `floorId`
|
|
||||||
- `width`
|
|
||||||
- `height`
|
|
||||||
- células estruturais preenchidas
|
|
||||||
|
|
||||||
Células vazias não são serializadas explicitamente. Apenas células com `Ground`, `Wall` ou `Hole` são guardadas.
|
|
||||||
|
|
||||||
## Structural cells
|
|
||||||
|
|
||||||
A layer estrutural é cell-based.
|
|
||||||
|
|
||||||
```txt
|
|
||||||
Empty
|
|
||||||
Ground
|
|
||||||
Wall
|
|
||||||
Hole
|
|
||||||
```
|
|
||||||
|
|
||||||
## StageObjectDefinition
|
|
||||||
|
|
||||||
Objetos lógicos são object-based.
|
|
||||||
|
|
||||||
Exemplos:
|
|
||||||
|
|
||||||
- traps
|
|
||||||
- doors
|
|
||||||
- interactables
|
|
||||||
- portals
|
|
||||||
- camera zones
|
|
||||||
- spawn points
|
|
||||||
- elevators
|
|
||||||
- markers
|
|
||||||
|
|
||||||
Cada objeto tem:
|
|
||||||
|
|
||||||
- `id`
|
|
||||||
- `layer`
|
|
||||||
- `kind`
|
|
||||||
- `typeId`
|
|
||||||
- `prefabId`
|
|
||||||
- `floorId`
|
|
||||||
- `x`, `y`, `width`, `height`
|
|
||||||
- flags como `cutsGround` e `blocksMovement`
|
|
||||||
|
|
||||||
## Regra sugerida para bake futuro
|
|
||||||
|
|
||||||
```txt
|
|
||||||
GroundCollision = Structural.Ground - Structural.Hole - Objects(cutsGround)
|
|
||||||
```
|
|
||||||
|
|
||||||
Depois o baker pode compactar células em BoxColliders maiores.
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ffb9c2df7a0f4b3ca08544979287cf20
|
|
||||||
timeCreated: 1781500522
|
|
||||||
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Intrepid.Utilities;
|
||||||
|
using UnityEditor.ShaderGraph.Internal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Editor.GardensStageEditor
|
namespace Editor.GardensStageEditor
|
||||||
@ -15,27 +17,35 @@ namespace Editor.GardensStageEditor
|
|||||||
public enum StructuralCellKind
|
public enum StructuralCellKind
|
||||||
{
|
{
|
||||||
Empty = 0,
|
Empty = 0,
|
||||||
Ground = 1,
|
Ground_Slab = 10,
|
||||||
Wall = 2
|
Ground_Ramp_Front = 11,
|
||||||
|
Ground_Ramp_Left = 12,
|
||||||
|
Ground_Ramp_Right = 13,
|
||||||
|
|
||||||
|
Wall = 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum StageObjectKind
|
public enum StageObjectKind
|
||||||
{
|
{
|
||||||
Trap = 0,
|
Trap_FallingFloor = 0,
|
||||||
Door = 1,
|
|
||||||
Interactable = 2,
|
DoorHorizontal = 10,
|
||||||
Portal = 3,
|
DoorVertical = 11,
|
||||||
CameraZone = 4,
|
|
||||||
Spawn = 5,
|
// Interactable = 2,
|
||||||
Elevator = 6,
|
// Portal = 3,
|
||||||
Marker = 7,
|
|
||||||
Custom = 100
|
CameraBoundary = 40,
|
||||||
|
|
||||||
|
Spawn = 50,
|
||||||
|
// Elevator = 6,
|
||||||
|
// Marker = 7,
|
||||||
|
// Custom = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
[CreateAssetMenu(menuName = "GON/Editor/Stage Definition", fileName = "StageDefinition")]
|
[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 cellSize = 1f;
|
||||||
public float floorHeight = 6f;
|
public float floorHeight = 6f;
|
||||||
public int activeFloorIndex;
|
public int activeFloorIndex;
|
||||||
@ -94,7 +104,7 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
public bool ContainsFloor(string floorId)
|
public bool ContainsFloor(string floorId)
|
||||||
{
|
{
|
||||||
return GetFloor(floorId) != null;
|
return GetFloor(floorId) is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CreateUniqueObjectId(StageObjectKind kind)
|
public string CreateUniqueObjectId(StageObjectKind kind)
|
||||||
@ -130,6 +140,7 @@ namespace Editor.GardensStageEditor
|
|||||||
public sealed class StageFloorDefinition
|
public sealed class StageFloorDefinition
|
||||||
{
|
{
|
||||||
public string floorId = "F0";
|
public string floorId = "F0";
|
||||||
|
public float FloorHeight;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private List<LogicalCell> cells = new();
|
private List<LogicalCell> cells = new();
|
||||||
@ -151,7 +162,7 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
public StructuralCellKind GetCell(int x, int y)
|
public StructuralCellKind GetCell(int x, int y)
|
||||||
{
|
{
|
||||||
int index = FindCellIndex(x, y);
|
var index = FindCellIndex(x, y);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
return StructuralCellKind.Empty;
|
return StructuralCellKind.Empty;
|
||||||
@ -173,7 +184,7 @@ namespace Editor.GardensStageEditor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalCell cell = new LogicalCell
|
var cell = new LogicalCell
|
||||||
{
|
{
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
@ -269,6 +280,11 @@ namespace Editor.GardensStageEditor
|
|||||||
public bool blocksMovement;
|
public bool blocksMovement;
|
||||||
public string notes;
|
public string notes;
|
||||||
|
|
||||||
|
public bool IsResizable => IsKindResizable(kind);
|
||||||
|
public Vector2Int DefaultSize => GetDefaultSize(kind);
|
||||||
|
public Vector2Int MinSize => GetMinSize(kind);
|
||||||
|
public Vector2Int MaxSize => GetMaxSize(kind);
|
||||||
|
|
||||||
public RectInt Bounds => new(x, y, Mathf.Max(1, width), Mathf.Max(1, height));
|
public RectInt Bounds => new(x, y, Mathf.Max(1, width), Mathf.Max(1, height));
|
||||||
|
|
||||||
public bool ContainsCell(int cellX, int cellY)
|
public bool ContainsCell(int cellX, int cellY)
|
||||||
@ -276,5 +292,62 @@ namespace Editor.GardensStageEditor
|
|||||||
var bounds = Bounds;
|
var bounds = Bounds;
|
||||||
return cellX >= bounds.xMin && cellX < bounds.xMax && cellY >= bounds.yMin && cellY < bounds.yMax;
|
return cellX >= bounds.xMin && cellX < bounds.xMax && cellY >= bounds.yMin && cellY < bounds.yMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void NormalizeSize()
|
||||||
|
{
|
||||||
|
if (!IsResizable)
|
||||||
|
{
|
||||||
|
var fixedSize = DefaultSize;
|
||||||
|
width = Mathf.Max(1, fixedSize.x);
|
||||||
|
height = Mathf.Max(1, fixedSize.y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var min = MinSize;
|
||||||
|
var max = MaxSize;
|
||||||
|
width = Mathf.Clamp(Mathf.Max(1, width), Mathf.Max(1, min.x), Mathf.Max(1, max.x));
|
||||||
|
height = Mathf.Clamp(Mathf.Max(1, height), Mathf.Max(1, min.y), Mathf.Max(1, max.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsKindResizable(StageObjectKind kind)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
StageObjectKind.Trap_FallingFloor => true,
|
||||||
|
StageObjectKind.CameraBoundary => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2Int GetDefaultSize(StageObjectKind kind)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
StageObjectKind.Trap_FallingFloor => 2 * Vector2Int.one,
|
||||||
|
StageObjectKind.DoorVertical => new Vector2Int(1, 2),
|
||||||
|
StageObjectKind.DoorHorizontal => new Vector2Int(2, 1),
|
||||||
|
StageObjectKind.CameraBoundary => new Vector2Int(8, 5),
|
||||||
|
_ => Vector2Int.one
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2Int GetMinSize(StageObjectKind kind)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
StageObjectKind.CameraBoundary => new Vector2Int(1, 1),
|
||||||
|
_ => GetDefaultSize(kind)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2Int GetMaxSize(StageObjectKind kind)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
StageObjectKind.Trap_FallingFloor => new Vector2Int(64, 64),
|
||||||
|
StageObjectKind.CameraBoundary => new Vector2Int(64, 64),
|
||||||
|
_ => GetDefaultSize(kind)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using Intrepid.Diagnostics;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Editor.GardensStageEditor
|
namespace Editor.GardensStageEditor
|
||||||
@ -12,12 +13,26 @@ namespace Editor.GardensStageEditor
|
|||||||
public static readonly Color PreviewStroke = new(1f, 1f, 1f, 0.9f);
|
public static readonly Color PreviewStroke = new(1f, 1f, 1f, 0.9f);
|
||||||
public static readonly Color SelectionStroke = new(1f, 0.85f, 0.25f, 1f);
|
public static readonly Color SelectionStroke = new(1f, 0.85f, 0.25f, 1f);
|
||||||
|
|
||||||
|
public static Color FromHtml(string html)
|
||||||
|
{
|
||||||
|
if (!html.StartsWith("#")) html = $"#{html}";
|
||||||
|
if (ColorUtility.TryParseHtmlString(html, out var color))
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
DLogger.LogDebug("color not supported");
|
||||||
|
return Color.magenta;
|
||||||
|
}
|
||||||
|
|
||||||
public static Color Structural(StructuralCellKind kind)
|
public static Color Structural(StructuralCellKind kind)
|
||||||
{
|
{
|
||||||
return kind switch
|
return kind switch
|
||||||
{
|
{
|
||||||
StructuralCellKind.Ground => new Color(0.28f, 0.52f, 0.35f, 0.8f),
|
StructuralCellKind.Ground_Slab => FromHtml("55E0FF"),
|
||||||
StructuralCellKind.Wall => new Color(0.38f, 0.38f, 0.42f, 0.9f),
|
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)
|
_ => new Color(0f, 0f, 0f, 0f)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Intrepid.Gameplay.Prototyping;
|
using System.IO;
|
||||||
|
using Editor.GardensStageEditor.Baker.Editor.GardensStageEditor;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.UIElements;
|
using UnityEditor.UIElements;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -9,6 +11,7 @@ namespace Editor.GardensStageEditor
|
|||||||
{
|
{
|
||||||
public sealed class StageEditorWindow : EditorWindow
|
public sealed class StageEditorWindow : EditorWindow
|
||||||
{
|
{
|
||||||
|
private PrefabTable prefabTable;
|
||||||
private StageDefinition stage;
|
private StageDefinition stage;
|
||||||
private StageEditorState state;
|
private StageEditorState state;
|
||||||
private List<StagePaletteEntry> palette;
|
private List<StagePaletteEntry> palette;
|
||||||
@ -17,6 +20,7 @@ namespace Editor.GardensStageEditor
|
|||||||
private StageMapCanvas canvas;
|
private StageMapCanvas canvas;
|
||||||
private StageInspectorPanel inspector;
|
private StageInspectorPanel inspector;
|
||||||
private StagePalettePanel palettePanel;
|
private StagePalettePanel palettePanel;
|
||||||
|
private Label mouseCellLabel;
|
||||||
|
|
||||||
[MenuItem("Tools/Gardens Of Nil/Stage Editor")]
|
[MenuItem("Tools/Gardens Of Nil/Stage Editor")]
|
||||||
public static void Open()
|
public static void Open()
|
||||||
@ -91,7 +95,7 @@ namespace Editor.GardensStageEditor
|
|||||||
RebuildTopBar();
|
RebuildTopBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MutateStage(string undoName, System.Action mutation)
|
public void MutateStage(string undoName, Action mutation)
|
||||||
{
|
{
|
||||||
if (stage is null || mutation is null)
|
if (stage is null || mutation is null)
|
||||||
{
|
{
|
||||||
@ -119,13 +123,28 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
topBar.Clear();
|
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")
|
var stageField = new ObjectField("Stage")
|
||||||
{
|
{
|
||||||
objectType = typeof(StageDefinition),
|
objectType = typeof(StageDefinition),
|
||||||
value = stage,
|
value = stage,
|
||||||
style =
|
style =
|
||||||
{
|
{
|
||||||
minWidth = 300
|
minWidth = 200
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
stageField.RegisterValueChangedCallback(evt =>
|
stageField.RegisterValueChangedCallback(evt =>
|
||||||
@ -206,18 +225,31 @@ namespace Editor.GardensStageEditor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
topBar.Add(save);
|
topBar.Add(save);
|
||||||
|
|
||||||
|
var bake = new Button(BakeStage)
|
||||||
|
{
|
||||||
|
text = "Bake",
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
marginLeft = 4
|
||||||
|
}
|
||||||
|
};
|
||||||
|
topBar.Add(bake);
|
||||||
}
|
}
|
||||||
|
|
||||||
var spacer = new VisualElement
|
topBar.Add(AddSpacer());
|
||||||
|
|
||||||
|
mouseCellLabel = new Label("Mouse: —")
|
||||||
{
|
{
|
||||||
style =
|
style =
|
||||||
{
|
{
|
||||||
flexGrow = 1f
|
opacity = 0.85f,
|
||||||
|
marginRight = 16f
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
topBar.Add(spacer);
|
topBar.Add(mouseCellLabel);
|
||||||
|
|
||||||
var hint = new Label("Infinite grid · LMB select/place/paint · RMB/MMB pan · Wheel zoom")
|
var hint = new Label("Infinite grid · LMB select/place/paint/move · selected resizable objects have a resize handle · RMB/MMB pan · Wheel zoom")
|
||||||
{
|
{
|
||||||
style =
|
style =
|
||||||
{
|
{
|
||||||
@ -227,6 +259,30 @@ namespace Editor.GardensStageEditor
|
|||||||
topBar.Add(hint);
|
topBar.Add(hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static VisualElement AddSpacer()
|
||||||
|
{
|
||||||
|
return new VisualElement
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
flexGrow = 1f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetMouseCell(Vector2Int? cell)
|
||||||
|
{
|
||||||
|
if (mouseCellLabel is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseCellLabel.text = cell.HasValue
|
||||||
|
? "Mouse: X " + cell.Value.x + " Y " + cell.Value.y
|
||||||
|
: "Mouse: —";
|
||||||
|
}
|
||||||
|
|
||||||
private void SetStage(StageDefinition newStage)
|
private void SetStage(StageDefinition newStage)
|
||||||
{
|
{
|
||||||
stage = newStage;
|
stage = newStage;
|
||||||
@ -238,11 +294,18 @@ namespace Editor.GardensStageEditor
|
|||||||
RebuildTopBar();
|
RebuildTopBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetPrefabTable(PrefabTable newPrefabTable)
|
||||||
|
{
|
||||||
|
prefabTable = newPrefabTable;
|
||||||
|
|
||||||
|
RebuildTopBar();
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateNewStageAsset()
|
private void CreateNewStageAsset()
|
||||||
{
|
{
|
||||||
var path = EditorUtility.SaveFilePanelInProject(
|
var path = EditorUtility.SaveFilePanelInProject(
|
||||||
"Create Stage Definition",
|
"Create Stage Definition",
|
||||||
"StageDefinition",
|
"new-stage.stage-definition",
|
||||||
"asset",
|
"asset",
|
||||||
"Choose where to create the new StageDefinition asset."
|
"Choose where to create the new StageDefinition asset."
|
||||||
);
|
);
|
||||||
@ -253,7 +316,7 @@ namespace Editor.GardensStageEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
var asset = CreateInstance<StageDefinition>();
|
var asset = CreateInstance<StageDefinition>();
|
||||||
asset.stageId = System.IO.Path.GetFileNameWithoutExtension(path).ToLowerInvariant();
|
asset.Id = Path.GetFileNameWithoutExtension(path).ToLowerInvariant();
|
||||||
asset.EnsureDefaults();
|
asset.EnsureDefaults();
|
||||||
|
|
||||||
AssetDatabase.CreateAsset(asset, path);
|
AssetDatabase.CreateAsset(asset, path);
|
||||||
@ -276,7 +339,8 @@ namespace Editor.GardensStageEditor
|
|||||||
var index = stage.floors.Count;
|
var index = stage.floors.Count;
|
||||||
var floor = new StageFloorDefinition
|
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);
|
stage.floors.Add(floor);
|
||||||
@ -291,5 +355,32 @@ namespace Editor.GardensStageEditor
|
|||||||
Debug.Log(report);
|
Debug.Log(report);
|
||||||
EditorUtility.DisplayDialog("Stage Validation", report, "OK");
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,13 +78,6 @@ namespace Editor.GardensStageEditor
|
|||||||
};
|
};
|
||||||
Add(section);
|
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")
|
var cellSize = new FloatField("Cell Size")
|
||||||
{
|
{
|
||||||
value = stage.cellSize
|
value = stage.cellSize
|
||||||
@ -165,13 +158,8 @@ namespace Editor.GardensStageEditor
|
|||||||
id.RegisterValueChangedCallback(evt => owner.MutateStage("Change object id", delegate { obj.id = evt.newValue; }));
|
id.RegisterValueChangedCallback(evt => owner.MutateStage("Change object id", delegate { obj.id = evt.newValue; }));
|
||||||
Add(id);
|
Add(id);
|
||||||
|
|
||||||
var layer = new EnumField("Layer", obj.layer);
|
AddReadOnlyLine("Layer", obj.layer.ToString());
|
||||||
layer.RegisterValueChangedCallback(evt => owner.MutateStage("Change object layer", delegate { obj.layer = (StageLogicalLayer)evt.newValue; }));
|
AddReadOnlyLine("Kind", obj.kind.ToString());
|
||||||
Add(layer);
|
|
||||||
|
|
||||||
var kind = new EnumField("Kind", obj.kind);
|
|
||||||
kind.RegisterValueChangedCallback(evt => owner.MutateStage("Change object kind", delegate { obj.kind = (StageObjectKind)evt.newValue; }));
|
|
||||||
Add(kind);
|
|
||||||
|
|
||||||
var typeId = new TextField("Type Id")
|
var typeId = new TextField("Type Id")
|
||||||
{
|
{
|
||||||
@ -201,19 +189,56 @@ namespace Editor.GardensStageEditor
|
|||||||
y.RegisterValueChangedCallback(evt => owner.MutateStage("Move object y", delegate { obj.y = evt.newValue; }));
|
y.RegisterValueChangedCallback(evt => owner.MutateStage("Move object y", delegate { obj.y = evt.newValue; }));
|
||||||
Add(y);
|
Add(y);
|
||||||
|
|
||||||
|
if (obj.IsResizable)
|
||||||
|
{
|
||||||
|
var min = obj.MinSize;
|
||||||
|
var max = obj.MaxSize;
|
||||||
|
Add(new Label("Resizable: yes · Min " + min.x + "x" + min.y + " · Max " + max.x + "x" + max.y)
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
opacity = 0.75f,
|
||||||
|
marginTop = 4,
|
||||||
|
marginBottom = 2
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var width = new IntegerField("Width")
|
var width = new IntegerField("Width")
|
||||||
{
|
{
|
||||||
value = obj.width
|
value = obj.width
|
||||||
};
|
};
|
||||||
width.RegisterValueChangedCallback(evt => owner.MutateStage("Resize object width", delegate { obj.width = Mathf.Max(1, evt.newValue); }));
|
width.RegisterValueChangedCallback(evt => owner.MutateStage("Resize object width", delegate
|
||||||
|
{
|
||||||
|
obj.width = evt.newValue;
|
||||||
|
obj.NormalizeSize();
|
||||||
|
}));
|
||||||
Add(width);
|
Add(width);
|
||||||
|
|
||||||
var height = new IntegerField("Height")
|
var height = new IntegerField("Height")
|
||||||
{
|
{
|
||||||
value = obj.height
|
value = obj.height
|
||||||
};
|
};
|
||||||
height.RegisterValueChangedCallback(evt => owner.MutateStage("Resize object height", delegate { obj.height = Mathf.Max(1, evt.newValue); }));
|
height.RegisterValueChangedCallback(evt => owner.MutateStage("Resize object height", delegate
|
||||||
|
{
|
||||||
|
obj.height = evt.newValue;
|
||||||
|
obj.NormalizeSize();
|
||||||
|
}));
|
||||||
Add(height);
|
Add(height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var fixedSize = obj.DefaultSize;
|
||||||
|
Add(new Label("Size: " + fixedSize.x + "x" + fixedSize.y + " (fixed)")
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
opacity = 0.75f,
|
||||||
|
marginTop = 4,
|
||||||
|
marginBottom = 2
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Add(new HelpBox("This object kind has a fixed size. It can be moved, but it cannot be resized from the inspector or the grid.", HelpBoxMessageType.Info));
|
||||||
|
}
|
||||||
|
|
||||||
var cutsGround = new Toggle("Cuts Ground")
|
var cutsGround = new Toggle("Cuts Ground")
|
||||||
{
|
{
|
||||||
@ -254,5 +279,39 @@ namespace Editor.GardensStageEditor
|
|||||||
};
|
};
|
||||||
Add(delete);
|
Add(delete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddReadOnlyLine(string label, string value)
|
||||||
|
{
|
||||||
|
var row = new VisualElement
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
flexDirection = FlexDirection.Row,
|
||||||
|
marginTop = 2,
|
||||||
|
marginBottom = 2
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var left = new Label(label)
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
width = 90,
|
||||||
|
opacity = 0.75f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
row.Add(left);
|
||||||
|
|
||||||
|
var right = new Label(value)
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
unityFontStyleAndWeight = FontStyle.Bold
|
||||||
|
}
|
||||||
|
};
|
||||||
|
row.Add(right);
|
||||||
|
|
||||||
|
Add(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UIElements;
|
using UnityEngine.UIElements;
|
||||||
|
|
||||||
@ -7,6 +8,16 @@ namespace Editor.GardensStageEditor
|
|||||||
{
|
{
|
||||||
private const float MinCellPixels = 12f;
|
private const float MinCellPixels = 12f;
|
||||||
private const float MaxCellPixels = 96f;
|
private const float MaxCellPixels = 96f;
|
||||||
|
private const float ResizeHandlePixels = 12f;
|
||||||
|
|
||||||
|
private enum DragMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Pan,
|
||||||
|
Paint,
|
||||||
|
MoveObject,
|
||||||
|
ResizeObject
|
||||||
|
}
|
||||||
|
|
||||||
private readonly StageEditorWindow owner;
|
private readonly StageEditorWindow owner;
|
||||||
private readonly StageEditorState state;
|
private readonly StageEditorState state;
|
||||||
@ -15,12 +26,18 @@ namespace Editor.GardensStageEditor
|
|||||||
private Vector2 pan = new(40f, 40f);
|
private Vector2 pan = new(40f, 40f);
|
||||||
private float cellPixels = 32f;
|
private float cellPixels = 32f;
|
||||||
|
|
||||||
private bool isPanning;
|
private DragMode dragMode = DragMode.None;
|
||||||
private bool isPainting;
|
|
||||||
private Vector2 panStartMouse;
|
private Vector2 panStartMouse;
|
||||||
private Vector2 panStartValue;
|
private Vector2 panStartValue;
|
||||||
private Vector2Int dragStartCell;
|
private Vector2Int dragStartCell;
|
||||||
private Vector2Int dragCurrentCell;
|
private Vector2Int dragCurrentCell;
|
||||||
|
private Vector2Int? hoverCell;
|
||||||
|
|
||||||
|
private StageObjectDefinition draggedObject;
|
||||||
|
private int objectStartX;
|
||||||
|
private int objectStartY;
|
||||||
|
private int objectStartWidth;
|
||||||
|
private int objectStartHeight;
|
||||||
|
|
||||||
public StageMapCanvas(StageEditorWindow owner, StageEditorState state)
|
public StageMapCanvas(StageEditorWindow owner, StageEditorState state)
|
||||||
{
|
{
|
||||||
@ -29,6 +46,7 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
focusable = true;
|
focusable = true;
|
||||||
style.flexGrow = 1f;
|
style.flexGrow = 1f;
|
||||||
|
style.overflow = Overflow.Hidden;
|
||||||
style.backgroundColor = StageEditorColors.Background;
|
style.backgroundColor = StageEditorColors.Background;
|
||||||
|
|
||||||
generateVisualContent += OnGenerateVisualContent;
|
generateVisualContent += OnGenerateVisualContent;
|
||||||
@ -36,6 +54,7 @@ namespace Editor.GardensStageEditor
|
|||||||
RegisterCallback<MouseDownEvent>(OnMouseDown);
|
RegisterCallback<MouseDownEvent>(OnMouseDown);
|
||||||
RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
RegisterCallback<MouseMoveEvent>(OnMouseMove);
|
||||||
RegisterCallback<MouseUpEvent>(OnMouseUp);
|
RegisterCallback<MouseUpEvent>(OnMouseUp);
|
||||||
|
RegisterCallback<MouseLeaveEvent>(OnMouseLeave);
|
||||||
RegisterCallback<WheelEvent>(OnWheel);
|
RegisterCallback<WheelEvent>(OnWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +77,8 @@ namespace Editor.GardensStageEditor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateHoverCell(evt.localMousePosition);
|
||||||
|
|
||||||
var mouse = evt.localMousePosition;
|
var mouse = evt.localMousePosition;
|
||||||
var before = ScreenToGridFloat(mouse);
|
var before = ScreenToGridFloat(mouse);
|
||||||
|
|
||||||
@ -74,6 +95,7 @@ namespace Editor.GardensStageEditor
|
|||||||
private void OnMouseDown(MouseDownEvent evt)
|
private void OnMouseDown(MouseDownEvent evt)
|
||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
|
UpdateHoverCell(evt.localMousePosition);
|
||||||
|
|
||||||
if (stage is null)
|
if (stage is null)
|
||||||
{
|
{
|
||||||
@ -83,10 +105,7 @@ namespace Editor.GardensStageEditor
|
|||||||
// Pan is no longer a palette tool. It is always available through RMB/MMB.
|
// Pan is no longer a palette tool. It is always available through RMB/MMB.
|
||||||
if (evt.button == 2 || evt.button == 1)
|
if (evt.button == 2 || evt.button == 1)
|
||||||
{
|
{
|
||||||
isPanning = true;
|
BeginPan(evt.localMousePosition);
|
||||||
panStartMouse = evt.localMousePosition;
|
|
||||||
panStartValue = pan;
|
|
||||||
this.CaptureMouse();
|
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -96,91 +115,240 @@ namespace Editor.GardensStageEditor
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryScreenToCell(evt.localMousePosition, out Vector2Int cell))
|
if (!TryScreenToCell(evt.localMousePosition, out var cell))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a resizable selected object has its handle clicked, resize wins over move/select.
|
||||||
|
if (TryBeginResizeSelectedObject(evt.localMousePosition, cell))
|
||||||
|
{
|
||||||
|
evt.StopPropagation();
|
||||||
|
MarkDirtyRepaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// LMB always tries to select an existing logical object first.
|
// LMB always tries to select an existing logical object first.
|
||||||
// This removes the need for a Select tool.
|
// If the user drags after selecting/hitting it, the same interaction moves it.
|
||||||
var hit = FindObjectAt(cell, false);
|
var hit = FindObjectAt(cell, false);
|
||||||
if (hit != null)
|
if (hit != null)
|
||||||
{
|
{
|
||||||
state.SelectObject(hit);
|
state.SelectObject(hit);
|
||||||
MarkDirtyRepaint();
|
BeginMoveObject(hit, cell);
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
|
MarkDirtyRepaint();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.SelectObject(null);
|
state.SelectObject(null);
|
||||||
|
|
||||||
// Empty space uses the active palette item to paint/place.
|
// Empty space uses the active palette item to paint/place.
|
||||||
dragStartCell = cell;
|
BeginPaint(cell);
|
||||||
dragCurrentCell = cell;
|
|
||||||
isPainting = true;
|
|
||||||
this.CaptureMouse();
|
|
||||||
|
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
MarkDirtyRepaint();
|
MarkDirtyRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMouseMove(MouseMoveEvent evt)
|
private void OnMouseMove(MouseMoveEvent evt)
|
||||||
{
|
{
|
||||||
if (isPanning)
|
UpdateHoverCell(evt.localMousePosition);
|
||||||
|
|
||||||
|
switch (dragMode)
|
||||||
{
|
{
|
||||||
|
case DragMode.Pan:
|
||||||
pan = panStartValue + evt.localMousePosition - panStartMouse;
|
pan = panStartValue + evt.localMousePosition - panStartMouse;
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
MarkDirtyRepaint();
|
MarkDirtyRepaint();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (isPainting)
|
case DragMode.Paint:
|
||||||
|
if (TryScreenToCell(evt.localMousePosition, out var paintCell))
|
||||||
{
|
{
|
||||||
if (TryScreenToCell(evt.localMousePosition, out Vector2Int cell))
|
dragCurrentCell = paintCell;
|
||||||
{
|
|
||||||
dragCurrentCell = cell;
|
|
||||||
MarkDirtyRepaint();
|
MarkDirtyRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case DragMode.MoveObject:
|
||||||
|
if (TryScreenToCell(evt.localMousePosition, out var moveCell))
|
||||||
|
{
|
||||||
|
ApplyMoveObject(moveCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case DragMode.ResizeObject:
|
||||||
|
if (TryScreenToCell(evt.localMousePosition, out var resizeCell))
|
||||||
|
{
|
||||||
|
ApplyResizeObject(resizeCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
case DragMode.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMouseUp(MouseUpEvent evt)
|
private void OnMouseUp(MouseUpEvent evt)
|
||||||
{
|
{
|
||||||
if (isPanning)
|
switch (dragMode)
|
||||||
{
|
{
|
||||||
isPanning = false;
|
case DragMode.None:
|
||||||
if (this.HasMouseCapture())
|
|
||||||
{
|
|
||||||
this.ReleaseMouse();
|
|
||||||
}
|
|
||||||
|
|
||||||
evt.StopPropagation();
|
|
||||||
return;
|
return;
|
||||||
}
|
case DragMode.Paint when evt.button == 0:
|
||||||
|
|
||||||
if (!isPainting || evt.button != 0)
|
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isPainting = false;
|
|
||||||
if (this.HasMouseCapture())
|
|
||||||
{
|
|
||||||
this.ReleaseMouse();
|
|
||||||
}
|
|
||||||
|
|
||||||
var rect = GetDragRect();
|
var rect = GetDragRect();
|
||||||
ApplyPalette(rect);
|
ApplyPalette(rect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DragMode.Pan:
|
||||||
|
case DragMode.MoveObject:
|
||||||
|
case DragMode.ResizeObject:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndDrag();
|
||||||
evt.StopPropagation();
|
evt.StopPropagation();
|
||||||
MarkDirtyRepaint();
|
MarkDirtyRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnMouseLeave(MouseLeaveEvent evt)
|
||||||
|
{
|
||||||
|
if (!this.HasMouseCapture())
|
||||||
|
{
|
||||||
|
hoverCell = null;
|
||||||
|
owner.SetMouseCell(null);
|
||||||
|
MarkDirtyRepaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginPan(Vector2 mouse)
|
||||||
|
{
|
||||||
|
dragMode = DragMode.Pan;
|
||||||
|
panStartMouse = mouse;
|
||||||
|
panStartValue = pan;
|
||||||
|
this.CaptureMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginPaint(Vector2Int cell)
|
||||||
|
{
|
||||||
|
dragMode = DragMode.Paint;
|
||||||
|
dragStartCell = cell;
|
||||||
|
dragCurrentCell = cell;
|
||||||
|
this.CaptureMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginMoveObject(StageObjectDefinition obj, Vector2Int cell)
|
||||||
|
{
|
||||||
|
dragMode = DragMode.MoveObject;
|
||||||
|
draggedObject = obj;
|
||||||
|
dragStartCell = cell;
|
||||||
|
dragCurrentCell = cell;
|
||||||
|
objectStartX = obj.x;
|
||||||
|
objectStartY = obj.y;
|
||||||
|
objectStartWidth = obj.width;
|
||||||
|
objectStartHeight = obj.height;
|
||||||
|
this.CaptureMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryBeginResizeSelectedObject(Vector2 mouse, Vector2Int cell)
|
||||||
|
{
|
||||||
|
var obj = state.selectedObject;
|
||||||
|
if (obj is null || !CanEditObjectOnActiveFloor(obj) || !obj.IsResizable)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetResizeHandleRect(obj).Contains(mouse))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dragMode = DragMode.ResizeObject;
|
||||||
|
draggedObject = obj;
|
||||||
|
dragStartCell = cell;
|
||||||
|
dragCurrentCell = cell;
|
||||||
|
objectStartX = obj.x;
|
||||||
|
objectStartY = obj.y;
|
||||||
|
objectStartWidth = obj.width;
|
||||||
|
objectStartHeight = obj.height;
|
||||||
|
this.CaptureMouse();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyMoveObject(Vector2Int cell)
|
||||||
|
{
|
||||||
|
if (draggedObject is null || !CanEditObjectOnActiveFloor(draggedObject))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dragCurrentCell = cell;
|
||||||
|
|
||||||
|
var dx = cell.x - dragStartCell.x;
|
||||||
|
var dy = cell.y - dragStartCell.y;
|
||||||
|
var newX = objectStartX + dx;
|
||||||
|
var newY = objectStartY + dy;
|
||||||
|
|
||||||
|
if (draggedObject.x == newX && draggedObject.y == newY)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
owner.MutateStage("Move object", delegate
|
||||||
|
{
|
||||||
|
draggedObject.x = newX;
|
||||||
|
draggedObject.y = newY;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyResizeObject(Vector2Int cell)
|
||||||
|
{
|
||||||
|
if (draggedObject is null || !CanEditObjectOnActiveFloor(draggedObject) || !draggedObject.IsResizable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dragCurrentCell = cell;
|
||||||
|
|
||||||
|
var min = draggedObject.MinSize;
|
||||||
|
var max = draggedObject.MaxSize;
|
||||||
|
var newWidth = Mathf.Clamp(cell.x - objectStartX + 1, Mathf.Max(1, min.x), Mathf.Max(1, max.x));
|
||||||
|
var newHeight = Mathf.Clamp(cell.y - objectStartY + 1, Mathf.Max(1, min.y), Mathf.Max(1, max.y));
|
||||||
|
|
||||||
|
if (draggedObject.width == newWidth && draggedObject.height == newHeight)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
owner.MutateStage("Resize object", delegate
|
||||||
|
{
|
||||||
|
draggedObject.width = newWidth;
|
||||||
|
draggedObject.height = newHeight;
|
||||||
|
draggedObject.NormalizeSize();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndDrag()
|
||||||
|
{
|
||||||
|
dragMode = DragMode.None;
|
||||||
|
draggedObject = null;
|
||||||
|
if (this.HasMouseCapture())
|
||||||
|
{
|
||||||
|
this.ReleaseMouse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplyPalette(RectInt rect)
|
private void ApplyPalette(RectInt rect)
|
||||||
{
|
{
|
||||||
StageFloorDefinition floor = stage?.ActiveFloor;
|
var floor = stage?.ActiveFloor;
|
||||||
if (floor is null)
|
if (floor is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -194,21 +362,12 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
if (entry.paintsStructural)
|
if (entry.paintsStructural)
|
||||||
{
|
{
|
||||||
owner.MutateStage("Paint " + entry.displayName, delegate
|
owner.MutateStage("Paint " + entry.displayName,
|
||||||
{
|
delegate { floor.FillRect(rect, entry.structuralKind); });
|
||||||
floor.FillRect(rect, entry.structuralKind);
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectRect = rect;
|
var objectRect = GetPaletteObjectRect(entry, rect);
|
||||||
if (rect is { width: 1, height: 1 })
|
|
||||||
{
|
|
||||||
objectRect = new RectInt(rect.x, rect.y, Mathf.Max(1, entry.defaultSize.x), Mathf.Max(1, entry.defaultSize.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
objectRect.width = Mathf.Clamp(objectRect.width, Mathf.Max(1, entry.minSize.x), Mathf.Max(1, entry.maxSize.x));
|
|
||||||
objectRect.height = Mathf.Clamp(objectRect.height, Mathf.Max(1, entry.minSize.y), Mathf.Max(1, entry.maxSize.y));
|
|
||||||
|
|
||||||
owner.MutateStage("Place " + entry.displayName, delegate
|
owner.MutateStage("Place " + entry.displayName, delegate
|
||||||
{
|
{
|
||||||
@ -228,11 +387,40 @@ namespace Editor.GardensStageEditor
|
|||||||
blocksMovement = entry.blocksMovement
|
blocksMovement = entry.blocksMovement
|
||||||
};
|
};
|
||||||
|
|
||||||
|
obj.NormalizeSize();
|
||||||
stage.objects.Add(obj);
|
stage.objects.Add(obj);
|
||||||
state.SelectObject(obj);
|
state.SelectObject(obj);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RectInt GetPaletteObjectRect(StagePaletteEntry entry, RectInt paintedRect)
|
||||||
|
{
|
||||||
|
var defaultSize = entry.defaultSize;
|
||||||
|
if (defaultSize.x <= 0 || defaultSize.y <= 0)
|
||||||
|
{
|
||||||
|
defaultSize = StageObjectDefinition.GetDefaultSize(entry.objectKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StageObjectDefinition.IsKindResizable(entry.objectKind))
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
var min = StageObjectDefinition.GetMinSize(entry.objectKind);
|
||||||
|
var max = StageObjectDefinition.GetMaxSize(entry.objectKind);
|
||||||
|
objectRect.width = Mathf.Clamp(objectRect.width, Mathf.Max(1, min.x), Mathf.Max(1, max.x));
|
||||||
|
objectRect.height = Mathf.Clamp(objectRect.height, Mathf.Max(1, min.y), Mathf.Max(1, max.y));
|
||||||
|
return objectRect;
|
||||||
|
}
|
||||||
|
|
||||||
private StageObjectDefinition FindObjectAt(Vector2Int cell, bool activeLayerOnly)
|
private StageObjectDefinition FindObjectAt(Vector2Int cell, bool activeLayerOnly)
|
||||||
{
|
{
|
||||||
if (stage is null)
|
if (stage is null)
|
||||||
@ -263,6 +451,31 @@ namespace Editor.GardensStageEditor
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CanEditObjectOnActiveFloor(StageObjectDefinition obj)
|
||||||
|
{
|
||||||
|
return stage is not null && obj is not null && stage.ActiveFloor is not null &&
|
||||||
|
obj.floorId == stage.ActiveFloor.floorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateHoverCell(Vector2 localMousePosition)
|
||||||
|
{
|
||||||
|
if (stage is null || !TryScreenToCell(localMousePosition, out var cell))
|
||||||
|
{
|
||||||
|
hoverCell = null;
|
||||||
|
owner.SetMouseCell(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hoverCell.HasValue && hoverCell.Value == cell)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverCell = cell;
|
||||||
|
owner.SetMouseCell(cell);
|
||||||
|
MarkDirtyRepaint();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnGenerateVisualContent(MeshGenerationContext mgc)
|
private void OnGenerateVisualContent(MeshGenerationContext mgc)
|
||||||
{
|
{
|
||||||
var p = mgc.painter2D;
|
var p = mgc.painter2D;
|
||||||
@ -281,13 +494,74 @@ namespace Editor.GardensStageEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
DrawInfiniteGrid(p);
|
DrawInfiniteGrid(p);
|
||||||
DrawCells(p, floor);
|
|
||||||
DrawObjects(p, floor.floorId);
|
DrawLowerFloors(p);
|
||||||
|
|
||||||
|
DrawCells(p, floor, 1f);
|
||||||
|
DrawObjects(p, floor.floorId, 1f, true);
|
||||||
|
|
||||||
DrawOriginAxes(p);
|
DrawOriginAxes(p);
|
||||||
|
DrawHoverCell(p);
|
||||||
DrawPreview(p);
|
DrawPreview(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawCells(Painter2D p, StageFloorDefinition floor)
|
private void DrawLowerFloors(Painter2D p)
|
||||||
|
{
|
||||||
|
if (stage is null || stage.floors is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
foreach (var cell in floor.Cells)
|
||||||
{
|
{
|
||||||
@ -297,12 +571,103 @@ namespace Editor.GardensStageEditor
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
color = color.WithAlpha(color.a * alphaMultiplier);
|
||||||
|
|
||||||
var rect = CellRect(cell.x, cell.y);
|
var rect = CellRect(cell.x, cell.y);
|
||||||
FillRect(p, rect, color);
|
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)
|
foreach (var obj in stage.objects)
|
||||||
{
|
{
|
||||||
@ -313,15 +678,89 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
var rect = GridRect(obj.Bounds);
|
var rect = GridRect(obj.Bounds);
|
||||||
var color = StageEditorColors.Layer(obj.layer);
|
var color = StageEditorColors.Layer(obj.layer);
|
||||||
FillRect(p, rect, color);
|
color = color.WithAlpha(color.a * alphaMultiplier);
|
||||||
StrokeRect(p, rect, color.WithAlpha(Mathf.Min(1f, color.a + 0.25f)), 2f);
|
|
||||||
|
|
||||||
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);
|
StrokeRect(p, rect.Expanded(2f), StageEditorColors.SelectionStroke, 3f);
|
||||||
|
|
||||||
|
if (obj.IsResizable)
|
||||||
|
{
|
||||||
|
DrawResizeHandle(p, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
FillRect(p, handle, StageEditorColors.SelectionStroke);
|
||||||
|
StrokeRect(p, handle, Color.black.WithAlpha(0.75f), 1f);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawInfiniteGrid(Painter2D p)
|
private void DrawInfiniteGrid(Painter2D p)
|
||||||
{
|
{
|
||||||
@ -363,9 +802,20 @@ namespace Editor.GardensStageEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawHoverCell(Painter2D p)
|
||||||
|
{
|
||||||
|
if (!hoverCell.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cell = hoverCell.Value;
|
||||||
|
StrokeRect(p, CellRect(cell.x, cell.y).Expanded(-2f), StageEditorColors.PreviewStroke.WithAlpha(0.45f), 1f);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawPreview(Painter2D p)
|
private void DrawPreview(Painter2D p)
|
||||||
{
|
{
|
||||||
if (!isPainting || state.activePaletteEntry is null)
|
if (dragMode != DragMode.Paint || state.activePaletteEntry is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -373,9 +823,9 @@ namespace Editor.GardensStageEditor
|
|||||||
var rect = GetDragRect();
|
var rect = GetDragRect();
|
||||||
var entry = state.activePaletteEntry;
|
var entry = state.activePaletteEntry;
|
||||||
|
|
||||||
if (!entry.paintsStructural && rect is { width: 1, height: 1 })
|
if (!entry.paintsStructural)
|
||||||
{
|
{
|
||||||
rect = new RectInt(rect.x, rect.y, Mathf.Max(1, entry.defaultSize.x), Mathf.Max(1, entry.defaultSize.y));
|
rect = GetPaletteObjectRect(entry, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
var screenRect = GridRect(rect);
|
var screenRect = GridRect(rect);
|
||||||
@ -411,7 +861,15 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
private Rect GridRect(RectInt rect)
|
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)
|
||||||
|
{
|
||||||
|
var rect = GridRect(obj.Bounds);
|
||||||
|
var size = Mathf.Min(ResizeHandlePixels, Mathf.Max(8f, cellPixels * 0.35f));
|
||||||
|
return new Rect(rect.xMax - size, rect.yMax - size, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillRect(Painter2D p, Rect rect, Color color)
|
private void FillRect(Painter2D p, Rect rect, Color color)
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace Editor.GardensStageEditor
|
|||||||
public Vector2Int defaultSize = Vector2Int.one;
|
public Vector2Int defaultSize = Vector2Int.one;
|
||||||
public Vector2Int minSize = Vector2Int.one;
|
public Vector2Int minSize = Vector2Int.one;
|
||||||
public Vector2Int maxSize = new(32, 32);
|
public Vector2Int maxSize = new(32, 32);
|
||||||
public bool resizable = true;
|
public bool resizable;
|
||||||
public bool cutsGround;
|
public bool cutsGround;
|
||||||
public bool blocksMovement;
|
public bool blocksMovement;
|
||||||
|
|
||||||
@ -39,8 +39,20 @@ namespace Editor.GardensStageEditor
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StagePaletteEntry Object(string id, string name, StageLogicalLayer layer, StageObjectKind kind, string typeId, Vector2Int defaultSize)
|
public static StagePaletteEntry Object(
|
||||||
|
string id,
|
||||||
|
string name,
|
||||||
|
StageLogicalLayer layer,
|
||||||
|
StageObjectKind kind,
|
||||||
|
string typeId,
|
||||||
|
Vector2Int defaultSize = default,
|
||||||
|
Vector2Int min = default,
|
||||||
|
Vector2Int max = default)
|
||||||
{
|
{
|
||||||
|
var kindDefault = StageObjectDefinition.GetDefaultSize(kind);
|
||||||
|
var kindMin = StageObjectDefinition.GetMinSize(kind);
|
||||||
|
var kindMax = StageObjectDefinition.GetMaxSize(kind);
|
||||||
|
|
||||||
return new StagePaletteEntry
|
return new StagePaletteEntry
|
||||||
{
|
{
|
||||||
id = id,
|
id = id,
|
||||||
@ -50,10 +62,10 @@ namespace Editor.GardensStageEditor
|
|||||||
objectKind = kind,
|
objectKind = kind,
|
||||||
typeId = typeId,
|
typeId = typeId,
|
||||||
prefabId = string.Empty,
|
prefabId = string.Empty,
|
||||||
defaultSize = defaultSize,
|
defaultSize = defaultSize == default ? kindDefault : defaultSize,
|
||||||
minSize = Vector2Int.one,
|
minSize = min == default ? kindMin : min,
|
||||||
maxSize = new Vector2Int(64, 64),
|
maxSize = max == default ? kindMax : max,
|
||||||
resizable = true
|
resizable = StageObjectDefinition.IsKindResizable(kind)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,26 +73,56 @@ namespace Editor.GardensStageEditor
|
|||||||
{
|
{
|
||||||
var entries = new List<StagePaletteEntry>
|
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_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 trap = Object("trap_falling_floor", "Falling Floor", StageLogicalLayer.Design, StageObjectKind.Trap, "falling_floor", Vector2Int.one);
|
var trapFallingFloor = Object("trap_falling_floor",
|
||||||
trap.cutsGround = true;
|
"Trap (Falling Floor)",
|
||||||
trap.blocksMovement = true;
|
StageLogicalLayer.Design,
|
||||||
entries.Add(trap);
|
StageObjectKind.Trap_FallingFloor,
|
||||||
|
"trap_falling_floor",
|
||||||
|
defaultSize: Vector2Int.one);
|
||||||
|
trapFallingFloor.cutsGround = true;
|
||||||
|
trapFallingFloor.blocksMovement = true;
|
||||||
|
entries.Add(trapFallingFloor);
|
||||||
|
|
||||||
var door = Object("door_standard", "Door", StageLogicalLayer.Design, StageObjectKind.Door, "door_standard", new Vector2Int(1, 2));
|
var doorHorizontal = Object("door_horizontal_standard",
|
||||||
door.blocksMovement = true;
|
"Door Horizontal",
|
||||||
entries.Add(door);
|
StageLogicalLayer.Design,
|
||||||
|
StageObjectKind.DoorHorizontal,
|
||||||
|
"door_horizontal_standard",
|
||||||
|
new Vector2Int(2, 1));
|
||||||
|
doorHorizontal.blocksMovement = true;
|
||||||
|
entries.Add(doorHorizontal);
|
||||||
|
|
||||||
entries.Add(Object("interactable", "Interactable", StageLogicalLayer.Design, StageObjectKind.Interactable, "interactable", Vector2Int.one));
|
var doorVertical = Object("door_vertical_standard",
|
||||||
entries.Add(Object("portal", "Portal", StageLogicalLayer.Design, StageObjectKind.Portal, "portal", new Vector2Int(2, 2)));
|
"Door Vertical",
|
||||||
entries.Add(Object("camera_zone", "Camera Zone", StageLogicalLayer.Camera, StageObjectKind.CameraZone, "camera_zone", new Vector2Int(8, 5)));
|
StageLogicalLayer.Design,
|
||||||
entries.Add(Object("spawn_player", "Player Spawn", StageLogicalLayer.Markers, StageObjectKind.Spawn, "player_spawn", Vector2Int.one));
|
StageObjectKind.DoorVertical,
|
||||||
entries.Add(Object("elevator", "Elevator", StageLogicalLayer.Markers, StageObjectKind.Elevator, "elevator", new Vector2Int(2, 2)));
|
"door_vertical_standard",
|
||||||
entries.Add(Object("marker", "Marker", StageLogicalLayer.Markers, StageObjectKind.Marker, "marker", Vector2Int.one));
|
new Vector2Int(1, 2));
|
||||||
|
doorVertical.blocksMovement = true;
|
||||||
|
entries.Add(doorVertical);
|
||||||
|
|
||||||
|
// entries.Add(Object("interactable", "Interactable", StageLogicalLayer.Design, StageObjectKind.Interactable, "interactable", Vector2Int.one));
|
||||||
|
// entries.Add(Object("portal", "Portal", StageLogicalLayer.Design, StageObjectKind.Portal, "portal", new Vector2Int(2, 2)));
|
||||||
|
entries.Add(Object("camera_boundary",
|
||||||
|
"Camera Boundary",
|
||||||
|
StageLogicalLayer.Camera,
|
||||||
|
StageObjectKind.CameraBoundary,
|
||||||
|
"camera_boundary",
|
||||||
|
defaultSize: new Vector2Int(8, 5),
|
||||||
|
min: new Vector2Int(8, 5)));
|
||||||
|
// entries.Add(Object("spawn_player", "Player Spawn", StageLogicalLayer.Markers, StageObjectKind.Spawn, "player_spawn", Vector2Int.one));
|
||||||
|
// entries.Add(Object("elevator", "Elevator", StageLogicalLayer.Markers, StageObjectKind.Elevator, "elevator", new Vector2Int(2, 2)));
|
||||||
|
// entries.Add(Object("marker", "Marker", StageLogicalLayer.Markers, StageObjectKind.Marker, "marker", Vector2Int.one));
|
||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0e7ed87816264200a12fcc4bf3584153
|
guid: 0e7ed87816264200a12fcc4bf3584153
|
||||||
timeCreated: 1781500522
|
|
||||||
@ -41,11 +41,6 @@ namespace Editor.GardensStageEditor
|
|||||||
|
|
||||||
stage.EnsureDefaults();
|
stage.EnsureDefaults();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(stage.stageId))
|
|
||||||
{
|
|
||||||
messages.Add(new StageValidationMessage(StageValidationSeverity.Warning, "Stage id is empty."));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stage.floors.Count == 0)
|
if (stage.floors.Count == 0)
|
||||||
{
|
{
|
||||||
messages.Add(new StageValidationMessage(StageValidationSeverity.Error, "Stage has no floors."));
|
messages.Add(new StageValidationMessage(StageValidationSeverity.Error, "Stage has no floors."));
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Intrepid.Core.Entities.Messages;
|
using Intrepid.Core.Entities.Messages;
|
||||||
using Intrepid.Core.Grounding;
|
using Intrepid.Core.Grounding;
|
||||||
using Intrepid.Diagnostics;
|
using Intrepid.Diagnostics;
|
||||||
@ -11,6 +12,8 @@ namespace Intrepid.Core.Entities
|
|||||||
{
|
{
|
||||||
public sealed class EntityMotorTopDown : MonoBehaviour
|
public sealed class EntityMotorTopDown : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
private const float FlatGroundNormalThreshold = 0.999f;
|
||||||
|
|
||||||
[GroupInjections, SerializeField] private Entity entity;
|
[GroupInjections, SerializeField] private Entity entity;
|
||||||
[GroupConfigurations, SerializeField] private LayerMask groundMask;
|
[GroupConfigurations, SerializeField] private LayerMask groundMask;
|
||||||
|
|
||||||
@ -29,32 +32,42 @@ namespace Intrepid.Core.Entities
|
|||||||
[GroupConfigurations, SerializeField] private float fallAcceleration = 35f;
|
[GroupConfigurations, SerializeField] private float fallAcceleration = 35f;
|
||||||
[GroupConfigurations, SerializeField] private float maxFallSpeed = 18f;
|
[GroupConfigurations, SerializeField] private float maxFallSpeed = 18f;
|
||||||
|
|
||||||
|
private readonly List<RaycastHit> _groundHits = new(16);
|
||||||
|
private RaycastHit _groundHit;
|
||||||
private Vector3 Origin { get; set; }
|
private Vector3 Origin { get; set; }
|
||||||
private Vector3 End { get; set; }
|
private Vector3 End { get; set; }
|
||||||
private bool HasHit { get; set; }
|
private bool HasHit { get; set; }
|
||||||
private Vector3 _inheritedGroundVelocity;
|
private Vector3 _inheritedGroundVelocity;
|
||||||
private float _fallVerticalSpeed;
|
private float _fallVerticalSpeed;
|
||||||
private RaycastHit _groundHit;
|
|
||||||
private float GroundProbeRadius => IsFalling || IsFallingToAbyss
|
private float GroundProbeRadius => IsFalling || IsFallingToAbyss
|
||||||
? groundProbeRadiusFalling
|
? groundProbeRadiusFalling
|
||||||
: groundProbeRadiusGrounded;
|
: groundProbeRadiusGrounded;
|
||||||
|
|
||||||
public GroundProfiles CurrentGroundProfiles { get; private set; } = GroundProfiles.None;
|
public GroundProfiles CurrentGroundProfiles { get; private set; } = GroundProfiles.None;
|
||||||
public float MaxSlopeAngle => maxSlopeAngle;
|
public float MaxSlopeAngle => maxSlopeAngle;
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public Vector3 LastSafeGroundPosition { get; private set; }
|
public Vector3 LastSafeGroundPosition { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public bool HasStableGroundNormal { get; private set; }
|
public bool HasStableGroundNormal { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public Vector3 StableGroundNormal { get; private set; }
|
public Vector3 StableGroundNormal { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public bool IsFalling { get; private set; }
|
public bool IsFalling { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public bool IsFallingToAbyss { get; private set; }
|
public bool IsFallingToAbyss { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public bool IsGrounded { get; private set; }
|
public bool IsGrounded { get; private set; }
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public Vector3 InheritedGroundVelocity => _inheritedGroundVelocity;
|
public Vector3 InheritedGroundVelocity => _inheritedGroundVelocity;
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly]
|
[GroupDebug, ShowInInspector, ReadOnly]
|
||||||
public float InheritedGroundVelocityTimer { get; private set; }
|
public float InheritedGroundVelocityTimer { get; private set; }
|
||||||
|
|
||||||
@ -370,10 +383,67 @@ namespace Intrepid.Core.Entities
|
|||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProjectVelocityOnPlane(
|
var projectedVelocity = ProjectVelocityOnPlane(
|
||||||
velocity,
|
velocity,
|
||||||
StableGroundNormal
|
StableGroundNormal
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return ApplyGroundMovementProfile(
|
||||||
|
projectedVelocity,
|
||||||
|
StableGroundNormal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 ApplyGroundMovementProfile(
|
||||||
|
Vector3 velocity,
|
||||||
|
Vector3 groundNormal)
|
||||||
|
{
|
||||||
|
if (!IsGrounded || !CurrentGroundProfiles.TryGetGroundProfileMovement(out var movement))
|
||||||
|
{
|
||||||
|
return velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (velocity.sqrMagnitude <= GonConstants.CommonZeroSqrt)
|
||||||
|
{
|
||||||
|
return Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
var downhill = Vector3.ProjectOnPlane(
|
||||||
|
Vector3.down,
|
||||||
|
groundNormal.normalized
|
||||||
|
);
|
||||||
|
|
||||||
|
if (downhill.sqrMagnitude <= GonConstants.CommonZeroSqrt)
|
||||||
|
{
|
||||||
|
return velocity * movement.SpeedMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
downhill.Normalize();
|
||||||
|
|
||||||
|
var moveDirection = velocity.normalized;
|
||||||
|
|
||||||
|
var downhillFactor = Vector3.Dot(moveDirection, downhill);
|
||||||
|
|
||||||
|
float directionalMultiplier;
|
||||||
|
|
||||||
|
if (downhillFactor > 0f)
|
||||||
|
{
|
||||||
|
directionalMultiplier = Mathf.Lerp(
|
||||||
|
movement.SidewaysSpeedMultiplier,
|
||||||
|
movement.DownhillSpeedMultiplier,
|
||||||
|
downhillFactor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directionalMultiplier = Mathf.Lerp(
|
||||||
|
movement.SidewaysSpeedMultiplier,
|
||||||
|
movement.UphillSpeedMultiplier,
|
||||||
|
-downhillFactor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return velocity * (movement.SpeedMultiplier * directionalMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterStableGroundNormal(Vector3 normal)
|
private void RegisterStableGroundNormal(Vector3 normal)
|
||||||
@ -392,55 +462,134 @@ namespace Intrepid.Core.Entities
|
|||||||
return TryGetGroundSurfaceAt(position, out _, out _, out _);
|
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(
|
private bool TryGetGroundSurfaceAt(
|
||||||
Vector3 position,
|
Vector3 position,
|
||||||
out RaycastHit hit,
|
out RaycastHit hit,
|
||||||
out Vector3 normal,
|
out Vector3 normal,
|
||||||
out GroundProfiles groundProfiles)
|
out GroundProfiles groundProfiles)
|
||||||
{
|
{
|
||||||
normal = default;
|
return TryGetBestGroundSurfaceHit(
|
||||||
groundProfiles = GroundProfiles.None;
|
position,
|
||||||
|
groundCheckDistance,
|
||||||
if (!TryGetGroundAt(position, out hit))
|
out hit,
|
||||||
{
|
out normal,
|
||||||
return false;
|
out groundProfiles
|
||||||
}
|
);
|
||||||
|
|
||||||
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 bool TryGetGroundAt(Vector3 position, out RaycastHit hit)
|
private bool TryGetGroundAt(Vector3 position, out RaycastHit hit)
|
||||||
{
|
{
|
||||||
Origin = position + Vector3.up * groundCheckHeight;
|
return TryGetBestGroundSurfaceHit(
|
||||||
End = Origin + Vector3.down * groundCheckDistance;
|
position,
|
||||||
|
|
||||||
HasHit = Physics.SphereCast(
|
|
||||||
Origin,
|
|
||||||
GroundProbeRadius,
|
|
||||||
Vector3.down,
|
|
||||||
out hit,
|
|
||||||
groundCheckDistance,
|
groundCheckDistance,
|
||||||
groundMask,
|
out hit,
|
||||||
QueryTriggerInteraction.Ignore
|
out _,
|
||||||
|
out _
|
||||||
);
|
);
|
||||||
|
|
||||||
return HasHit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryAnyGroundSurfaceBelowAt(
|
private bool TryAnyGroundSurfaceBelowAt(
|
||||||
@ -449,43 +598,18 @@ namespace Intrepid.Core.Entities
|
|||||||
out Vector3 normal,
|
out Vector3 normal,
|
||||||
out GroundProfiles groundProfiles)
|
out GroundProfiles groundProfiles)
|
||||||
{
|
{
|
||||||
normal = default;
|
return TryGetBestGroundSurfaceHit(
|
||||||
groundProfiles = GroundProfiles.None;
|
position,
|
||||||
|
|
||||||
var origin = position + Vector3.up * groundCheckHeight;
|
|
||||||
|
|
||||||
HasHit = Physics.SphereCast(
|
|
||||||
origin,
|
|
||||||
GroundProbeRadius,
|
|
||||||
Vector3.down,
|
|
||||||
out hit,
|
|
||||||
fallingGroundCheckDistance,
|
fallingGroundCheckDistance,
|
||||||
groundMask,
|
out hit,
|
||||||
QueryTriggerInteraction.Ignore
|
out normal,
|
||||||
|
out groundProfiles
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!HasHit)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var surface = hit.collider.GetComponentInParent<GroundSurface>();
|
private static bool IsSlope(Vector3 normal)
|
||||||
|
|
||||||
if (surface.IsNull())
|
|
||||||
{
|
{
|
||||||
return false;
|
return normal.y < FlatGroundNormalThreshold;
|
||||||
}
|
|
||||||
|
|
||||||
normal = surface.Normal;
|
|
||||||
|
|
||||||
if (!IsWalkable(normal))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
groundProfiles = surface.GroundProfiles;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsWalkable(Vector3 normal)
|
private bool IsWalkable(Vector3 normal)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ using Intrepid.Utilities;
|
|||||||
|
|
||||||
namespace Intrepid.Core.Grounding
|
namespace Intrepid.Core.Grounding
|
||||||
{
|
{
|
||||||
public abstract class GroundProfile : Identification
|
public abstract class GroundProfileBehaviour : Identification
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Intrepid.Core.Grounding
|
|
||||||
{
|
|
||||||
public abstract class GroundProfileMotion : GroundProfile
|
|
||||||
{
|
|
||||||
public abstract Vector3 Velocity { get; protected set; }
|
|
||||||
public abstract Vector3 DeltaPosition { get; protected set; }
|
|
||||||
public abstract bool IsMoving { get; protected set; }
|
|
||||||
public abstract bool IsStatic { get; protected set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Intrepid.Core.Grounding
|
||||||
|
{
|
||||||
|
public class GroundProfileMotionBehaviour : GroundProfileBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private GroundProfileMotion groundProfileMotion;
|
||||||
|
|
||||||
|
public GroundProfileMotion GroundProfileMotion => groundProfileMotion;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Intrepid.Core.Grounding
|
||||||
|
{
|
||||||
|
public class GroundProfileMovementBehaviour : GroundProfileBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private GroundProfileMovement groundProfileMovement = GroundProfileMovement.NoModifiers;
|
||||||
|
|
||||||
|
public GroundProfileMovement GroundProfileMovement => groundProfileMovement;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bdd4ad30e2d149b58a2f84fa9a5b5fbc
|
||||||
|
timeCreated: 1781681309
|
||||||
@ -1,19 +1,129 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Intrepid.Utilities;
|
||||||
|
using Sirenix.OdinInspector;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Intrepid.Core.Grounding
|
namespace Intrepid.Core.Grounding
|
||||||
{
|
{
|
||||||
|
[Serializable]
|
||||||
|
public abstract class GroundProfile
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, GroupConfigurations("Motion Profile"), HideLabel]
|
||||||
|
public sealed class GroundProfileMotion : GroundProfile
|
||||||
|
{
|
||||||
|
[SerializeField] private Vector3 velocity;
|
||||||
|
[SerializeField] private Vector3 deltaPosition;
|
||||||
|
[SerializeField] private bool isMoving;
|
||||||
|
[SerializeField] private bool isStatic;
|
||||||
|
|
||||||
|
public Vector3 Velocity
|
||||||
|
{
|
||||||
|
get => velocity;
|
||||||
|
set => velocity = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 DeltaPosition
|
||||||
|
{
|
||||||
|
get => deltaPosition;
|
||||||
|
set => deltaPosition = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsMoving
|
||||||
|
{
|
||||||
|
get => isMoving;
|
||||||
|
set => isMoving = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsStatic
|
||||||
|
{
|
||||||
|
get => isStatic;
|
||||||
|
set => isStatic = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, GroupConfigurations("Movement Profile"), HideLabel]
|
||||||
|
public class GroundProfileMovement : GroundProfile
|
||||||
|
{
|
||||||
|
[SerializeField] private float speedMultiplier;
|
||||||
|
[SerializeField] private float accelerationMultiplier;
|
||||||
|
[SerializeField] private float decelerationMultiplier;
|
||||||
|
[SerializeField] private float uphillSpeedMultiplier;
|
||||||
|
[SerializeField] private float downhillSpeedMultiplier;
|
||||||
|
[SerializeField] private float sidewaysSpeedMultiplier;
|
||||||
|
|
||||||
|
public float SpeedMultiplier
|
||||||
|
{
|
||||||
|
get => speedMultiplier;
|
||||||
|
protected set => speedMultiplier = value;
|
||||||
|
}
|
||||||
|
public float AccelerationMultiplier
|
||||||
|
{
|
||||||
|
get => accelerationMultiplier;
|
||||||
|
protected set => accelerationMultiplier = value;
|
||||||
|
}
|
||||||
|
public float DecelerationMultiplier
|
||||||
|
{
|
||||||
|
get => decelerationMultiplier;
|
||||||
|
protected set => decelerationMultiplier = value;
|
||||||
|
}
|
||||||
|
public float UphillSpeedMultiplier
|
||||||
|
{
|
||||||
|
get => uphillSpeedMultiplier;
|
||||||
|
protected set => uphillSpeedMultiplier = value;
|
||||||
|
}
|
||||||
|
public float DownhillSpeedMultiplier
|
||||||
|
{
|
||||||
|
get => downhillSpeedMultiplier;
|
||||||
|
protected set => downhillSpeedMultiplier = value;
|
||||||
|
}
|
||||||
|
public float SidewaysSpeedMultiplier
|
||||||
|
{
|
||||||
|
get => sidewaysSpeedMultiplier;
|
||||||
|
protected set => sidewaysSpeedMultiplier = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GroundProfileMovement NoModifiers => new()
|
||||||
|
{
|
||||||
|
SpeedMultiplier = 1f,
|
||||||
|
AccelerationMultiplier = 1f,
|
||||||
|
DecelerationMultiplier = 1f,
|
||||||
|
UphillSpeedMultiplier = 1f,
|
||||||
|
DownhillSpeedMultiplier = 1f,
|
||||||
|
SidewaysSpeedMultiplier = 1f,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static GroundProfileMovement operator *(GroundProfileMovement a, GroundProfileMovement b)
|
||||||
|
{
|
||||||
|
return new GroundProfileMovement
|
||||||
|
{
|
||||||
|
SpeedMultiplier = a.SpeedMultiplier * b.SpeedMultiplier,
|
||||||
|
AccelerationMultiplier = a.AccelerationMultiplier * b.AccelerationMultiplier,
|
||||||
|
DecelerationMultiplier = a.DecelerationMultiplier * b.DecelerationMultiplier,
|
||||||
|
UphillSpeedMultiplier = a.UphillSpeedMultiplier * b.UphillSpeedMultiplier,
|
||||||
|
DownhillSpeedMultiplier = a.DownhillSpeedMultiplier * b.DownhillSpeedMultiplier,
|
||||||
|
SidewaysSpeedMultiplier = a.SidewaysSpeedMultiplier * b.SidewaysSpeedMultiplier,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public readonly struct GroundProfiles
|
public readonly struct GroundProfiles
|
||||||
{
|
{
|
||||||
public static readonly GroundProfiles None = new(false);
|
public static readonly GroundProfiles None = new(false);
|
||||||
|
|
||||||
private readonly bool _isSafe;
|
private readonly bool _isSafe;
|
||||||
private GroundProfileMotion GroundProfileMotion { get; }
|
private GroundProfileMotion GroundProfileMotion { get; }
|
||||||
|
private GroundProfileMovement GroundProfileMovement { get; }
|
||||||
public bool IsSafe => CheckIfThisProfileIsSafe();
|
public bool IsSafe => CheckIfThisProfileIsSafe();
|
||||||
|
|
||||||
public GroundProfiles(bool isSafe, GroundProfileMotion groundProfileMotion = null)
|
public GroundProfiles(bool isSafe,
|
||||||
|
GroundProfileMotion groundProfileMotion = null,
|
||||||
|
GroundProfileMovement groundProfileMovement = null)
|
||||||
{
|
{
|
||||||
_isSafe = isSafe;
|
_isSafe = isSafe;
|
||||||
GroundProfileMotion = groundProfileMotion;
|
GroundProfileMotion = groundProfileMotion;
|
||||||
|
GroundProfileMovement = groundProfileMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckIfThisProfileIsSafe()
|
private bool CheckIfThisProfileIsSafe()
|
||||||
@ -28,7 +138,7 @@ namespace Intrepid.Core.Grounding
|
|||||||
|
|
||||||
private bool TryGet<T>(T value, out T profile) where T: GroundProfile
|
private bool TryGet<T>(T value, out T profile) where T: GroundProfile
|
||||||
{
|
{
|
||||||
if (value.IsNull())
|
if (value is null)
|
||||||
{
|
{
|
||||||
profile = null;
|
profile = null;
|
||||||
return false;
|
return false;
|
||||||
@ -42,5 +152,10 @@ namespace Intrepid.Core.Grounding
|
|||||||
{
|
{
|
||||||
return TryGet(GroundProfileMotion, out profile);
|
return TryGet(GroundProfileMotion, out profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetGroundProfileMovement(out GroundProfileMovement profile)
|
||||||
|
{
|
||||||
|
return TryGet(GroundProfileMovement, out profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -13,8 +15,8 @@ namespace Intrepid.Core.Grounding
|
|||||||
{
|
{
|
||||||
[GroupInjections, SerializeField] private BoxCollider boxCollider;
|
[GroupInjections, SerializeField] private BoxCollider boxCollider;
|
||||||
[GroupConfigurations("Profiles"), SerializeField] private bool safe = true;
|
[GroupConfigurations("Profiles"), SerializeField] private bool safe = true;
|
||||||
[GroupConfigurations("Profiles"), SerializeField] private GroundProfileMotion groundProfileMotion;
|
[GroupConfigurations("Profiles"), SerializeField] private GroundProfileMotionBehaviour motionProfile;
|
||||||
|
[GroupConfigurations("Profiles"), SerializeField] private List<GroundProfileMovementBehaviour> movementProfiles = new();
|
||||||
|
|
||||||
[GroupDebug, ShowInInspector, ReadOnly] public Vector3 Position { get; private set; }
|
[GroupDebug, ShowInInspector, ReadOnly] public Vector3 Position { get; private set; }
|
||||||
[GroupDebug, ShowInInspector, ReadOnly] public Vector3 Normal { get; private set; }
|
[GroupDebug, ShowInInspector, ReadOnly] public Vector3 Normal { get; private set; }
|
||||||
@ -38,7 +40,12 @@ namespace Intrepid.Core.Grounding
|
|||||||
[GroupDebug, Button(ButtonSizes.Medium)]
|
[GroupDebug, Button(ButtonSizes.Medium)]
|
||||||
private void RefreshProfiles()
|
private void RefreshProfiles()
|
||||||
{
|
{
|
||||||
GroundProfiles = new GroundProfiles(safe, groundProfileMotion);
|
var groundProfileMovement = movementProfiles.Count == 0
|
||||||
|
? null
|
||||||
|
: movementProfiles
|
||||||
|
.Select(behaviour => behaviour.GroundProfileMovement)
|
||||||
|
.Aggregate(GroundProfileMovement.NoModifiers, (a, b) => a * b);
|
||||||
|
GroundProfiles = new GroundProfiles(safe, motionProfile?.GroundProfileMotion, groundProfileMovement);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Button(ButtonSizes.Medium)]
|
[Button(ButtonSizes.Medium)]
|
||||||
|
|||||||
@ -12,19 +12,24 @@ namespace Intrepid.Gameplay.Prototyping
|
|||||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeX = 1;
|
[GroupConfigurations, SerializeField, ReadOnly] private int sizeX = 1;
|
||||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeY = 1;
|
[GroupConfigurations, SerializeField, ReadOnly] private int sizeY = 1;
|
||||||
[GroupConfigurations, SerializeField, ReadOnly] private int sizeZ = 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 x = 1;
|
||||||
[GroupDebug, SerializeField, Min(1)] private int y = 1;
|
[GroupDebug, SerializeField, Min(1)] private int y = 1;
|
||||||
[GroupDebug, SerializeField, Min(1)] private int z = 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()
|
protected override void DebugResize()
|
||||||
{
|
{
|
||||||
sizeX = Mathf.Max(1, x);
|
sizeX = Mathf.Max(1, x);
|
||||||
sizeY = Mathf.Max(1, y);
|
sizeY = Mathf.Max(1, y);
|
||||||
sizeZ = Mathf.Max(1, z);
|
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()
|
protected override void Generate()
|
||||||
@ -42,8 +47,10 @@ namespace Intrepid.Gameplay.Prototyping
|
|||||||
triangles.ToArray(),
|
triangles.ToArray(),
|
||||||
uvs.ToArray()));
|
uvs.ToArray()));
|
||||||
|
|
||||||
PrototypeModel.BoxCollider.size = new Vector3(sizeX + offset, sizeY, sizeZ + offset);
|
var offsetX = offset_x.x + offset_x.y;
|
||||||
PrototypeModel.BoxCollider.center = Vector3.zero;
|
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);
|
PrototypeModel.transform.localPosition = new Vector3(0f, sizeY / 2f, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Intrepid.Gameplay.Prototyping
|
namespace Intrepid.Gameplay.Prototyping
|
||||||
{
|
{
|
||||||
public abstract class GroundModelPrototype : ModelPrototype
|
public abstract class GroundModelPrototype : ModelPrototype
|
||||||
{
|
{
|
||||||
|
public abstract void SetSize(Vector2Int size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using Sirenix.OdinInspector;
|
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 x = 1;
|
||||||
[GroupDebug, SerializeField, Min(1)] private int z = 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()
|
protected override void DebugResize()
|
||||||
{
|
{
|
||||||
sizeX = Mathf.Max(1, x);
|
sizeX = Mathf.Max(1, x);
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Intrepid.Utilities;
|
using Intrepid.Utilities;
|
||||||
using Sirenix.OdinInspector;
|
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 x = 1;
|
||||||
[GroupDebug, SerializeField, Min(1)] private int z = 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()
|
protected override void DebugResize()
|
||||||
{
|
{
|
||||||
sizeX = Mathf.Max(1, x);
|
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)]
|
[GroupDebug, Button(ButtonSizes.Medium, ButtonStyle.FoldoutButton)]
|
||||||
private void SetSize()
|
protected void SizeFitting()
|
||||||
{
|
{
|
||||||
DebugResize();
|
DebugResize();
|
||||||
if (PrototypeModel.IsNull()) return;
|
if (PrototypeModel.IsNull()) return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user