Build TravelRun intro and tutorial flow

This commit is contained in:
jongjae0305
2026-07-06 16:15:20 +09:00
parent af26dd4311
commit 2ba3882f1b
153 changed files with 13625 additions and 2086 deletions
+205 -7
View File
@@ -32,6 +32,13 @@ public class Platform : MonoBehaviour {
MileageCard
}
public enum PlatformSkin {
Airport,
Japan,
China,
USA
}
public GameObject[] obstacles; // 장애물 오브젝트들
public int emptyPatternWeight = 2; // 장애물이 없는 패턴이 선택될 가중치
public Sprite mileageSprite; // 이 발판에서 사용할 마일리지 토큰 스프라이트
@@ -46,6 +53,7 @@ public class Platform : MonoBehaviour {
private MileagePattern reservedMileagePattern = MileagePattern.Random; // 다음 활성화 때 사용할 마일리지 패턴
private SlideObstaclePattern.SlideLayout reservedSlideLayout = SlideObstaclePattern.SlideLayout.Random; // 다음 슬라이딩 장애물 배치
private ItemPattern reservedItemPattern = ItemPattern.None; // 다음 활성화 때 사용할 아이템 배치
private PlatformSkin reservedSkin = PlatformSkin.Airport; // 현재 맵에서 사용할 발판/장애물 스킨
private const int MileagePoolSize = 5;
private const int ItemPoolSize = 1;
private const float MileageTokenScale = 0.55f;
@@ -57,18 +65,21 @@ public class Platform : MonoBehaviour {
PlatformPattern pattern,
MileagePattern mileagePattern,
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.Random,
ItemPattern itemPattern = ItemPattern.None) {
ItemPattern itemPattern = ItemPattern.None,
PlatformSkin platformSkin = PlatformSkin.Airport) {
reservedPattern = pattern;
reservedMileagePattern = mileagePattern;
reservedSlideLayout = slideLayout;
reservedItemPattern = itemPattern;
reservedSkin = platformSkin;
}
public void ConfigureForRandom() {
public void ConfigureForRandom(PlatformSkin platformSkin = PlatformSkin.Airport) {
reservedPattern = PlatformPattern.Random;
reservedMileagePattern = MileagePattern.Random;
reservedSlideLayout = SlideObstaclePattern.SlideLayout.Random;
reservedItemPattern = ItemPattern.None;
reservedSkin = platformSkin;
}
// 컴포넌트가 활성화될때 마다 매번 실행되는 메서드
@@ -76,6 +87,7 @@ public class Platform : MonoBehaviour {
// 발판을 리셋하는 처리
stepped = false;
ApplyVisualSkin();
EnsureMileagePickups();
EnsureItemPickups();
@@ -361,23 +373,209 @@ public class Platform : MonoBehaviour {
}
private Vector2 GetItemPosition(ItemPattern itemPattern) {
const float frontX = -1.45f;
switch(itemPattern)
{
case ItemPattern.HealthSushi:
return new Vector2(-1.6f, 1.55f);
return new Vector2(frontX, 1.55f);
case ItemPattern.InvincibleRamen:
return new Vector2(-0.8f, 1.55f);
return new Vector2(frontX, 1.55f);
case ItemPattern.Shield:
return new Vector2(-0.2f, 1.55f);
return new Vector2(frontX, 1.55f);
case ItemPattern.SpeedShoes:
return new Vector2(0.7f, 1.55f);
return new Vector2(frontX, 1.55f);
case ItemPattern.MileageCard:
return new Vector2(1.4f, 1.55f);
return new Vector2(frontX, 1.55f);
default:
return new Vector2(0f, 1.55f);
}
}
private void ApplyVisualSkin() {
#if UNITY_EDITOR
Sprite platformSprite = LoadSpriteAtPath(GetPlatformSkinPath(reservedSkin));
Sprite ceilingSprite = LoadSpriteAtPath(GetCeilingSkinPath(reservedSkin));
Sprite lowObstacleSprite = LoadSpriteAtPath(GetLowObstacleSkinPath(reservedSkin));
Sprite hangingObstacleSprite = LoadSpriteAtPath(GetHangingObstacleSkinPath(reservedSkin));
Sprite mileageSkinSprite = LoadSpriteAtPath(GetMileageSkinPath(reservedSkin));
ApplySprite(GetComponent<SpriteRenderer>(), platformSprite);
Transform ceilingPlatform = FindChildRecursive(transform, "Ceiling Platform");
if(ceilingPlatform != null)
{
ApplySprite(ceilingPlatform.GetComponent<SpriteRenderer>(), ceilingSprite != null ? ceilingSprite : platformSprite);
}
ApplyLowObstacleSkin(lowObstacleSprite);
ApplyHangingObstacleSkin(hangingObstacleSprite);
if(mileageSkinSprite != null)
{
mileageSprite = mileageSkinSprite;
}
#endif
}
#if UNITY_EDITOR
private void ApplyLowObstacleSkin(Sprite obstacleSprite) {
if(obstacleSprite == null || obstacles == null)
{
return;
}
for(int i = 0; i < obstacles.Length; i++)
{
GameObject obstacle = obstacles[i];
if(obstacle == null || obstacle.name.Contains("Slide"))
{
continue;
}
ApplySprite(obstacle.GetComponent<SpriteRenderer>(), obstacleSprite);
}
}
private void ApplyHangingObstacleSkin(Sprite obstacleSprite) {
if(obstacleSprite == null)
{
return;
}
GameObject slideObstacle = FindObstacle("Slide Obstacle Pattern");
if(slideObstacle == null)
{
return;
}
SlideObstaclePattern slideObstaclePattern = slideObstacle.GetComponent<SlideObstaclePattern>();
if(slideObstaclePattern == null || slideObstaclePattern.obstacles == null)
{
return;
}
for(int i = 0; i < slideObstaclePattern.obstacles.Length; i++)
{
Transform hangingObstacle = slideObstaclePattern.obstacles[i];
if(hangingObstacle != null)
{
ApplySprite(hangingObstacle.GetComponent<SpriteRenderer>(), obstacleSprite);
}
}
}
private void ApplySprite(SpriteRenderer spriteRenderer, Sprite sprite) {
if(spriteRenderer != null && sprite != null)
{
spriteRenderer.sprite = sprite;
}
}
private Sprite LoadSpriteAtPath(string assetPath) {
if(string.IsNullOrEmpty(assetPath))
{
return null;
}
return AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
}
private Transform FindChildRecursive(Transform parent, string childName) {
if(parent == null)
{
return null;
}
for(int i = 0; i < parent.childCount; i++)
{
Transform child = parent.GetChild(i);
if(child.name == childName)
{
return child;
}
Transform match = FindChildRecursive(child, childName);
if(match != null)
{
return match;
}
}
return null;
}
private string GetPlatformSkinPath(PlatformSkin platformSkin) {
switch(platformSkin)
{
case PlatformSkin.Japan:
return "Assets/Sprites/ObstacleSkins/Skin_Platform_Japan.png";
case PlatformSkin.China:
return "Assets/Sprites/ObstacleSkins/Skin_Platform_China.png";
case PlatformSkin.USA:
return "Assets/Sprites/ObstacleSkins/Skin_Platform_USA.png";
case PlatformSkin.Airport:
default:
return "Assets/Sprites/ObstacleSkins/Skin_Platform_AirportFloorTile.png";
}
}
private string GetCeilingSkinPath(PlatformSkin platformSkin) {
if(platformSkin == PlatformSkin.Airport)
{
return "Assets/Sprites/ObstacleSkins/Skin_Platform_AirportCeiling.png";
}
return GetPlatformSkinPath(platformSkin);
}
private string GetLowObstacleSkinPath(PlatformSkin platformSkin) {
switch(platformSkin)
{
case PlatformSkin.Japan:
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_StoneLantern.png";
case PlatformSkin.China:
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_MarketCrate.png";
case PlatformSkin.USA:
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_Cone.png";
case PlatformSkin.Airport:
default:
return "Assets/Sprites/ObstacleSkins/Skin_Obstacle_Suitcases.png";
}
}
private string GetHangingObstacleSkinPath(PlatformSkin platformSkin) {
switch(platformSkin)
{
case PlatformSkin.Japan:
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_RoadSign.png";
case PlatformSkin.China:
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_RedLanterns.png";
case PlatformSkin.USA:
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_Banner.png";
case PlatformSkin.Airport:
default:
return "Assets/Sprites/ObstacleSkins/Skin_Hanging_AirportSign.png";
}
}
private string GetMileageSkinPath(PlatformSkin platformSkin) {
switch(platformSkin)
{
case PlatformSkin.Japan:
return "Assets/Sprites/Mileage/Mileage_Japan.png";
case PlatformSkin.China:
return "Assets/Sprites/Mileage/Mileage_China.png";
case PlatformSkin.USA:
return "Assets/Sprites/Mileage/Mileage_USA.png";
case PlatformSkin.Airport:
default:
return "Assets/Sprites/Mileage/Mileage_Korea.png";
}
}
#endif
private Sprite LoadItemSprite(GameManager.TutorialItemType itemType) {
#if UNITY_EDITOR
string assetPath = "";