From a6e168e86be7edc1c42221ff5067ed6d32baccc1 Mon Sep 17 00:00:00 2001 From: swrring Date: Sun, 10 May 2026 16:03:55 +0900 Subject: [PATCH] =?UTF-8?q?fix(BT12-Dev):=20=EB=AC=B4=ED=95=9C=20=EB=B0=B0?= =?UTF-8?q?=EA=B2=BD=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20InfiniteHori?= =?UTF-8?q?zontalBackground=20=E2=80=94=20sprite=20=EC=9E=AC=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=20reposition=20=ED=8C=A8=ED=84=B4=20(PD=20=EC=A7=80?= =?UTF-8?q?=EC=A0=81=20=EC=A0=95=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PD 지적 (2026-05-10): - "단순히 키운거라서 비효율적 — 리소스를 재활용할 수 있는 기능 구현" 본 PM 자성 — 직전 Tiled DrawMode size (500, 7) 영역 단순 영역 영역 메모리·렌더 영역 비효율. 영역 영역 — Camera 영역 영역 영역 sprite 영역 reposition 패턴 (재활용·효율). 신규 컴포넌트 InfiniteHorizontalBackground.cs: - Start — sprite 가로 폭 측정 + 자식 사본 2개 (Left·Right) 영역 영역 영역 영역 → 화면 영역 영역 영역 3 sprite (root + Left + Right) 영역 충분 (sprite > Camera width 정합) - LateUpdate — Camera 영역 영역 영역 영역 sprite 폭 영역 영역 영역 → root 영역 정수 배수 reposition → 자식 사본 영역 영역 영역 영역 따라가 영역 영역 영역 영역 영역 영역 - 효율 — sprite 1개 (Resources 1회·Texture 메모리 재사용)·GameObject 3개 Background_BgImage1 정정: - DrawMode Tiled → Simple (sprite default size·재활용 패턴 정합) - Scale (1.77, 1.77, 1) — Camera height fit - Position (0, 0.5, 10) — World root - InfiniteHorizontalBackground 컴포넌트 부착 MCP Play 검증: - SendMessage("LateUpdate") → bgPos 0 → 188.04 reposition 정합 - Camera 150 → bgChild0 (94.02)·bgChild1 (282.07) — Camera 영역 영역 sprite 3 영역 정합 --- Assets/Scenes/Ingame.unity | 54 +++++++---- .../InfiniteHorizontalBackground.cs | 95 +++++++++++++++++++ .../InfiniteHorizontalBackground.cs.meta | 2 + 3 files changed, 131 insertions(+), 20 deletions(-) create mode 100644 Assets/Scripts/Background/InfiniteHorizontalBackground.cs create mode 100644 Assets/Scripts/Background/InfiniteHorizontalBackground.cs.meta diff --git a/Assets/Scenes/Ingame.unity b/Assets/Scenes/Ingame.unity index 3c99727..d84f587 100644 --- a/Assets/Scenes/Ingame.unity +++ b/Assets/Scenes/Ingame.unity @@ -4447,7 +4447,7 @@ PrefabInstance: - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} @@ -4457,27 +4457,27 @@ PrefabInstance: - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 480 objectReference: {fileID: 0} - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 600 objectReference: {fileID: 0} - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 750 objectReference: {fileID: 0} - target: {fileID: 1561733016117246437, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -300 objectReference: {fileID: 0} - target: {fileID: 3550758221024711263, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} @@ -4597,7 +4597,7 @@ PrefabInstance: - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} @@ -4607,27 +4607,27 @@ PrefabInstance: - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 480 objectReference: {fileID: 0} - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 600 objectReference: {fileID: 0} - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 1260 objectReference: {fileID: 0} - target: {fileID: 6974954132386231314, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -300 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} @@ -4637,7 +4637,7 @@ PrefabInstance: - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMax.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} @@ -4647,27 +4647,27 @@ PrefabInstance: - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchorMin.y - value: 0 + value: 1 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.x - value: 0 + value: 480 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_SizeDelta.y - value: 0 + value: 600 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.x - value: 0 + value: 240 objectReference: {fileID: 0} - target: {fileID: 9212598073689065413, guid: 9071d6ddb5d4f854185629ee1970af50, type: 3} propertyPath: m_AnchoredPosition.y - value: 0 + value: -300 objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] @@ -141782,6 +141782,7 @@ GameObject: m_Component: - component: {fileID: 1251841319} - component: {fileID: 1251841318} + - component: {fileID: 1251841320} m_Layer: 0 m_Name: Background_BgImage1 m_TagString: Untagged @@ -141843,7 +141844,7 @@ SpriteRenderer: m_Color: {r: 1, g: 1, b: 1, a: 1} m_FlipX: 0 m_FlipY: 0 - m_DrawMode: 2 + m_DrawMode: 0 m_Size: {x: 500, y: 7} m_AdaptiveModeThreshold: 0.5 m_SpriteTileMode: 0 @@ -141859,11 +141860,24 @@ Transform: serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0.5, z: 10} - m_LocalScale: {x: 1, y: 1, z: 1} + m_LocalScale: {x: 1.77, y: 1.77, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1251841320 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1251841317} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4de83d4e43dec1541b816717e1fd2afd, type: 3} + m_Name: + m_EditorClassIdentifier: Assembly-CSharp::EerieVillage.Background.InfiniteHorizontalBackground + _childSortingOrderOffset: 0 --- !u!1 &1252911031 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Background/InfiniteHorizontalBackground.cs b/Assets/Scripts/Background/InfiniteHorizontalBackground.cs new file mode 100644 index 0000000..4912de1 --- /dev/null +++ b/Assets/Scripts/Background/InfiniteHorizontalBackground.cs @@ -0,0 +1,95 @@ +using UnityEngine; + +namespace EerieVillage.Background +{ + /// + /// 무한 가로 스크롤 배경 — sprite 재활용 reposition 패턴. + /// PD 지시 (2026-05-10): "리소스를 재활용할 수 있는 기능 — Tiled size 단순 키움 영역 X". + /// + /// 동작: + /// - Start 시점 — sprite 가로 폭 측정 + 자식 사본 2개 (Left·Right) 영역 영역 영역 영역 영역. + /// → 화면 영역 영역 영역 3 sprite (root + Left + Right) 영역 영역 영역 영역 영역. + /// - LateUpdate — Camera 영역 영역 영역 영역 영역 sprite 폭 영역 영역 영역 영역 → root 영역 정수 배수 영역 reposition. + /// → 자식 사본 영역 영역 영역 영역 따라가 영역 영역 영역 영역 영역 영역 영역 영역. + /// + /// 효율: + /// - sprite 영역 1개 (Resources 영역 1회 영역 — Texture 메모리 영역 X·재사용) + /// - GameObject 영역 3개 (root + 2 사본) — Camera 영역 영역 영역 영역 영역 영역 영역 충분. + /// + [RequireComponent(typeof(SpriteRenderer))] + public class InfiniteHorizontalBackground : MonoBehaviour + { + [Tooltip("자식 사본 sortingOrder (root sortingOrder 영역 영역). 영역 영역 영역 영역 0 영역 영역 영역 영역.")] + [SerializeField] int _childSortingOrderOffset = 0; + + Transform _camTr; + float _spriteWidth; + Transform _leftCopy; + Transform _rightCopy; + + void Start() + { + var cam = Camera.main; + if (cam == null) + { + Debug.LogWarning($"[InfiniteHorizontalBackground@{name}] Camera.main NULL — 영역 영역 영역."); + enabled = false; + return; + } + _camTr = cam.transform; + + var sr = GetComponent(); + if (sr.sprite == null) + { + Debug.LogWarning($"[InfiniteHorizontalBackground@{name}] sprite NULL — 영역 영역 영역."); + enabled = false; + return; + } + + // sprite 가로 영역 (월드 단위·scale 영역 영역) + _spriteWidth = sr.sprite.bounds.size.x * transform.lossyScale.x; + if (_spriteWidth <= 0.001f) + { + Debug.LogWarning($"[InfiniteHorizontalBackground@{name}] spriteWidth ~0 — 영역 영역 영역."); + enabled = false; + return; + } + + // 자식 사본 2개 영역 영역 (Left·Right) + _leftCopy = CreateCopy("Left", -_spriteWidth, sr); + _rightCopy = CreateCopy("Right", +_spriteWidth, sr); + } + + Transform CreateCopy(string copyName, float worldOffsetX, SpriteRenderer src) + { + var copy = new GameObject(copyName); + copy.transform.SetParent(transform, false); + // localPosition 영역 — parent.lossyScale 영역 영역 영역. 영역 영역 영역 — local 단위 영역 영역. + float localOffsetX = worldOffsetX / transform.lossyScale.x; + copy.transform.localPosition = new Vector3(localOffsetX, 0f, 0f); + copy.transform.localScale = Vector3.one; + + var sr = copy.AddComponent(); + sr.sprite = src.sprite; + sr.sortingLayerID = src.sortingLayerID; + sr.sortingOrder = src.sortingOrder + _childSortingOrderOffset; + sr.color = src.color; + sr.flipX = src.flipX; + sr.flipY = src.flipY; + return copy.transform; + } + + void LateUpdate() + { + if (_camTr == null) return; + + // Camera 영역 영역 영역 영역 영역 영역 sprite 폭 영역 영역 영역 영역 → root 영역 정수 배수 영역 reposition + float dx = _camTr.position.x - transform.position.x; + if (Mathf.Abs(dx) >= _spriteWidth) + { + int n = Mathf.RoundToInt(dx / _spriteWidth); + transform.position += new Vector3(n * _spriteWidth, 0f, 0f); + } + } + } +} diff --git a/Assets/Scripts/Background/InfiniteHorizontalBackground.cs.meta b/Assets/Scripts/Background/InfiniteHorizontalBackground.cs.meta new file mode 100644 index 0000000..c40b4d2 --- /dev/null +++ b/Assets/Scripts/Background/InfiniteHorizontalBackground.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4de83d4e43dec1541b816717e1fd2afd \ No newline at end of file