Compare commits
10 Commits
81efd62931
...
ef384bf59c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ef384bf59c | ||
![]() |
4a06cc0565 | ||
![]() |
ccf8772ccd | ||
![]() |
d03a4b7892 | ||
![]() |
241a2fc51d | ||
![]() |
1b45fab5eb | ||
![]() |
2c026cae7b | ||
![]() |
70702f3235 | ||
![]() |
0d2a8a5e2c | ||
![]() |
22ad52aa56 |
222581
Assets/01.Scenes/77.SailTest_Ship.unity
Normal file
222581
Assets/01.Scenes/77.SailTest_Ship.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/01.Scenes/77.SailTest_Ship.unity.meta
Normal file
7
Assets/01.Scenes/77.SailTest_Ship.unity.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1f9c7b58d8381495ab544fa0de6c882e
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/0_Voyage.meta
Normal file
8
Assets/0_Voyage.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bfc3da0f817ff4750990fc9bc24c83fb
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/0_Voyage/Ship.meta
Normal file
8
Assets/0_Voyage/Ship.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 188c9014e830549cda5d9f8e516967f7
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/0_Voyage/Ship/Player.meta
Normal file
8
Assets/0_Voyage/Ship/Player.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 38d669123c62042f9ab41e27be00d703
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
307
Assets/0_Voyage/Ship/Player/PlayerShip.prefab
Normal file
307
Assets/0_Voyage/Ship/Player/PlayerShip.prefab
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &1553910019582315619
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 7177504742663284911}
|
||||||
|
- component: {fileID: 1657872600039613395}
|
||||||
|
- component: {fileID: 2479726504690309911}
|
||||||
|
- component: {fileID: -1082383067592254908}
|
||||||
|
- component: {fileID: 7722456790212551628}
|
||||||
|
- component: {fileID: 3140672700990605547}
|
||||||
|
- component: {fileID: 66612183539046142}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: PlayerShip
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &7177504742663284911
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_ConstrainProportionsScale: 0
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 2507610487897935131}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &1657872600039613395
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1b8549feefedd4d37a3936f5a3ae3fb8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
--- !u!114 &2479726504690309911
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 62899f850307741f2a39c98a8b639597, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Actions: {fileID: -944628639613478452, guid: 646f5a2712aec4a0d9492587d23e9584, type: 3}
|
||||||
|
m_NotificationBehavior: 2
|
||||||
|
m_UIInputModule: {fileID: 0}
|
||||||
|
m_DeviceLostEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_DeviceRegainedEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ControlsChangedEvent:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_ActionEvents:
|
||||||
|
- m_PersistentCalls:
|
||||||
|
m_Calls:
|
||||||
|
- m_Target: {fileID: -1082383067592254908}
|
||||||
|
m_TargetAssemblyTypeName: VoyagePlayerShipMovement, Assembly-CSharp
|
||||||
|
m_MethodName: OnMove
|
||||||
|
m_Mode: 0
|
||||||
|
m_Arguments:
|
||||||
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
|
||||||
|
m_IntArgument: 0
|
||||||
|
m_FloatArgument: 0
|
||||||
|
m_StringArgument:
|
||||||
|
m_BoolArgument: 0
|
||||||
|
m_CallState: 2
|
||||||
|
m_ActionId: a55441ed-e841-44cd-9097-5d0193fa406a
|
||||||
|
m_ActionName: 'Voyage/Move[/Keyboard/w,/Keyboard/upArrow,/Keyboard/s,/Keyboard/downArrow,/Keyboard/a,/Keyboard/leftArrow,/Keyboard/d,/Keyboard/rightArrow]'
|
||||||
|
m_NeverAutoSwitchControlSchemes: 0
|
||||||
|
m_DefaultControlScheme:
|
||||||
|
m_DefaultActionMap: Voyage
|
||||||
|
m_SplitScreenIndex: -1
|
||||||
|
m_Camera: {fileID: 0}
|
||||||
|
--- !u!114 &-1082383067592254908
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 2607481b15fd548b18ca4897db56ab3f, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
movementSettings:
|
||||||
|
maxSpeed: 20
|
||||||
|
accelerationRate: 1
|
||||||
|
dragFactor: 0.98
|
||||||
|
minSpeedThreshold: 0.1
|
||||||
|
rotationSettings:
|
||||||
|
maxRotationSpeed: 270
|
||||||
|
minRotationSpeed: 90
|
||||||
|
accelerationRate: 5
|
||||||
|
turnSpeedPenalty: 0.5
|
||||||
|
maxTurnAngle: 180
|
||||||
|
--- !u!114 &7722456790212551628
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a09f8b932e18409aa7f5d2a221921f45, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
meshTransform: {fileID: 2507610487897935131}
|
||||||
|
maxRotationTiltAngle: 15
|
||||||
|
rotationTiltSpeed: 5
|
||||||
|
rotationTiltReturnSpeed: 3
|
||||||
|
angularVelocityMultiplier: 2
|
||||||
|
maxAccelTiltAngle: 15
|
||||||
|
accelTiltForce: 15
|
||||||
|
accelTiltDamping: 0.9
|
||||||
|
accelTiltSpeed: 10
|
||||||
|
springStiffness: 30
|
||||||
|
springDamping: 15
|
||||||
|
minSpeedWaveHeight: 0.2
|
||||||
|
maxSpeedWaveHeight: 0.05
|
||||||
|
baseWaveFrequency: 1
|
||||||
|
speedWaveMultiplier: 5
|
||||||
|
randomWaveOffset: 0.5
|
||||||
|
waveUnitSpeed: 10
|
||||||
|
--- !u!114 &3140672700990605547
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 3d5c5f51b32b4633b887d096554c6cd9, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
settings:
|
||||||
|
showDebugVisuals: 1
|
||||||
|
lineLength: 5
|
||||||
|
lineWidth: 0.1
|
||||||
|
speedLineColor: {r: 0, g: 1, b: 0, a: 1}
|
||||||
|
rotationSpeedLineColor: {r: 1, g: 0, b: 1, a: 1}
|
||||||
|
rotationDeltaLineColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
|
||||||
|
tiltLineColor: {r: 1, g: 0, b: 0, a: 1}
|
||||||
|
waveHeightLineColor: {r: 0, g: 0, b: 1, a: 1}
|
||||||
|
wavePatternLineColor: {r: 0, g: 1, b: 1, a: 1}
|
||||||
|
--- !u!54 &66612183539046142
|
||||||
|
Rigidbody:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1553910019582315619}
|
||||||
|
serializedVersion: 4
|
||||||
|
m_Mass: 1
|
||||||
|
m_Drag: 0
|
||||||
|
m_AngularDrag: 0.05
|
||||||
|
m_CenterOfMass: {x: 0, y: 0, z: 0}
|
||||||
|
m_InertiaTensor: {x: 1, y: 1, z: 1}
|
||||||
|
m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_IncludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ExcludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ImplicitCom: 1
|
||||||
|
m_ImplicitTensor: 1
|
||||||
|
m_UseGravity: 0
|
||||||
|
m_IsKinematic: 0
|
||||||
|
m_Interpolate: 0
|
||||||
|
m_Constraints: 0
|
||||||
|
m_CollisionDetection: 0
|
||||||
|
--- !u!1 &6407855916708530114
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 2507610487897935131}
|
||||||
|
- component: {fileID: 6689194080255194332}
|
||||||
|
- component: {fileID: 9176830315433650152}
|
||||||
|
- component: {fileID: 8182957266188503550}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: Ship_Mesh
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &2507610487897935131
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6407855916708530114}
|
||||||
|
serializedVersion: 2
|
||||||
|
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 2, y: 2, z: 2}
|
||||||
|
m_ConstrainProportionsScale: 1
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 7177504742663284911}
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!33 &6689194080255194332
|
||||||
|
MeshFilter:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6407855916708530114}
|
||||||
|
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||||
|
--- !u!23 &9176830315433650152
|
||||||
|
MeshRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6407855916708530114}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_CastShadows: 1
|
||||||
|
m_ReceiveShadows: 1
|
||||||
|
m_DynamicOccludee: 1
|
||||||
|
m_StaticShadowCaster: 0
|
||||||
|
m_MotionVectors: 1
|
||||||
|
m_LightProbeUsage: 1
|
||||||
|
m_ReflectionProbeUsage: 1
|
||||||
|
m_RayTracingMode: 2
|
||||||
|
m_RayTraceProcedural: 0
|
||||||
|
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||||
|
m_RayTracingAccelStructBuildFlags: 1
|
||||||
|
m_SmallMeshCulling: 1
|
||||||
|
m_RenderingLayerMask: 1
|
||||||
|
m_RendererPriority: 0
|
||||||
|
m_Materials:
|
||||||
|
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
|
||||||
|
m_StaticBatchInfo:
|
||||||
|
firstSubMesh: 0
|
||||||
|
subMeshCount: 0
|
||||||
|
m_StaticBatchRoot: {fileID: 0}
|
||||||
|
m_ProbeAnchor: {fileID: 0}
|
||||||
|
m_LightProbeVolumeOverride: {fileID: 0}
|
||||||
|
m_ScaleInLightmap: 1
|
||||||
|
m_ReceiveGI: 1
|
||||||
|
m_PreserveUVs: 0
|
||||||
|
m_IgnoreNormalsForChartDetection: 0
|
||||||
|
m_ImportantGI: 0
|
||||||
|
m_StitchLightmapSeams: 1
|
||||||
|
m_SelectedEditorRenderState: 3
|
||||||
|
m_MinimumChartSize: 4
|
||||||
|
m_AutoUVMaxDistance: 0.5
|
||||||
|
m_AutoUVMaxAngle: 89
|
||||||
|
m_LightmapParameters: {fileID: 0}
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingLayer: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_AdditionalVertexStreams: {fileID: 0}
|
||||||
|
--- !u!135 &8182957266188503550
|
||||||
|
SphereCollider:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6407855916708530114}
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_IncludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_ExcludeLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 0
|
||||||
|
m_LayerOverridePriority: 0
|
||||||
|
m_IsTrigger: 0
|
||||||
|
m_ProvidesContacts: 0
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 3
|
||||||
|
m_Radius: 0.5
|
||||||
|
m_Center: {x: 0, y: 0, z: 0}
|
7
Assets/0_Voyage/Ship/Player/PlayerShip.prefab.meta
Normal file
7
Assets/0_Voyage/Ship/Player/PlayerShip.prefab.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 983eaf0fdc71247f290f90900181426f
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
144
Assets/0_Voyage/VoyageInputAction.inputactions
Normal file
144
Assets/0_Voyage/VoyageInputAction.inputactions
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
{
|
||||||
|
"name": "VoyageInputAction",
|
||||||
|
"maps": [
|
||||||
|
{
|
||||||
|
"name": "Voyage",
|
||||||
|
"id": "d93e610e-8799-4d7b-a03a-53a7350ea4e3",
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"name": "Move",
|
||||||
|
"type": "Value",
|
||||||
|
"id": "a55441ed-e841-44cd-9097-5d0193fa406a",
|
||||||
|
"expectedControlType": "Vector2",
|
||||||
|
"processors": "",
|
||||||
|
"interactions": "",
|
||||||
|
"initialStateCheck": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "07e2e88b-19a4-492a-bb6e-477a79caf78d",
|
||||||
|
"path": "<Gamepad>/leftStick",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Gamepad",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WASD",
|
||||||
|
"id": "88163144-1dc8-4b91-90b7-480ef0f731ff",
|
||||||
|
"path": "Dpad",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": true,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "5e78c955-772b-4110-b9ec-1d3b1fa4e44d",
|
||||||
|
"path": "<Keyboard>/w",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "up",
|
||||||
|
"id": "d5604539-9a5a-4d07-acd9-70ac31836b9b",
|
||||||
|
"path": "<Keyboard>/upArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "0535b78b-70bb-4cde-a90e-97ed54681107",
|
||||||
|
"path": "<Keyboard>/s",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "down",
|
||||||
|
"id": "59888646-6c80-4780-9988-5c86276440fa",
|
||||||
|
"path": "<Keyboard>/downArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "f5aed17b-d203-4d12-9fed-038a6f77763b",
|
||||||
|
"path": "<Keyboard>/a",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "left",
|
||||||
|
"id": "dcf9672c-0be6-4081-b274-815f47063229",
|
||||||
|
"path": "<Keyboard>/leftArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "38cb85bf-410b-4efa-b236-df3058449b76",
|
||||||
|
"path": "<Keyboard>/d",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "right",
|
||||||
|
"id": "9a2660b3-1aa8-492d-aa54-65d111ef6262",
|
||||||
|
"path": "<Keyboard>/rightArrow",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": ";Keyboard&Mouse",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"id": "e60cbff8-92ff-48f1-9fab-5f36544e0e5f",
|
||||||
|
"path": "<Joystick>/stick",
|
||||||
|
"interactions": "",
|
||||||
|
"processors": "",
|
||||||
|
"groups": "Joystick",
|
||||||
|
"action": "Move",
|
||||||
|
"isComposite": false,
|
||||||
|
"isPartOfComposite": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controlSchemes": []
|
||||||
|
}
|
14
Assets/0_Voyage/VoyageInputAction.inputactions.meta
Normal file
14
Assets/0_Voyage/VoyageInputAction.inputactions.meta
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 646f5a2712aec4a0d9492587d23e9584
|
||||||
|
ScriptedImporter:
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
|
||||||
|
generateWrapperCode: 0
|
||||||
|
wrapperCodePath:
|
||||||
|
wrapperClassName:
|
||||||
|
wrapperCodeNamespace:
|
8
Assets/0_Voyage/_Scripts.meta
Normal file
8
Assets/0_Voyage/_Scripts.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ce5c0d31d260946248ce91fbc8add1d5
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/0_Voyage/_Scripts/Ship.meta
Normal file
8
Assets/0_Voyage/_Scripts/Ship.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 081a0d92d51044bb1b4eafacae9a8e05
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
13
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShip.cs
Normal file
13
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShip.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using Unity.Cinemachine;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Voyage
|
||||||
|
{
|
||||||
|
|
||||||
|
public class VoyagePlayerShip : MonoBehaviour
|
||||||
|
{
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShip.cs.meta
Normal file
2
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShip.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1b8549feefedd4d37a3936f5a3ae3fb8
|
209
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs
Normal file
209
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovement.cs
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 플레이어 배의 기본 이동과 회전을 처리하는 컴포넌트
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(Rigidbody))]
|
||||||
|
public class VoyagePlayerShipMovement : MonoBehaviour
|
||||||
|
{
|
||||||
|
#region Settings
|
||||||
|
[System.Serializable]
|
||||||
|
public class MovementSettings
|
||||||
|
{
|
||||||
|
[Tooltip("배의 최대 이동 속도")]
|
||||||
|
public float maxSpeed = 20f;
|
||||||
|
public float accelerationRate = 1f;
|
||||||
|
public float dragFactor = 0.98f;
|
||||||
|
public float minSpeedThreshold = 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.Serializable]
|
||||||
|
public class RotationSettings
|
||||||
|
{
|
||||||
|
public float maxRotationSpeed = 270f;
|
||||||
|
public float minRotationSpeed = 90f;
|
||||||
|
public float accelerationRate = 5f;
|
||||||
|
[Tooltip("선회 시 감속 정도 (0: 감속 없음, 1: 완전 정지)")]
|
||||||
|
public float turnSpeedPenalty = 0.5f;
|
||||||
|
[Tooltip("최대 감속이 적용되는 각도")]
|
||||||
|
public float maxTurnAngle = 180f;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Inspector Fields
|
||||||
|
[SerializeField]
|
||||||
|
private MovementSettings movementSettings = new();
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private RotationSettings rotationSettings = new();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public Vector2 CurrentInput => currentInput;
|
||||||
|
public float CurrentRotationSpeed => currentRotationSpeed;
|
||||||
|
public float CurrentSpeed => currentSpeed;
|
||||||
|
public float MaxSpeed => movementSettings.maxSpeed;
|
||||||
|
public Vector3 CurrentVelocity => currentVelocity;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Fields
|
||||||
|
private Vector3 currentVelocity;
|
||||||
|
private Vector2 currentInput;
|
||||||
|
private float currentRotationSpeed;
|
||||||
|
private float targetSpeed;
|
||||||
|
private float currentSpeed;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Unity Messages
|
||||||
|
private void FixedUpdate()
|
||||||
|
{
|
||||||
|
UpdateShipMovement();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Methods
|
||||||
|
public void OnMove(InputAction.CallbackContext context)
|
||||||
|
{
|
||||||
|
currentInput = context.ReadValue<Vector2>();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Movement Methods
|
||||||
|
private void UpdateShipMovement()
|
||||||
|
{
|
||||||
|
if (IsMoving())
|
||||||
|
{
|
||||||
|
UpdateMovementWithInput();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DecelerateShip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyDragForce();
|
||||||
|
ApplyFinalMovement();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMovementWithInput()
|
||||||
|
{
|
||||||
|
UpdateSpeed();
|
||||||
|
UpdateRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpeed()
|
||||||
|
{
|
||||||
|
float baseTargetSpeed = CalculateBaseTargetSpeed();
|
||||||
|
float turnPenaltyFactor = CalculateTurnPenaltyFactor();
|
||||||
|
|
||||||
|
targetSpeed = baseTargetSpeed * turnPenaltyFactor;
|
||||||
|
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed,
|
||||||
|
movementSettings.accelerationRate * Time.fixedDeltaTime);
|
||||||
|
|
||||||
|
if (ShouldStop())
|
||||||
|
{
|
||||||
|
StopShip();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVelocityVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotation()
|
||||||
|
{
|
||||||
|
if (!IsMoving()) return;
|
||||||
|
|
||||||
|
Quaternion targetRotation = CalculateTargetRotation();
|
||||||
|
float rotationSpeed = CalculateRotationSpeed();
|
||||||
|
|
||||||
|
ApplyRotation(targetRotation, rotationSpeed);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helper Methods
|
||||||
|
private bool IsMoving()
|
||||||
|
{
|
||||||
|
return currentInput.magnitude > movementSettings.minSpeedThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateBaseTargetSpeed()
|
||||||
|
{
|
||||||
|
return Mathf.Clamp01(currentInput.magnitude) * movementSettings.maxSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateTurnPenaltyFactor()
|
||||||
|
{
|
||||||
|
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
||||||
|
float angleDifference = Vector3.Angle(transform.forward, inputDirection);
|
||||||
|
float penaltyFactor = angleDifference / rotationSettings.maxTurnAngle * rotationSettings.turnSpeedPenalty;
|
||||||
|
|
||||||
|
return Mathf.Clamp01(1f - penaltyFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Quaternion CalculateTargetRotation()
|
||||||
|
{
|
||||||
|
Vector3 inputDirection = new Vector3(currentInput.x, 0, currentInput.y).normalized;
|
||||||
|
return Quaternion.LookRotation(inputDirection, Vector3.up);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateRotationSpeed()
|
||||||
|
{
|
||||||
|
float speedBasedRotation = rotationSettings.maxRotationSpeed * (currentSpeed / movementSettings.maxSpeed);
|
||||||
|
float desiredRotationSpeed = Mathf.Max(speedBasedRotation, rotationSettings.minRotationSpeed);
|
||||||
|
|
||||||
|
return Mathf.Lerp(currentRotationSpeed, desiredRotationSpeed,
|
||||||
|
rotationSettings.accelerationRate * Time.fixedDeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyRotation(Quaternion targetRotation, float rotationSpeed)
|
||||||
|
{
|
||||||
|
currentRotationSpeed = rotationSpeed;
|
||||||
|
transform.rotation = Quaternion.RotateTowards(
|
||||||
|
transform.rotation,
|
||||||
|
targetRotation,
|
||||||
|
rotationSpeed * Time.fixedDeltaTime
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldStop()
|
||||||
|
{
|
||||||
|
return currentSpeed < movementSettings.minSpeedThreshold &&
|
||||||
|
targetSpeed < movementSettings.minSpeedThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopShip()
|
||||||
|
{
|
||||||
|
currentSpeed = 0f;
|
||||||
|
currentVelocity = Vector3.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateVelocityVector()
|
||||||
|
{
|
||||||
|
currentVelocity = transform.forward * currentSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DecelerateShip()
|
||||||
|
{
|
||||||
|
currentSpeed = Mathf.Lerp(currentSpeed, 0f,
|
||||||
|
movementSettings.accelerationRate * Time.fixedDeltaTime);
|
||||||
|
currentRotationSpeed = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyDragForce()
|
||||||
|
{
|
||||||
|
currentSpeed *= movementSettings.dragFactor;
|
||||||
|
if (currentSpeed < movementSettings.minSpeedThreshold)
|
||||||
|
{
|
||||||
|
StopShip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateVelocityVector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyFinalMovement()
|
||||||
|
{
|
||||||
|
transform.position += currentVelocity * Time.fixedDeltaTime;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2607481b15fd548b18ca4897db56ab3f
|
256
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
Normal file
256
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementDebug.cs
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Voyage
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
/// <summary>
|
||||||
|
/// 배의 움직임을 시각적으로 디버깅하기 위한 컴포넌트
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(VoyagePlayerShipMovement))]
|
||||||
|
[RequireComponent(typeof(VoyagePlayerShipMovementVisual))]
|
||||||
|
public class VoyagePlayerShipDebug : MonoBehaviour
|
||||||
|
{
|
||||||
|
#region Debug Settings
|
||||||
|
[System.Serializable]
|
||||||
|
public class DebugSettings
|
||||||
|
{
|
||||||
|
public bool showDebugVisuals = true;
|
||||||
|
public float lineLength = 5f;
|
||||||
|
public float lineWidth = 0.1f;
|
||||||
|
|
||||||
|
[Header("라인 색상")]
|
||||||
|
public Color speedLineColor = Color.green;
|
||||||
|
public Color rotationSpeedLineColor = Color.magenta;
|
||||||
|
public Color rotationDeltaLineColor = Color.yellow;
|
||||||
|
public Color tiltLineColor = Color.red;
|
||||||
|
public Color waveHeightLineColor = Color.blue;
|
||||||
|
public Color wavePatternLineColor = Color.cyan;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SerializeField] private DebugSettings settings = new();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Line Renderers
|
||||||
|
private class DebugLines
|
||||||
|
{
|
||||||
|
public LineRenderer Speed { get; set; }
|
||||||
|
public LineRenderer RotationSpeed { get; set; }
|
||||||
|
public LineRenderer RotationDelta { get; set; }
|
||||||
|
public LineRenderer Tilt { get; set; }
|
||||||
|
public LineRenderer WaveHeight { get; set; }
|
||||||
|
public LineRenderer WavePattern { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private DebugLines lines = new();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Components
|
||||||
|
private VoyagePlayerShipMovement movement;
|
||||||
|
private VoyagePlayerShipMovementVisual movementVisual;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Unity Messages
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (!settings.showDebugVisuals) return;
|
||||||
|
|
||||||
|
InitializeComponents();
|
||||||
|
InitializeDebugLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!settings.showDebugVisuals) return;
|
||||||
|
UpdateAllDebugLines();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Initialization
|
||||||
|
private void InitializeComponents()
|
||||||
|
{
|
||||||
|
movement = GetComponent<VoyagePlayerShipMovement>();
|
||||||
|
movementVisual = GetComponent<VoyagePlayerShipMovementVisual>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeDebugLines()
|
||||||
|
{
|
||||||
|
lines.Speed = CreateLineRenderer("SpeedLine", settings.speedLineColor);
|
||||||
|
lines.RotationSpeed = CreateLineRenderer("RotationSpeedLine", settings.rotationSpeedLineColor);
|
||||||
|
lines.RotationDelta = CreateLineRenderer("RotationDeltaLine", settings.rotationDeltaLineColor);
|
||||||
|
lines.Tilt = CreateLineRenderer("TiltLine", settings.tiltLineColor);
|
||||||
|
lines.WaveHeight = CreateLineRenderer("WaveHeightLine", settings.waveHeightLineColor);
|
||||||
|
lines.WavePattern = CreateLineRenderer("WavePatternLine", settings.wavePatternLineColor, 50);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Line Updates
|
||||||
|
private void UpdateAllDebugLines()
|
||||||
|
{
|
||||||
|
UpdateSpeedLine();
|
||||||
|
UpdateRotationLines();
|
||||||
|
UpdateTiltLine();
|
||||||
|
UpdateWaveVisualization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSpeedLine()
|
||||||
|
{
|
||||||
|
Vector3 start = GetDebugLineStart(1.5f);
|
||||||
|
Vector3 direction = transform.forward * (movement.CurrentSpeed / movement.MaxSpeed);
|
||||||
|
Vector3 end = start + direction * (settings.lineLength * 2f);
|
||||||
|
|
||||||
|
DrawLine(lines.Speed, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotationLines()
|
||||||
|
{
|
||||||
|
UpdateRotationSpeedArc();
|
||||||
|
UpdateRotationDeltaArc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotationSpeedArc()
|
||||||
|
{
|
||||||
|
if (Mathf.Abs(movement.CurrentRotationSpeed) <= 0.1f)
|
||||||
|
{
|
||||||
|
lines.RotationSpeed.positionCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawArc(lines.RotationSpeed,
|
||||||
|
GetDebugLineStart(1.2f),
|
||||||
|
settings.lineLength,
|
||||||
|
movement.CurrentRotationSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRotationDeltaArc()
|
||||||
|
{
|
||||||
|
if (movement.CurrentInput.magnitude <= 0.1f)
|
||||||
|
{
|
||||||
|
lines.RotationDelta.positionCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float deltaAngle = CalculateRotationDeltaAngle();
|
||||||
|
if (Mathf.Abs(deltaAngle) <= 0.1f)
|
||||||
|
{
|
||||||
|
lines.RotationDelta.positionCount = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawArc(lines.RotationDelta,
|
||||||
|
GetDebugLineStart(1.2f),
|
||||||
|
settings.lineLength * 1.05f,
|
||||||
|
deltaAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTiltLine()
|
||||||
|
{
|
||||||
|
Vector3 start = GetDebugLineStart(1.5f);
|
||||||
|
Vector3 tiltDirection = movementVisual.MeshTransform.up;
|
||||||
|
DrawLine(lines.Tilt, start, start + tiltDirection * (settings.lineLength * 0.4f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWaveVisualization()
|
||||||
|
{
|
||||||
|
UpdateWaveHeightLine();
|
||||||
|
UpdateWavePatternLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWaveHeightLine()
|
||||||
|
{
|
||||||
|
// 현재 파도 높이 표시
|
||||||
|
Vector3 waveStart = transform.position + Vector3.up * 1.5f - transform.forward * 1.5f;
|
||||||
|
Vector3 waveEnd = waveStart + Vector3.up * (movementVisual.CurrentWaveHeight * settings.lineLength);
|
||||||
|
DrawLine(lines.WaveHeight, waveStart, waveEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWavePatternLine()
|
||||||
|
{
|
||||||
|
// 파도 패턴 시각화
|
||||||
|
Vector3[] wavePoints = new Vector3[lines.WavePattern.positionCount];
|
||||||
|
float waveLength = settings.lineLength * 2f;
|
||||||
|
|
||||||
|
for (int i = 0; i < wavePoints.Length; i++)
|
||||||
|
{
|
||||||
|
float t = (float)i / (lines.WavePattern.positionCount - 1);
|
||||||
|
float x = t * waveLength - waveLength * 0.5f;
|
||||||
|
float currentSpeedByUnit = movement.CurrentSpeed / movementVisual.WaveUnitSpeed;
|
||||||
|
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
||||||
|
float waveHeight = Mathf.Lerp(movementVisual.MinSpeedWaveHeight, movementVisual.MaxSpeedWaveHeight, currentSpeedByUnit);
|
||||||
|
float y = Mathf.Sin((movementVisual.WaveTime + x) * movementVisual.BaseWaveFrequency) * waveHeight;
|
||||||
|
|
||||||
|
wavePoints[i] = transform.position +
|
||||||
|
Vector3.right * x +
|
||||||
|
Vector3.up * (y + 2f); // 높이 오프셋
|
||||||
|
wavePoints[i] += Vector3.back * 3f + Vector3.down * 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.WavePattern.SetPositions(wavePoints);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helper Methods
|
||||||
|
private Vector3 GetDebugLineStart(float heightOffset)
|
||||||
|
{
|
||||||
|
return transform.position + Vector3.up * heightOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateRotationDeltaAngle()
|
||||||
|
{
|
||||||
|
Vector3 inputDirection = new Vector3(movement.CurrentInput.x, 0, movement.CurrentInput.y).normalized;
|
||||||
|
Quaternion targetRotation = Quaternion.LookRotation(inputDirection, Vector3.up);
|
||||||
|
return Quaternion.Angle(transform.rotation, targetRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawArc(LineRenderer lineRenderer, Vector3 center, float radius, float totalAngle)
|
||||||
|
{
|
||||||
|
const int ArcSegments = 10;
|
||||||
|
Vector3[] arcPoints = new Vector3[ArcSegments];
|
||||||
|
float angleStep = totalAngle / (ArcSegments - 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < ArcSegments; i++)
|
||||||
|
{
|
||||||
|
float angle = angleStep * i;
|
||||||
|
Vector3 point = center + Quaternion.Euler(0, angle, 0) * transform.forward * radius;
|
||||||
|
arcPoints[i] = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineRenderer.positionCount = ArcSegments;
|
||||||
|
lineRenderer.SetPositions(arcPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LineRenderer CreateLineRenderer(string name, Color color, int pointCount = 2)
|
||||||
|
{
|
||||||
|
GameObject lineObj = new GameObject($"Debug_{name}");
|
||||||
|
lineObj.transform.SetParent(transform);
|
||||||
|
|
||||||
|
LineRenderer line = lineObj.AddComponent<LineRenderer>();
|
||||||
|
InitializeLineRenderer(line, color, pointCount);
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeLineRenderer(LineRenderer line, Color color, int pointCount)
|
||||||
|
{
|
||||||
|
line.startWidth = settings.lineWidth;
|
||||||
|
line.endWidth = settings.lineWidth;
|
||||||
|
line.material = new Material(Shader.Find("Universal Render Pipeline/Unlit"));
|
||||||
|
line.startColor = line.endColor = color;
|
||||||
|
line.positionCount = pointCount;
|
||||||
|
|
||||||
|
line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||||
|
line.receiveShadows = false;
|
||||||
|
line.material.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLine(LineRenderer line, Vector3 start, Vector3 end)
|
||||||
|
{
|
||||||
|
if (line is null) return;
|
||||||
|
|
||||||
|
line.positionCount = 2;
|
||||||
|
line.SetPosition(0, start);
|
||||||
|
line.SetPosition(1, end);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3d5c5f51b32b4633b887d096554c6cd9
|
||||||
|
timeCreated: 1752575924
|
224
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementVisual.cs
Normal file
224
Assets/0_Voyage/_Scripts/Ship/VoyagePlayerShipMovementVisual.cs
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[RequireComponent(typeof(VoyagePlayerShipMovement))]
|
||||||
|
public class VoyagePlayerShipMovementVisual : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("메시 설정")]
|
||||||
|
[SerializeField] private Transform meshTransform;
|
||||||
|
public Transform MeshTransform => meshTransform;
|
||||||
|
|
||||||
|
[Header("회전 틸트 설정")]
|
||||||
|
[SerializeField] private float maxRotationTiltAngle = 15f;
|
||||||
|
[SerializeField] private float rotationTiltSpeed = 5f;
|
||||||
|
[SerializeField] private float rotationTiltReturnSpeed = 3f;
|
||||||
|
[SerializeField] private float angularVelocityMultiplier = 2f;
|
||||||
|
|
||||||
|
[Header("가속 틸트 설정")]
|
||||||
|
[SerializeField] private float maxAccelTiltAngle = 15f;
|
||||||
|
[SerializeField] private float accelTiltForce = 15f;
|
||||||
|
[SerializeField] private float accelTiltDamping = 0.9f;
|
||||||
|
[SerializeField] private float accelTiltSpeed = 10f;
|
||||||
|
[SerializeField] private float springStiffness = 30f;
|
||||||
|
[SerializeField] private float springDamping = 15f;
|
||||||
|
|
||||||
|
[Header("파도 효과 설정")]
|
||||||
|
[SerializeField] private float minSpeedWaveHeight = 0.2f;
|
||||||
|
public float MinSpeedWaveHeight => minSpeedWaveHeight;
|
||||||
|
[SerializeField] private float maxSpeedWaveHeight = 0.05f;
|
||||||
|
public float MaxSpeedWaveHeight => maxSpeedWaveHeight;
|
||||||
|
[SerializeField] private float baseWaveFrequency = 1f;
|
||||||
|
public float BaseWaveFrequency => baseWaveFrequency;
|
||||||
|
[SerializeField] private float speedWaveMultiplier = 5f;
|
||||||
|
[SerializeField] private float randomWaveOffset = 0.5f;
|
||||||
|
[SerializeField] private float waveUnitSpeed = 10f;
|
||||||
|
public float WaveUnitSpeed => waveUnitSpeed;
|
||||||
|
|
||||||
|
private VoyagePlayerShipMovement movement;
|
||||||
|
private Quaternion originalMeshRotation;
|
||||||
|
private Vector3 originalMeshPosition;
|
||||||
|
|
||||||
|
// 틸트 관련 변수들
|
||||||
|
private float currentRotationTilt;
|
||||||
|
private float lastRotationY;
|
||||||
|
private float currentAngularVelocity;
|
||||||
|
private float currentAccelTilt;
|
||||||
|
private float accelTiltVelocity;
|
||||||
|
private float prevSpeed;
|
||||||
|
|
||||||
|
// 파도 관련 변수들
|
||||||
|
private float waveTime;
|
||||||
|
public float WaveTime => waveTime;
|
||||||
|
private float waveRandomOffset;
|
||||||
|
private float currentWaveHeight;
|
||||||
|
public float CurrentWaveHeight => currentWaveHeight;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
InitializeComponents();
|
||||||
|
InitializeMeshTransform();
|
||||||
|
InitializeWaveEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Initialization
|
||||||
|
|
||||||
|
private void InitializeWaveEffect()
|
||||||
|
{
|
||||||
|
waveTime = 0f;
|
||||||
|
waveRandomOffset = Random.Range(-randomWaveOffset, randomWaveOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateMeshTransform()
|
||||||
|
{
|
||||||
|
if (Application.isEditor && !Application.isPlaying && meshTransform is null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Mesh Transform을 Inspector에서 할당해주세요.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeMeshTransform()
|
||||||
|
{
|
||||||
|
if (meshTransform is null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Mesh Transform이 할당되지 않았습니다.");
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
originalMeshPosition = meshTransform.localPosition;
|
||||||
|
originalMeshRotation = meshTransform.localRotation;
|
||||||
|
lastRotationY = transform.eulerAngles.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponents()
|
||||||
|
{
|
||||||
|
movement = GetComponent<VoyagePlayerShipMovement>();
|
||||||
|
|
||||||
|
if (meshTransform == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Mesh Transform이 할당되지 않았습니다.");
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
originalMeshPosition = meshTransform.localPosition;
|
||||||
|
originalMeshRotation = meshTransform.localRotation;
|
||||||
|
lastRotationY = transform.eulerAngles.y;
|
||||||
|
waveTime = 0f;
|
||||||
|
waveRandomOffset = Random.Range(-randomWaveOffset, randomWaveOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void FixedUpdate()
|
||||||
|
{
|
||||||
|
if (meshTransform is null) return;
|
||||||
|
|
||||||
|
UpdateMeshRotationTilt();
|
||||||
|
UpdateAccelerationTilt();
|
||||||
|
ApplyMeshTilt();
|
||||||
|
UpdateWaveMotion();
|
||||||
|
ApplyMeshOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
ValidateMeshTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMeshRotationTilt()
|
||||||
|
{
|
||||||
|
if (meshTransform is null) return;
|
||||||
|
|
||||||
|
// 현재 Y축 회전값과 각속도 계산
|
||||||
|
float currentRotationY = transform.eulerAngles.y;
|
||||||
|
float deltaRotation = Mathf.DeltaAngle(lastRotationY, currentRotationY);
|
||||||
|
currentAngularVelocity = deltaRotation / Time.fixedDeltaTime;
|
||||||
|
|
||||||
|
// 목표 틸트 각도 계산
|
||||||
|
float targetTilt = -currentAngularVelocity * angularVelocityMultiplier;
|
||||||
|
targetTilt = Mathf.Clamp(targetTilt, -maxRotationTiltAngle, maxRotationTiltAngle);
|
||||||
|
|
||||||
|
// 틸트 적용 또는 복귀
|
||||||
|
if (Mathf.Abs(currentAngularVelocity) > 0.1f)
|
||||||
|
{
|
||||||
|
currentRotationTilt =
|
||||||
|
Mathf.Lerp(currentRotationTilt, targetTilt, rotationTiltSpeed * Time.fixedDeltaTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 입력이 없을 때는 원래 자세로 천천히 복귀
|
||||||
|
currentRotationTilt = Mathf.Lerp(currentRotationTilt, 0f, rotationTiltReturnSpeed * Time.fixedDeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastRotationY = currentRotationY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateAccelerationTilt()
|
||||||
|
{
|
||||||
|
// 가속도 계산
|
||||||
|
float acceleration = (GetCurrentSpeed() - prevSpeed) / Time.fixedDeltaTime;
|
||||||
|
|
||||||
|
// 스프링 물리 시스템 구현
|
||||||
|
float springForce = -springStiffness * currentAccelTilt; // 복원력
|
||||||
|
float dampingForce = -springDamping * accelTiltVelocity; // 감쇠력
|
||||||
|
float accelerationForce = -acceleration * accelTiltForce; // 가속에 의한 힘
|
||||||
|
|
||||||
|
// 전체 힘 계산
|
||||||
|
float totalForce = springForce + dampingForce + accelerationForce;
|
||||||
|
|
||||||
|
// 가속도 계산 (F = ma, 질량은 1로 가정)
|
||||||
|
float tiltAcceleration = totalForce;
|
||||||
|
|
||||||
|
// 속도 업데이트
|
||||||
|
accelTiltVelocity += tiltAcceleration;
|
||||||
|
accelTiltVelocity *= accelTiltDamping; // 감쇠 적용
|
||||||
|
accelTiltVelocity *= Time.fixedDeltaTime;
|
||||||
|
|
||||||
|
// 위치(각도) 업데이트
|
||||||
|
currentAccelTilt = Mathf.Lerp(currentAccelTilt, currentAccelTilt + accelTiltVelocity,
|
||||||
|
accelTiltSpeed * Time.fixedDeltaTime);
|
||||||
|
currentAccelTilt = Mathf.Clamp(currentAccelTilt, -maxAccelTiltAngle, maxAccelTiltAngle);
|
||||||
|
|
||||||
|
prevSpeed = GetCurrentSpeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyMeshTilt()
|
||||||
|
{
|
||||||
|
if (meshTransform is null) return;
|
||||||
|
|
||||||
|
// 회전 틸트와 가속 틸트를 조합
|
||||||
|
// 메시에 최종 틸트 적용
|
||||||
|
meshTransform.localRotation = originalMeshRotation * Quaternion.Euler(
|
||||||
|
currentAccelTilt, // X축 (가속 틸트)
|
||||||
|
0, // Y축
|
||||||
|
currentRotationTilt // Z축 (회전 틸트)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateWaveMotion()
|
||||||
|
{
|
||||||
|
if (meshTransform is null) return;
|
||||||
|
|
||||||
|
// 현재 속도에 비례하여 파도 주기 조절
|
||||||
|
float waveSpeedFactor = 1f + (GetCurrentSpeed() / waveUnitSpeed) * speedWaveMultiplier;
|
||||||
|
waveTime += Time.fixedDeltaTime * baseWaveFrequency * waveSpeedFactor;
|
||||||
|
float currentSpeedByUnit = GetCurrentSpeed() / waveUnitSpeed;
|
||||||
|
currentSpeedByUnit = Mathf.Clamp01(currentSpeedByUnit);
|
||||||
|
float waveHeight = Mathf.Lerp(minSpeedWaveHeight, maxSpeedWaveHeight, currentSpeedByUnit);
|
||||||
|
|
||||||
|
currentWaveHeight = waveHeight * Mathf.Sin(waveTime + waveRandomOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyMeshOffset()
|
||||||
|
{
|
||||||
|
if (meshTransform is null) return;
|
||||||
|
|
||||||
|
Vector3 position = originalMeshPosition + (Vector3.up * currentWaveHeight);
|
||||||
|
meshTransform.localPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetCurrentSpeed()
|
||||||
|
{
|
||||||
|
return movement.CurrentSpeed;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a09f8b932e18409aa7f5d2a221921f45
|
||||||
|
timeCreated: 1752575398
|
@ -877,7 +877,8 @@ PlayerSettings:
|
|||||||
Android: 1
|
Android: 1
|
||||||
Standalone: 1
|
Standalone: 1
|
||||||
il2cppCompilerConfiguration: {}
|
il2cppCompilerConfiguration: {}
|
||||||
il2cppCodeGeneration: {}
|
il2cppCodeGeneration:
|
||||||
|
Standalone: 1
|
||||||
il2cppStacktraceInformation: {}
|
il2cppStacktraceInformation: {}
|
||||||
managedStrippingLevel:
|
managedStrippingLevel:
|
||||||
Android: 1
|
Android: 1
|
||||||
|
Loading…
Reference in New Issue
Block a user