(25/07/14)hack and slash 공격,피격 판정 아이디어

허윤·2025년 7월 14일

100000개 실행 기준

using System.Collections.Generic;
using System.Diagnostics;
using Unity.VisualScripting;
using UnityEngine;

public class FrameTester : MonoBehaviour
{
    Dictionary<Collider, FrameTester> tester = new();
    Collider cachedCollider;
    FrameTester cachedComp;

    void Start()
    {
        // 자기 자신 등록
        cachedCollider = gameObject.GetComponent<Collider>();
        cachedComp = GetComponent<FrameTester>();
        tester[cachedCollider] = cachedComp;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            RunComparison(new Ray(transform.position, Vector3.up));
        }
    }

    void RunComparison(Ray ray)
    {
        const int len = 100000;
        double gTime = 0;
        double dTime = 0;

        // -----------------------
        // GetComponent 방식
        // -----------------------
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < len; i++)
        {
            if (Physics.Raycast(ray, out var hit, 10f))
            {
                var comp = hit.collider.GetComponent<FrameTester>();
                comp.asdf(1.24f, 45.23f);
            }
        }
        sw.Stop();
        gTime = sw.Elapsed.TotalMilliseconds;
        UnityEngine.Debug.Log($"[GetComponent] {len}회 실행: {gTime} ms");


        // -----------------------
        // Dictionary 방식
        // -----------------------
        sw.Restart();
        for (int i = 0; i < len; i++)
        {
            if (Physics.Raycast(ray, out var hit, 10f))
            {
                if (tester.TryGetValue(hit.collider, out var comp))
                {
                    comp.asdf(1.24f, 45.23f);
                }
            }
        }
        sw.Stop();
        dTime = sw.Elapsed.TotalMilliseconds;
        UnityEngine.Debug.Log($"[Dictionary] {len}회 실행: {dTime} ms");
    }

    public void asdf(float a, float b)
    {
        float result = a * 1210210;
        result -= 21312 * b;
    }
}

테스트코드
GetComponent와 Dictinoary에 캐싱하여 판별하는 케이스
위 테스트 결과에서 20ms 밖에 차이가 안나지만
O(n)인 GetComponent와
O(1)인 딕셔너리를 비교했을때
GetComponent하는 게임오브젝트에 각종 renderer와 animator, navmesh, colider +1(몸통,머리)를 추가 할 시
검색 속도가 더 느려질 것으로 보이므로 GameManager에 캐싱해서 사용하는 방법을 사용
다만 value값에 interface를 사용하는게 메모리와 유지보수측면에서 좋지 않을까 싶다.

profile
C# 클라이언트 프로그래밍 지망

0개의 댓글