feat(BT12-Dev): InfiniteHorizontalGround 컴포넌트 신규 (PD 결정 (나)·Background 패턴)
PD: "Background 밑에 GameObject 배치·맵 최하단·맵에 맞게 사이즈 자동" → "(나) 형태로 진행해"
신규 컴포넌트 — Assets/Scripts/Background/InfiniteHorizontalGround.cs:
- InfiniteHorizontalBackground 동일 패턴·BoxCollider 영역 적용
- Start: BoxCollider size.x 측정 + 자식 사본 2개 (Left·Right) 자동 생성
자식 BoxCollider는 부모 Static Rb attachedRigidbody 자동 상속
- LateUpdate: Camera.x 영역 BoxCollider 폭 정수 배수 root reposition
Scene 변경 — GameObject (Layer 0·Static Rb·직전 48109f9):
- pos (0.5,0,10) → (0, -4.62, 0)
Background sprite 최하단 = pos.y(0.5) - height(10.25)/2 = -4.62
- BoxCollider size (1,1) → (53.12, 1.00)
Background sprite width = 26.56 unit × lossyScale 2 (1.7×배경 추가 영역) = 53.12
- InfiniteHorizontalGround 부착
회귀 영역 X:
- KinematicObject Cast — 자식 BoxCollider + 부모 Static Rb 표준 정합
- Wall LayerMask (1<<0) Layer 0 정합
- Composite Level 비활성·Player·Enemy 1.7배·Background reposition Camera.x 동기
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
93856bc92a
commit
832cc07661
|
|
@ -4427,7 +4427,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}
|
||||
|
|
@ -4437,27 +4437,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}
|
||||
|
|
@ -4577,7 +4577,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}
|
||||
|
|
@ -4587,27 +4587,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}
|
||||
|
|
@ -4617,7 +4617,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}
|
||||
|
|
@ -4627,27 +4627,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: []
|
||||
|
|
@ -135712,7 +135712,6 @@ Transform:
|
|||
- {fileID: 554302359}
|
||||
- {fileID: 1377441407}
|
||||
- {fileID: 671227345}
|
||||
- {fileID: 1648360768}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1085714285
|
||||
|
|
@ -142383,7 +142382,8 @@ Transform:
|
|||
m_LocalPosition: {x: 0, y: 0.5, z: 10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Children:
|
||||
- {fileID: 1648360768}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1251841320
|
||||
|
|
@ -300096,6 +300096,7 @@ GameObject:
|
|||
- component: {fileID: 1648360768}
|
||||
- component: {fileID: 1648360770}
|
||||
- component: {fileID: 1648360769}
|
||||
- component: {fileID: 1648360771}
|
||||
m_Layer: 0
|
||||
m_Name: GameObject
|
||||
m_TagString: Untagged
|
||||
|
|
@ -300111,12 +300112,12 @@ Transform:
|
|||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1648360767}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 153, y: -6, z: 0}
|
||||
m_LocalScale: {x: 400, y: 1, z: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: -5.1226563, z: -10}
|
||||
m_LocalScale: {x: 100, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1082779267}
|
||||
m_Father: {fileID: 1251841319}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!61 &1648360769
|
||||
BoxCollider2D:
|
||||
|
|
@ -300162,7 +300163,7 @@ BoxCollider2D:
|
|||
drawMode: 0
|
||||
adaptiveTiling: 0
|
||||
m_AutoTiling: 0
|
||||
m_Size: {x: 1, y: 1}
|
||||
m_Size: {x: 53.12, y: 1}
|
||||
m_EdgeRadius: 0
|
||||
--- !u!50 &1648360770
|
||||
Rigidbody2D:
|
||||
|
|
@ -300191,6 +300192,18 @@ Rigidbody2D:
|
|||
m_SleepingMode: 0
|
||||
m_CollisionDetection: 0
|
||||
m_Constraints: 0
|
||||
--- !u!114 &1648360771
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1648360767}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f210addf0dc44e246b727396fba0b57d, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::EerieVillage.Background.InfiniteHorizontalGround
|
||||
--- !u!1 &1649507902
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace EerieVillage.Background
|
||||
{
|
||||
/// <summary>
|
||||
/// 무한 가로 스크롤 지면 collider — BoxCollider 재활용 reposition 패턴.
|
||||
/// PD 지시 (2026-05-10·결정 "(나) 형태로 진행해"): 맵 최하단 이동 가능 길·맵에 맞게 사이즈 자동.
|
||||
/// InfiniteHorizontalBackground 동일 패턴·BoxCollider 영역 적용.
|
||||
///
|
||||
/// 동작:
|
||||
/// - Start: BoxCollider size.x 측정 + 자식 사본 2개 (Left·Right) BoxCollider 자동 생성.
|
||||
/// 자식 collider는 부모 Static Rb attachedRigidbody 자동 상속 (Unity 2D Physics 표준).
|
||||
/// - LateUpdate: Camera.x 영역 BoxCollider 폭 영역 정수 배수 root reposition.
|
||||
///
|
||||
/// 효율: BoxCollider 1개 + 자식 2개 = 3개·Camera 영역 항상 collide 정합.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(BoxCollider2D))]
|
||||
public class InfiniteHorizontalGround : MonoBehaviour
|
||||
{
|
||||
Transform _camTr;
|
||||
float _colliderWidth;
|
||||
Transform _leftCopy;
|
||||
Transform _rightCopy;
|
||||
|
||||
void Start()
|
||||
{
|
||||
var cam = Camera.main;
|
||||
if (cam == null)
|
||||
{
|
||||
Debug.LogWarning($"[InfiniteHorizontalGround@{name}] Camera.main NULL — disable.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
_camTr = cam.transform;
|
||||
|
||||
var box = GetComponent<BoxCollider2D>();
|
||||
// 월드 단위 BoxCollider 폭 (lossyScale 적용)
|
||||
_colliderWidth = box.size.x * transform.lossyScale.x;
|
||||
if (_colliderWidth <= 0.001f)
|
||||
{
|
||||
Debug.LogWarning($"[InfiniteHorizontalGround@{name}] colliderWidth ~0 — disable.");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 자식 사본 2개 — Left·Right
|
||||
_leftCopy = CreateCopy("Left", -_colliderWidth, box);
|
||||
_rightCopy = CreateCopy("Right", +_colliderWidth, box);
|
||||
}
|
||||
|
||||
Transform CreateCopy(string copyName, float worldOffsetX, BoxCollider2D src)
|
||||
{
|
||||
var copy = new GameObject(copyName);
|
||||
copy.transform.SetParent(transform, false);
|
||||
copy.layer = gameObject.layer;
|
||||
// localPosition은 parent.lossyScale 영향 — local 단위 변환
|
||||
float localOffsetX = worldOffsetX / transform.lossyScale.x;
|
||||
copy.transform.localPosition = new Vector3(localOffsetX, 0f, 0f);
|
||||
copy.transform.localScale = Vector3.one;
|
||||
|
||||
var box = copy.AddComponent<BoxCollider2D>();
|
||||
box.size = src.size;
|
||||
box.offset = src.offset;
|
||||
box.isTrigger = src.isTrigger;
|
||||
box.sharedMaterial = src.sharedMaterial;
|
||||
return copy.transform;
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (_camTr == null) return;
|
||||
|
||||
float dx = _camTr.position.x - transform.position.x;
|
||||
if (Mathf.Abs(dx) >= _colliderWidth)
|
||||
{
|
||||
int n = Mathf.RoundToInt(dx / _colliderWidth);
|
||||
transform.position += new Vector3(n * _colliderWidth, 0f, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f210addf0dc44e246b727396fba0b57d
|
||||
Loading…
Reference in New Issue