JK강재신 / Unity · XR
← 프로젝트 목록

쓰리디아이 / 2020

승마 VR 어트랙션

어린이 체험을 위한 VR 플레이와 점수 시스템

UnityNPC랭킹
프로젝트 연도 / 기록 당시 상태2020
개발팀 · 리소스 인력 제외1인
사용 기술Unity3D · VR

PROJECT IN ACTION

실행 화면과 시연

승마 VR 어트랙션 프로젝트 화면
승마 VR 어트랙션 · 시연 1 프로젝트 이미지
YouTube / PROJECT VIDEO

승마 VR 어트랙션 · 시연 1

직접 열기 ↗
승마 VR 어트랙션 · 시연 2 프로젝트 이미지
YouTube / PROJECT VIDEO

승마 VR 어트랙션 · 시연 2

직접 열기 ↗

OVERVIEW

프로젝트와 나의 역할

공격 NPC, 스테이지별 점수와 로컬 랭킹 저장 기능을 개발했습니다.

  • Enemy NPC 개발
  • Stage 별 Score 및 랭킹 시스템 개발

ENGINEERING NOTES

기능별 구현과 문제 해결

담당 기능의 배경부터 구현 방식과 선택한 범위까지 정리했습니다.

01

점수 규칙에 맞춘 NPC 투척물

배경과 과제

움직이는 플레이어를 투척물이 빗나가면서 콘텐츠의 점수 처리 규칙과 맞지 않는 상황이 생겼습니다.

내가 구현한 방식

일정 범위에 진입한 플레이어를 공격하는 NPC를 구현하고, 투척물 이동을 정해진 Path를 따르는 방식으로 변경했습니다.

선택의 이유와 범위

물리적인 투척 재현보다 이 콘텐츠에 정의된 명중·점수 규칙을 우선했습니다.

2026 / RECONSTRUCTED EXAMPLE

경로 기반 투척물 위치 계산

시작점·제어점·도착점으로 2차 베지어 경로를 계산합니다.

  1. 시작·제어·목표점
  2. 진행도
  3. 경로 보간
  4. 표시 위치

설명용 개념도 · 실제 제품 화면이나 전체 시스템 설계도가 아닙니다.

사용 방법과 적용 범위

Sample에 세 위치와 0~1 진행도를 전달해 표시 위치를 받습니다.

명중 판정과 점수는 별도입니다. 이동 표적을 따라갈지 고정할지는 호출자 정책입니다.

예제 코드 펼치기포트폴리오용 재구성 코드 · 실제 업무 소스 아님
// 2026 portfolio reconstruction. Not original production source.
using UnityEngine;
namespace PortfolioExamples
{
    public static class PathProjectile
    {
        // Quadratic path demonstration. Hit registration belongs to the caller.
        public static Vector3 Sample(Vector3 start,Vector3 control,Vector3 destination,float progress)
        {
            float t=Mathf.Clamp01(progress), u=1-t;
            return u*u*start + 2*u*t*control + t*t*destination;
        }
    }
}
02

스테이지별 점수와 로컬 랭킹

배경과 과제

스테이지별 플레이 결과를 저장하고 다시 확인할 수 있어야 했습니다.

내가 구현한 방식

플레이한 스테이지의 점수와 랭킹을 로컬 파일에 기록하는 기능을 개발했습니다.

선택의 이유와 범위

온라인 공용 랭킹이 아닌 로컬 저장 범위의 구현입니다.

2026 / RECONSTRUCTED EXAMPLE

최고 점수와 동점 순서를 관리하기

플레이어별 최고 점수를 유지하고, 동점은 이름 순으로 정렬합니다.

  1. 점수 입력
  2. 최고 기록 갱신
  3. 동점 규칙
  4. 랭킹 표시

설명용 개념도 · 실제 제품 화면이나 전체 시스템 설계도가 아닙니다.

사용 방법과 적용 범위

Submit(player, score) 후 Top(count)로 결과를 받습니다. 스테이지별로 별도 인스턴스를 만듭니다.

메모리 내 모델입니다. 파일 저장·복원과 온라인 랭킹은 구현하지 않습니다.

예제 코드 펼치기포트폴리오용 재구성 코드 · 실제 업무 소스 아님
// 2026 portfolio reconstruction. Not original production source. In-memory model; persistence is a separate adapter.
using System;
using System.Collections.Generic;
namespace PortfolioExamples
{
    public sealed class LocalLeaderboard
    {
        readonly Dictionary<string, int> best = new Dictionary<string, int>();
        public void Submit(string player, int score)
        {
            if (string.IsNullOrWhiteSpace(player) || score < 0) throw new ArgumentException("Invalid score entry.");
            if (!best.TryGetValue(player, out int previous) || score > previous) best[player] = score;
        }
        public List<KeyValuePair<string, int>> Top(int count)
        {
            if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
            var rows = new List<KeyValuePair<string, int>>(best);
            rows.Sort((a,b) => a.Value != b.Value ? b.Value.CompareTo(a.Value) : StringComparer.Ordinal.Compare(a.Key,b.Key));
            return rows.GetRange(0, Math.Min(count, rows.Count));
        }
    }
}

MORE SCREENS

추가 실행 화면

CODE & VALIDATION

코드와 검증 범위

기존 코드 발췌와 2026년 포트폴리오용 재구성 코드를 구분해 제공합니다. 재구성 코드는 실제 제품 소스가 아니며, 일반 원리를 설명하기 위해 새로 작성했습니다.

Unity 6000.0.23f1 컴파일 및 Editor 검증 56개 통과. 실제 장비 연동과 제품 통합은 검증 범위에 포함하지 않습니다.

예제별 사용법과 검증 내용 ↗
다른 프로젝트 살펴보기 ↗