From 225b076b62c4ea74475e3f5e77c03b4afbe9eafb Mon Sep 17 00:00:00 2001 From: dal4segno Date: Mon, 16 Feb 2026 09:52:49 +0900 Subject: [PATCH] =?UTF-8?q?=ED=83=80=EC=9B=8C=20=EA=B3=B5=EA=B2=A9=20?= =?UTF-8?q?=EC=8B=9C=20=EA=B3=B5=EA=B2=A9=20=EC=8B=9C=EC=A0=90=20=EB=B0=8F?= =?UTF-8?q?=20=EB=8C=80=EC=83=81=EC=9D=84=20=EC=95=8C=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EC=9D=B4=ED=8E=99=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80(=EC=9E=84=EC=8B=9C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/AutoTargetSystem.cs | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/Assets/Scripts/AutoTargetSystem.cs b/Assets/Scripts/AutoTargetSystem.cs index 7b07161..ccd43ef 100644 --- a/Assets/Scripts/AutoTargetSystem.cs +++ b/Assets/Scripts/AutoTargetSystem.cs @@ -1,3 +1,4 @@ +using System.Collections; using Unity.Netcode; using UnityEngine; @@ -12,6 +13,20 @@ namespace Northbound [Tooltip("탐지할 레이어")] public LayerMask targetLayer = ~0; + [Header("Beam Effect")] + [Tooltip("빔 효과 LineRenderer 프리팹 (없으면 자동 생성)")] + public LineRenderer beamPrefab; + [Tooltip("빔 색상")] + public Color beamColor = Color.red; + [Tooltip("빔 시작 너비")] + public float beamStartWidth = 0.1f; + [Tooltip("빔 끝 너비")] + public float beamEndWidth = 0.05f; + [Tooltip("빔 표시 시간")] + public float beamDuration = 0.15f; + [Tooltip("빔 발사 위치 (null이면 건물 중심)")] + public Transform firePoint; + [Header("Debug")] [Tooltip("디버그 정보 표시")] public bool showDebugInfo = true; @@ -19,6 +34,8 @@ namespace Northbound private Building _building; private ITeamMember _teamMember; private float _lastAttackTime; + private LineRenderer _beamRenderer; + private Coroutine _beamCoroutine; private void Awake() { @@ -128,8 +145,15 @@ namespace Northbound if (damageable != null) { + // 빔 시작점 계산 + Vector3 beamStart = firePoint != null ? firePoint.position : transform.position + Vector3.up * 2f; + Vector3 beamEnd = closestEnemy.transform.position + Vector3.up * 1f; // 타겟 중앙 + damageable.TakeDamage(attackDamage, NetworkObjectId); _lastAttackTime = Time.time; + + // 모든 클라이언트에 빔 효과 표시 + ShowAttackBeamClientRpc(beamStart, beamEnd); var targetTeam = closestEnemy.GetComponent() ?? closestEnemy.GetComponentInParent() ?? @@ -148,6 +172,69 @@ namespace Northbound } } + #region Beam Effect + + /// + /// 빔 효과를 모든 클라이언트에 표시 + /// + [ClientRpc] + private void ShowAttackBeamClientRpc(Vector3 start, Vector3 end) + { + if (_beamCoroutine != null) + { + StopCoroutine(_beamCoroutine); + } + _beamCoroutine = StartCoroutine(ShowBeamCoroutine(start, end)); + } + + private IEnumerator ShowBeamCoroutine(Vector3 start, Vector3 end) + { + // LineRenderer 초기화 + if (_beamRenderer == null) + { + InitializeBeamRenderer(); + } + + if (_beamRenderer != null) + { + _beamRenderer.enabled = true; + _beamRenderer.SetPosition(0, start); + _beamRenderer.SetPosition(1, end); + + yield return new WaitForSeconds(beamDuration); + + _beamRenderer.enabled = false; + } + } + + private void InitializeBeamRenderer() + { + if (beamPrefab != null) + { + // 프리팹 사용 + GameObject beamObj = Instantiate(beamPrefab.gameObject, transform); + _beamRenderer = beamObj.GetComponent(); + } + else + { + // 자동 생성 + GameObject beamObj = new GameObject("AttackBeam"); + beamObj.transform.SetParent(transform); + _beamRenderer = beamObj.AddComponent(); + + // 기본 설정 + _beamRenderer.positionCount = 2; + _beamRenderer.startWidth = beamStartWidth; + _beamRenderer.endWidth = beamEndWidth; + _beamRenderer.material = new Material(Shader.Find("Sprites/Default")); + _beamRenderer.startColor = beamColor; + _beamRenderer.endColor = beamColor; + _beamRenderer.enabled = false; + } + } + + #endregion + private void OnDrawGizmos() { if (_building == null || _building.buildingData == null) return;