diff --git a/Assets/JYY/Animator/PldDogControl.controller b/Assets/JYY/Animator/PldDogControl.controller index afc22279..a67e40bf 100644 --- a/Assets/JYY/Animator/PldDogControl.controller +++ b/Assets/JYY/Animator/PldDogControl.controller @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:456cfb85b82895096e12d09ac206e0afdd9d487c2cce78d73c84693a4883e337 -size 21552 +oid sha256:b9e37c8d0a91f3599d34a7715c632cbcf76fd3c0a96c5d5335ab9d6ff65d3b4c +size 18916 diff --git a/Assets/JYY/Materials.meta b/Assets/JYY/Materials.meta new file mode 100644 index 00000000..566299da --- /dev/null +++ b/Assets/JYY/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2e841b33c73e8fd44a8cf0bc9c1ae488 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Materials/AOE_ShaderGraph.shader b/Assets/JYY/Materials/AOE_ShaderGraph.shader new file mode 100644 index 00000000..0671dc10 --- /dev/null +++ b/Assets/JYY/Materials/AOE_ShaderGraph.shader @@ -0,0 +1,75 @@ +Shader "Unlit/AOE_ShaderGraph" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + _Color ("Color", Color) = (1,1,1,1) + _Radius ("Radius", Range(0,1)) = 0.5 + _Feather ("Feather", Range(0,1)) = 0.1 + } + SubShader + { + Tags { "RenderType"="Transparent" "Queue"="Transparent" } + LOD 100 + Blend SrcAlpha OneMinusSrcAlpha + ZWrite Off + Cull Off + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + // make fog work + #pragma multi_compile_fog + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + UNITY_FOG_COORDS(1) + float4 vertex : SV_POSITION; + }; + + sampler2D _MainTex; + float4 _MainTex_ST; + float4 _Color; + float _Radius; + float _Feather; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.uv, _MainTex); + return o; + } + + fixed4 frag (v2f i) : SV_Target + { + // 중심에서의 거리 계산 + float2 centeredUV = i.uv - 0.5; + float dist = length(centeredUV); + + // 알파 조절: 중심에서 점점 투명 → 가장자리는 불투명 + float alpha = smoothstep(_Radius, _Radius - _Feather, dist); + + // 텍스처 적용 (선택) + fixed4 texCol = tex2D(_MainTex, i.uv); + + // 최종 컬러 (컬러 * 텍스처 * 알파) + fixed4 col = _Color * texCol; + col.a *= alpha; + return col; + } + ENDCG + } + } +} diff --git a/Assets/JYY/Materials/AOE_ShaderGraph.shader.meta b/Assets/JYY/Materials/AOE_ShaderGraph.shader.meta new file mode 100644 index 00000000..a5d0b9aa --- /dev/null +++ b/Assets/JYY/Materials/AOE_ShaderGraph.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 048956df0d9d82445bcfc730131181dd +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat b/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat new file mode 100644 index 00000000..e1494460 --- /dev/null +++ b/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f68ca65948709a37c1781fb40ff6ddfe393e145fb5704467abd99e26a297931 +size 978 diff --git a/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat.meta b/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat.meta new file mode 100644 index 00000000..2daff644 --- /dev/null +++ b/Assets/JYY/Materials/Unlit_AOE_ShaderGraph.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 478a013fb343575418a252ed84af0c58 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Prefabs/AOEIndicator.prefab b/Assets/JYY/Prefabs/AOEIndicator.prefab new file mode 100644 index 00000000..6ac5eda7 --- /dev/null +++ b/Assets/JYY/Prefabs/AOEIndicator.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b8cb01bd819acc4a85f049a7fa119e05a3587e1f3b9e88ce1f0f0729a09b326 +size 4274 diff --git a/Assets/JYY/Prefabs/AOEIndicator.prefab.meta b/Assets/JYY/Prefabs/AOEIndicator.prefab.meta new file mode 100644 index 00000000..1d15c4e7 --- /dev/null +++ b/Assets/JYY/Prefabs/AOEIndicator.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9e020ef2784edf4ca2a83ae9e1edefd +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Scenes/MonsterTest.unity b/Assets/JYY/Scenes/MonsterTest.unity index 060987cc..464228ac 100644 --- a/Assets/JYY/Scenes/MonsterTest.unity +++ b/Assets/JYY/Scenes/MonsterTest.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b1c6e41543c3607b246fcee1f2073d80b57afb1b314b1f2bb9aad1e0f168192 -size 95980 +oid sha256:802822f2af6dbca1cd9bc0c4561d270cd3ce198842594476be72b8216d0f51cf +size 99718 diff --git a/Assets/JYY/Sprites.meta b/Assets/JYY/Sprites.meta new file mode 100644 index 00000000..7d7b4b8e --- /dev/null +++ b/Assets/JYY/Sprites.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d7dcd0a2efc35e04287877979738ea37 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JYY/Sprites/AOEIndicator.png b/Assets/JYY/Sprites/AOEIndicator.png new file mode 100644 index 00000000..49dd0124 --- /dev/null +++ b/Assets/JYY/Sprites/AOEIndicator.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d8478323944a513ad2a0ebeacb8e5804080cf2b9b06fa70c3b35bab512586e5 +size 19392 diff --git a/Assets/JYY/Sprites/AOEIndicator.png.meta b/Assets/JYY/Sprites/AOEIndicator.png.meta new file mode 100644 index 00000000..4793f29f --- /dev/null +++ b/Assets/JYY/Sprites/AOEIndicator.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: fab9fda9e2e50b1458af69d2b01d167c +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 2 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Android + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Character/Enemy/EnemyAttackController.cs b/Assets/Scripts/Character/Enemy/EnemyAttackController.cs new file mode 100644 index 00000000..c76dfdea --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyAttackController.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using UnityEngine; + +public class EnemyAttackController : MonoBehaviour +{ + [Header("각종 전조 오브젝트")] + [SerializeField] private GameObject verticalWarningArea; + [SerializeField] private GameObject horizontalWarningArea; + [SerializeField] private GameObject chariotWarningArea; + [SerializeField] private GameObject dynamoWarningArea; + + // 배열에 담아서 관리 + private List warningAreas; + private GameObject _activeArea; + + private void Awake() + { + // Awake 시점에 리스트로 묶어두면 이후 유지보수 편리 + warningAreas = new List() + { + verticalWarningArea, + horizontalWarningArea, + chariotWarningArea, + dynamoWarningArea + }; + } + + // 랜덤 전조 호출 + // 랜덤 전조 호출 + public void TriggerRandomWarning(Vector3 spawnPosition, Quaternion spawnRotation) + { + // 0 ~ Count-1 사이 랜덤 인덱스 + int idx = Random.Range(0, warningAreas.Count); + GameObject selected = warningAreas[idx]; + + // 예시: Instantiate 방식으로 화면에 띄우기 + _activeArea = Instantiate(selected, spawnPosition, spawnRotation); + } + + public void DestroyWarningArea() + { + Destroy(_activeArea); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyAttackController.cs.meta b/Assets/Scripts/Character/Enemy/EnemyAttackController.cs.meta new file mode 100644 index 00000000..b66f8c7e --- /dev/null +++ b/Assets/Scripts/Character/Enemy/EnemyAttackController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6423b2bcccf1448ca438a8e82a79a4cb +timeCreated: 1745149371 \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyController.cs b/Assets/Scripts/Character/Enemy/EnemyController.cs index 611addf7..3f5f69df 100644 --- a/Assets/Scripts/Character/Enemy/EnemyController.cs +++ b/Assets/Scripts/Character/Enemy/EnemyController.cs @@ -6,6 +6,7 @@ public enum EnemyState { None, Idle, Trace, Attack, GetHit, Move, Dead } [RequireComponent(typeof(NavMeshAgent))] [RequireComponent(typeof(Animator))] +[RequireComponent(typeof(EnemyAttackController))] public abstract class EnemyController : CharacterBase { [Header("AI")] @@ -17,6 +18,8 @@ public abstract class EnemyController : CharacterBase public EnemyState CurrentState {get; private set;} + public EnemyAttackController EnemyAttackController { get; private set; } + public float WalkSpeed => walkSpeed; public float RunSpeed => runSpeed; @@ -41,6 +44,7 @@ public abstract class EnemyController : CharacterBase { EnemyAnimator = GetComponent(); Agent = GetComponent(); + EnemyAttackController = GetComponent(); } protected override void Start() diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs index 06c94904..6cc865a5 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateAttack.cs @@ -10,7 +10,7 @@ public class EnemyStateAttack : IEnemyState private EnemyController _enemyController; private Animator _animator; private Coroutine _attackRoutine; - + private EnemyAttackController _enemyAttackController; private enum AttackType { VerticalAttack, // 위에서 아래로 베는 것 @@ -25,7 +25,7 @@ public class EnemyStateAttack : IEnemyState { _enemyController = enemyController; _animator = _enemyController.EnemyAnimator; - + _enemyAttackController = _enemyController.EnemyAttackController; _animator.SetBool(VertiAttack, true); _attackRoutine = _enemyController.StartCoroutine(VerticalAttackSequence()); } @@ -37,21 +37,19 @@ public class EnemyStateAttack : IEnemyState private IEnumerator VerticalAttackSequence() { // 1. 전조 이펙트 생성 - + _enemyAttackController.TriggerRandomWarning(_enemyController.transform.position, _enemyController.transform.rotation); // 2. 검을 들어올림 yield return new WaitForSeconds(3f); // 3. 대기(전조와 검 들어올리는 애니메이션을 위함) - // 4. 전조 제거 - - // 5. 검 휘두르기 + // 4. 검 휘두르기 _animator.SetTrigger(VertiSlash); - - // 6. 공격 판정 발생 + _enemyAttackController.DestroyWarningArea(); + // TODO : 5. 공격 판정 발생 yield return new WaitForSeconds(1f); - // 7. 애니메이션 트리거 종료 -> 애니메이터 상태 머신으로 처리 + // 6. 애니메이션 트리거 종료 -> 애니메이터 상태 머신으로 처리 _enemyController.SetState(EnemyState.Trace); } @@ -64,6 +62,7 @@ public class EnemyStateAttack : IEnemyState } _animator.SetBool(VertiAttack, false); _animator = null; + _enemyAttackController = null; _enemyController = null; } } \ No newline at end of file diff --git a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs index 9b8e7f3f..ae814987 100644 --- a/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs +++ b/Assets/Scripts/Character/Enemy/EnemyState/EnemyStateTrace.cs @@ -50,7 +50,14 @@ public class EnemyStateTrace : IEnemyState { if (_detectPlayerInCircleWaitTime > MaxDetectPlayerInCircleWaitTime) { - _enemyController.Agent.SetDestination(_detectPlayerTransform.position); + // 방향 계산 + Vector3 dirToPlayer = (_detectPlayerTransform.position - _enemyController.transform.position).normalized; + + // 플레이어 방향으로 offset 적용 (예: 1.5m 앞) + Vector3 stopOffset = _detectPlayerTransform.position - dirToPlayer * 1.5f; + + // 목적지 설정 + _enemyController.Agent.SetDestination(stopOffset); _detectPlayerInCircleWaitTime = 0f; }