본문 바로가기

유니티(자료구조2, 형상관리 깃브랜치, 배열 예제_3D_폭탄) _ 멋쟁이사자처럼 유니티 부트캠프 후기 36회차

@salmu2025. 7. 8. 20:01
반응형

[36회차 수업내용] 250708

1.  Git Branch

2. 딕셔너리

3. 해쉬테이블

4. 배열_ 폭탄 실습

 

 

1. 깃 브랜치

: 코드를 변경하거나 새로운 기능을 실험할 때 기존 코드에 영향을 주지 않고 따로 작업할 수 있는 분기점

 

새로운 기능 개발 기존 코드 망치지 않고 기능 개발 가능
버그 수정 버그 수정용 분리된 작업 공간 제공
여러 사람이 동시에 작업 각자 브랜치를 따로 쓰면 충돌 줄일 수 있음
실험/테스트 실험해보고 이상하면 그냥 브랜치 삭제하면 끝

 

 

 

1.1 Brach 수정/ 취소/ 이동 등

    • Ammend: 최근 커밋 수정
    • Undo: 최근 커밋 취소 / 푸시된 커밋은 Undo 불가
    • Checkout : 특정 Commit으로 이동
      • Detached Head - 브랜치가 아닌 특정 커밋을 보고있는 상태
        • HEAD → 브랜치 → 최신 커밋
        • HEAD는 Git에서 “지금 내가 바라보는 커밋“을 가리키는 포인터
        • detached HEAD 상태는 브랜치가 아닌 특정 커밋을 직접 checkout한 상태예요.
    • Revert Changes in Commit : 특정 Commit으로 이동하고 이후 Commit은 삭제 / 명령어는 reset
    • Merge : 특정 Branch로 합치기
    • Rebase : Branch를 흡수 -> 기존 Branch 내역이 사라지기 때문에 흐름을 놓칠 수 있다
      • 한 브랜치의 커밋을 다른 브랜치 위로 재정렬
      • 직선 구조 → 깔끔한 라인
      • 협업 전에는 위험 (Push 후 rebase는 금물)

 

[Merge <-> Rebase]

 

Before 

main 브랜치
A---B---C (main)

feature 브랜치
        \
         D---E (feature)

 

 

Merge

A---B---C----------F (merge 커밋)
        \        /
         D------E (feature)

 

Rebase

main 브랜치
A---B---C (main)

feature 브랜치 (rebased)
             \
              D'---E' (feature)

내용은 같지만 커밋번호(해시)가 다름 D->D' /  브랜치가 마치 처음부터 main 위에서 작업된 것처럼 깔끔하게 정렬됨

 

 

2. 딕셔너리 (Dictionary)

: 키(key)와 값(value)의 쌍으로 이루어진 자료구조

: <TKey, TValue> 제네릭 자료구조

중복 불가, 고유해야 함
중복 가능
순서 보장되지 않음 (해시 테이블 구조를 기반으로 만들어짐 = 정렬된 구조 아님)
성능 키로 값 검색 시 매우 빠름 (해시 기반)

 

Dictionary<string, int> d_nameAges = new Dictionary<string, int>();

//추가
d_nameAges.Add("철수", 10);
d_nameAges.Add("영희", 15);
d_nameAges.Add("동수", 17);
//데이터 출력
int age = d_nameAges["철수"] // Key 값으로 Value를 찾을 수 있음. age = 10 
// string name = d_nameAges[10]; -> Value는 중복 가능하기 때문에 찾을 수 없음.

foreach (var nameAge in d_nameAges)
{
   string str = nameAge.Key + ", " + nameAge.Value;
   Debug.Log(str);
   
    //철수, 10
    //영희, 15
    //동수, 17

}

 

 

 

[데이터가 여러개일때]

using System.Collections.Generic;  // 제네릭 컬렉션(Dictionary 등)을 사용하기 위한 네임스페이스
using UnityEngine;             

public class PersonData
{
    public int age;         // 나이
    public string name;     // 이름
    public float height;    // 키 (cm)
    public float weight;    // 몸무게 (kg)

    // 생성자: 객체 생성 시 모든 필드를 초기화
    public PersonData(int age, string name, float height, float weight)
    {
        this.age = age;         // 매개변수 age를 멤버 변수 age에 할당
        this.name = name;       // 매개변수 name을 멤버 변수 name에 할당
        this.height = height;   // 매개변수 height를 멤버 변수 height에 할당
        this.weight = weight;   // 매개변수 weight를 멤버 변수 weight에 할당
    }
}

// Unity MonoBehaviour를 상속받는 클래스: Unity 생명주기 메서드 사용 가능
public class StudyDictionary : MonoBehaviour
{
    // 사람 이름(string)을 키로 하고, PersonData 객체를 값으로 하는 persons 딕셔너리 선언 및 초기화
    public Dictionary<string, PersonData> persons = new Dictionary<string, PersonData>();

    void Start()
    {
        // persons 딕셔너리에 이름을 키로 하여 PersonData 객체 추가
        persons.Add("철수", new PersonData(10, "철수", 150f, 30f));
        persons.Add("영희", new PersonData(10, "영희", 150f, 30f));
        persons.Add("동수", new PersonData(10, "동수", 150f, 30f));

        // "철수" 키를 통해 PersonData 객체에 접근하여 각각의 필드 출력
        Debug.Log(persons["철수"].age);     // 나이 출력
        Debug.Log(persons["철수"].name);    // 이름 출력
        Debug.Log(persons["철수"].height);  // 키 출력
        Debug.Log(persons["철수"].weight);  // 몸무게 출력
    }
}

 

 

 

3. 해쉬 테이블(Hash Table)

: Dictionary와 유사하지만, 모든 데이터를 <object>로 저장

: 키(Key)와 값(Value) 쌍으로 데이터를 저장

  Dictionary<TKey, TValue> Hashtable
저장 방식 제네릭으로 TKeyTValue 타입 지정 모든 키와 값이 object 타입으로 저장
타입 안정성(Type Safety) 있음 (컴파일 시 타입 검사 가능) 없음 (모든 데이터가 object라서 캐스팅 필요)
성능 더 빠르고 안전 상대적으로 느리고 캐스팅 비용 발생
사용 권장 여부 현대 .NET에서는 Dictionary 사용 권장 레거시 호환용, 현재는 잘 사용하지 않음

 

Hashtable table = new Hashtable();

table["key"] = 123;      // int 저장
table["name"] = "철수"; // string 저장
table[10] = true;        // bool 저장
Hashtable h_nameAges = new Hashtable();  // Hashtable 객체 생성 (키-값 쌍 저장 가능)

// 데이터 추가
h_nameAges["철수"] = 10;                // 키 "철수"에 정수 10 저장
h_nameAges["영수"] = "20";              // 키 "영수"에 문자열 "20" 저장 (타입 다를 수 있음, 비효율적임)

// 데이터 출력 (값을 꺼낼 때는 원래 타입으로 캐스팅 필요)
int score = (int)h_nameAges["철수"];   // "철수" 키의 값을 int 타입으로 변환하여 가져옴

// 키 "Player2"에 해당하는 데이터가 있으면 삭제 (없으면 무시됨)
h_nameAges.Remove("Player2");

// 키 "철수"가 Hashtable에 존재하는지 확인
if (h_nameAges.ContainsKey("철수"))
{
    Debug.Log("HashTable에 철수가 있음.");  // 키가 있을 때 출력
}

 

 

*GetHashCode() : 객체를 빠르게 찾기 위해 생성된 정수형 식별자(해시값)를 반환하는 메서드



 

4. 배열과 레이어 _ 폭탄 실습

 

[bomb]

using System.Collections;
using UnityEngine;

public class Bomb : MonoBehaviour
{
    private Rigidbody bombRb;              // 폭탄의 Rigidbody 컴포넌트
    public float bombTime = 4f;            // 폭발까지 대기 시간 (초)
    public float bombRange = 10f;          // 폭발 반경
    public LayerMask layerMask;            // 폭발 영향을 줄 대상 레이어 설정

    // 시작 시 Rigidbody 컴포넌트 가져오기
    void Awake()
    {
        bombRb = GetComponent<Rigidbody>();
    }

    // 폭탄이 생성되고 일정 시간 후 폭발 실행
    IEnumerator Start()
    {
        yield return new WaitForSeconds(bombTime);  // bombTime초 대기

        BombForce();  // 폭발 효과 실행
    }

    // 폭발 효과 함수
    private void BombForce()
    {
        // 폭발 반경 내에 있는 collider들을 감지
        Collider[] colliders = Physics.OverlapSphere(transform.position, bombRange, layerMask);

        foreach (var collider in colliders)
        {
            Rigidbody rb = collider.GetComponent<Rigidbody>();

            // Rigidbody가 있다면 폭발 힘 적용
            // AddExplosionForce(폭발 파워, 폭발 위치, 폭발 반경, 폭발 반발력)
            rb.AddExplosionForce(100f, transform.position, bombRange, 1f);
        }

        // 폭발 후 이 오브젝트(폭탄) 제거
        Destroy(gameObject);
    }
}

 

 

* Physics.OverlapSphere :

지정한 위치를 중심으로 반지름 범위 안에 있는 Collider들을 감지해서 배열로 반환함.

Collider[] Physics.OverlapSphere(Vector3 position, float radius, int layerMask = Default)

radius = 감지할 범위 반지름

 

 

*AddexplosionForce
 // AddExplosionForce(폭발 파워, 폭발 위치, 폭발 반경, 폭발 반발력)

폭발 반발력 = 위쪽으로 추가로 밀어주는 힘

 

 

[bomb spawner]

using System.Collections;
using UnityEngine;

public class BombSpawner : MonoBehaviour
{
    public GameObject bombPrefab; // 생성할 폭탄 프리팹

    public int rangeX = 5; // X축 생성 범위 (-rangeX ~ +rangeX)
    public int rangeZ = 5; // Z축 생성 범위 (-rangeZ ~ +rangeZ)

    // 게임 시작 시 반복적으로 폭탄 생성
    IEnumerator Start()
    {
        while (true)
        {
            yield return new WaitForSeconds(1f); // 1초 대기
            RespawnBomb(); // 폭탄 생성
        }
    }

    // 무작위 위치에 폭탄 생성
    private void RespawnBomb()
    {
        // X, Z축 무작위 위치 계산
        float ranX = Random.Range(-rangeX, rangeX + 1);
        float ranZ = Random.Range(-rangeZ, rangeZ + 1);
        
        // Y축은 항상 10f로 설정 (하늘 위에서 떨어지도록)
        Vector3 ranPos = new Vector3(ranX, 10f, ranZ);
        
        // 해당 위치에 폭탄 프리팹 생성
        Instantiate(bombPrefab, ranPos, Quaternion.identity);
    }
}

 

 

 

오브젝트의 생성 관리와 코루틴 등의 활용이 많이 익숙해진 것 같다. 깃 형상관리도 추후 팀워크를 할때 유용하게 활용될 점이라 익혀둬야겠다는 생각이 들었다. 자료구조도 흥미로웠고 어떤식으로 활용될지 궁금해졌다.

반응형
salmu
@salmu :: SMU 각종 기록

목차