697 lines
23 KiB
C#
697 lines
23 KiB
C#
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
// 발판으로서 필요한 동작을 담은 스크립트
|
|
public class Platform : MonoBehaviour {
|
|
public enum PlatformPattern {
|
|
Random,
|
|
Empty,
|
|
LowLeft,
|
|
LowMid,
|
|
LowRight,
|
|
Slide,
|
|
ForceHit
|
|
}
|
|
|
|
public enum MileagePattern {
|
|
Random,
|
|
None,
|
|
SafeLine,
|
|
JumpArc,
|
|
SlideLine
|
|
}
|
|
|
|
public enum ItemPattern {
|
|
None,
|
|
HealthSushi,
|
|
InvincibleRamen,
|
|
Shield,
|
|
SpeedShoes,
|
|
MileageCard
|
|
}
|
|
|
|
public enum PlatformSkin {
|
|
Airport,
|
|
Japan,
|
|
China,
|
|
USA
|
|
}
|
|
|
|
public GameObject[] obstacles; // 장애물 오브젝트들
|
|
public int emptyPatternWeight = 2; // 장애물이 없는 패턴이 선택될 가중치
|
|
public Sprite mileageSprite; // 이 발판에서 사용할 마일리지 토큰 스프라이트
|
|
public int mileagePatternChance = 50; // 마일리지 패턴 등장 확률
|
|
public int smallMileageValue = 10; // 일반 토큰 가치
|
|
public int bonusMileageValue = 30; // 어려운 루트 보너스 토큰 가치
|
|
|
|
private bool stepped = false; // 플레이어 캐릭터가 밟았었는가
|
|
private MileagePickup[] mileagePickups; // 런타임에 생성하는 마일리지 토큰 풀
|
|
private ItemPickup[] itemPickups; // 런타임에 생성하는 튜토리얼 아이템 풀
|
|
private PlatformPattern reservedPattern = PlatformPattern.Random; // 다음 활성화 때 사용할 수동 패턴
|
|
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;
|
|
private const float MileageColliderRadius = 0.4f;
|
|
private const float ItemTokenScale = 1.36f;
|
|
private const float ItemColliderRadius = 0.46f;
|
|
private const float JumpMileageMinWidthScale = 1.8f;
|
|
private const float JumpMileageMaxWidthScale = 2.5f;
|
|
|
|
public void ConfigureForTutorial(
|
|
PlatformPattern pattern,
|
|
MileagePattern mileagePattern,
|
|
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.Random,
|
|
ItemPattern itemPattern = ItemPattern.None,
|
|
PlatformSkin platformSkin = PlatformSkin.Airport) {
|
|
reservedPattern = pattern;
|
|
reservedMileagePattern = mileagePattern;
|
|
reservedSlideLayout = slideLayout;
|
|
reservedItemPattern = itemPattern;
|
|
reservedSkin = platformSkin;
|
|
}
|
|
|
|
public void ConfigureForRandom(PlatformSkin platformSkin = PlatformSkin.Airport) {
|
|
reservedPattern = PlatformPattern.Random;
|
|
reservedMileagePattern = MileagePattern.Random;
|
|
reservedSlideLayout = SlideObstaclePattern.SlideLayout.Random;
|
|
reservedItemPattern = ItemPattern.None;
|
|
reservedSkin = platformSkin;
|
|
}
|
|
|
|
// 컴포넌트가 활성화될때 마다 매번 실행되는 메서드
|
|
private void OnEnable() {
|
|
// 발판을 리셋하는 처리
|
|
|
|
stepped = false;
|
|
ApplyVisualSkin();
|
|
EnsureMileagePickups();
|
|
EnsureItemPickups();
|
|
|
|
for(int i = 0; i < obstacles.Length; i++)
|
|
{
|
|
obstacles[i].SetActive(false);
|
|
}
|
|
|
|
HideMileagePickups();
|
|
HideItemPickups();
|
|
|
|
if(reservedPattern != PlatformPattern.Random)
|
|
{
|
|
ApplyReservedPattern();
|
|
return;
|
|
}
|
|
|
|
if(obstacles.Length == 0)
|
|
{
|
|
TryPlaceMileagePattern(null);
|
|
return;
|
|
}
|
|
|
|
// 낮은 장애물과 높은 장애물이 동시에 켜져 불가능한 배치가 되지 않도록 하나만 선택한다.
|
|
int patternIndex = Random.Range(0, obstacles.Length + emptyPatternWeight);
|
|
GameObject activeObstacle = null;
|
|
|
|
if(patternIndex < obstacles.Length)
|
|
{
|
|
activeObstacle = obstacles[patternIndex];
|
|
ConfigureSlideObstacle(activeObstacle);
|
|
activeObstacle.SetActive(true);
|
|
}
|
|
|
|
TryPlaceMileagePattern(activeObstacle);
|
|
}
|
|
|
|
void OnCollisionEnter2D(Collision2D collision) {
|
|
// 플레이어 캐릭터가 자신을 밟았을때 점수를 추가하는 처리
|
|
if(collision.collider.tag == "Player" && !stepped && GameFlowManager.IsGameplayActive)
|
|
{
|
|
stepped = true;
|
|
GameManager.instance.AddScore(1);
|
|
}
|
|
}
|
|
|
|
private void EnsureMileagePickups() {
|
|
if(mileagePickups != null && mileagePickups.Length == MileagePoolSize)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mileagePickups = new MileagePickup[MileagePoolSize];
|
|
|
|
for(int i = 0; i < MileagePoolSize; i++)
|
|
{
|
|
GameObject pickupObject = new GameObject("Mileage Pickup " + (i + 1));
|
|
pickupObject.transform.SetParent(transform);
|
|
pickupObject.transform.localScale = GetParentScaleCompensatedVector(MileageTokenScale);
|
|
|
|
SpriteRenderer spriteRenderer = pickupObject.AddComponent<SpriteRenderer>();
|
|
spriteRenderer.sprite = mileageSprite;
|
|
spriteRenderer.sortingLayerName = "Foreground";
|
|
spriteRenderer.sortingOrder = 1;
|
|
|
|
CircleCollider2D pickupCollider = pickupObject.AddComponent<CircleCollider2D>();
|
|
pickupCollider.isTrigger = true;
|
|
pickupCollider.radius = MileageColliderRadius;
|
|
|
|
mileagePickups[i] = pickupObject.AddComponent<MileagePickup>();
|
|
mileagePickups[i].Setup(mileageSprite, smallMileageValue);
|
|
|
|
pickupObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void EnsureItemPickups() {
|
|
if(itemPickups != null && itemPickups.Length == ItemPoolSize)
|
|
{
|
|
return;
|
|
}
|
|
|
|
itemPickups = new ItemPickup[ItemPoolSize];
|
|
|
|
for(int i = 0; i < ItemPoolSize; i++)
|
|
{
|
|
GameObject pickupObject = new GameObject("Tutorial Item Pickup " + (i + 1));
|
|
pickupObject.transform.SetParent(transform);
|
|
pickupObject.transform.localScale = GetParentScaleCompensatedVector(ItemTokenScale);
|
|
|
|
SpriteRenderer spriteRenderer = pickupObject.AddComponent<SpriteRenderer>();
|
|
spriteRenderer.sortingLayerName = "Foreground";
|
|
spriteRenderer.sortingOrder = 2;
|
|
|
|
CircleCollider2D pickupCollider = pickupObject.AddComponent<CircleCollider2D>();
|
|
pickupCollider.isTrigger = true;
|
|
pickupCollider.radius = ItemColliderRadius;
|
|
|
|
itemPickups[i] = pickupObject.AddComponent<ItemPickup>();
|
|
pickupObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void HideMileagePickups() {
|
|
if(mileagePickups == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(int i = 0; i < mileagePickups.Length; i++)
|
|
{
|
|
if(mileagePickups[i] != null)
|
|
{
|
|
mileagePickups[i].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void HideItemPickups() {
|
|
if(itemPickups == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(int i = 0; i < itemPickups.Length; i++)
|
|
{
|
|
if(itemPickups[i] != null)
|
|
{
|
|
itemPickups[i].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TryPlaceMileagePattern(GameObject activeObstacle) {
|
|
if(mileageSprite == null || mileagePickups == null || Random.Range(0, 100) >= mileagePatternChance)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(activeObstacle == null)
|
|
{
|
|
PlaceSafeMileageLine();
|
|
return;
|
|
}
|
|
|
|
if(activeObstacle.name.Contains("Slide"))
|
|
{
|
|
PlaceSlideMileageLine();
|
|
}
|
|
else
|
|
{
|
|
PlaceJumpMileageArc(GetWorldRelativeX(activeObstacle.transform));
|
|
}
|
|
}
|
|
|
|
private void ApplyReservedPattern() {
|
|
GameObject activeObstacle = null;
|
|
|
|
switch(reservedPattern)
|
|
{
|
|
case PlatformPattern.LowLeft:
|
|
activeObstacle = FindObstacle("Obstacle Left");
|
|
break;
|
|
case PlatformPattern.LowMid:
|
|
activeObstacle = FindObstacle("Obstacle Mid");
|
|
break;
|
|
case PlatformPattern.LowRight:
|
|
activeObstacle = FindObstacle("Obstacle Right");
|
|
break;
|
|
case PlatformPattern.Slide:
|
|
activeObstacle = FindObstacle("Slide Obstacle Pattern");
|
|
break;
|
|
case PlatformPattern.ForceHit:
|
|
activeObstacle = FindObstacle("Obstacle Mid");
|
|
ActivateObstacle(activeObstacle);
|
|
|
|
GameObject slideObstacle = FindObstacle("Slide Obstacle Pattern");
|
|
reservedSlideLayout = SlideObstaclePattern.SlideLayout.WidePair;
|
|
ActivateObstacle(slideObstacle);
|
|
break;
|
|
}
|
|
|
|
if(reservedPattern != PlatformPattern.ForceHit && activeObstacle != null)
|
|
{
|
|
ActivateObstacle(activeObstacle);
|
|
}
|
|
|
|
PlaceReservedMileagePattern(activeObstacle);
|
|
PlaceReservedItemPattern();
|
|
}
|
|
|
|
private void ActivateObstacle(GameObject obstacle) {
|
|
if(obstacle == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ConfigureSlideObstacle(obstacle);
|
|
obstacle.SetActive(true);
|
|
}
|
|
|
|
private void ConfigureSlideObstacle(GameObject activeObstacle) {
|
|
if(activeObstacle == null || !activeObstacle.name.Contains("Slide"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
SlideObstaclePattern slideObstaclePattern = activeObstacle.GetComponent<SlideObstaclePattern>();
|
|
if(slideObstaclePattern != null)
|
|
{
|
|
slideObstaclePattern.ConfigureLayout(reservedSlideLayout);
|
|
}
|
|
}
|
|
|
|
private GameObject FindObstacle(string obstacleName) {
|
|
for(int i = 0; i < obstacles.Length; i++)
|
|
{
|
|
if(obstacles[i] != null && obstacles[i].name == obstacleName)
|
|
{
|
|
return obstacles[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void PlaceReservedMileagePattern(GameObject activeObstacle) {
|
|
if(mileageSprite == null || mileagePickups == null || reservedMileagePattern == MileagePattern.None)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(reservedMileagePattern == MileagePattern.SafeLine)
|
|
{
|
|
PlaceSafeMileageLine();
|
|
return;
|
|
}
|
|
|
|
if(reservedMileagePattern == MileagePattern.JumpArc)
|
|
{
|
|
float obstacleX = activeObstacle != null ? GetWorldRelativeX(activeObstacle.transform) : 0f;
|
|
PlaceJumpMileageArc(obstacleX);
|
|
return;
|
|
}
|
|
|
|
if(reservedMileagePattern == MileagePattern.SlideLine)
|
|
{
|
|
PlaceSlideMileageLine();
|
|
return;
|
|
}
|
|
|
|
TryPlaceMileagePattern(activeObstacle);
|
|
}
|
|
|
|
private void PlaceReservedItemPattern() {
|
|
if(reservedItemPattern == ItemPattern.None || itemPickups == null || itemPickups.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameManager.TutorialItemType itemType = GetTutorialItemType(reservedItemPattern);
|
|
ItemPickup pickup = itemPickups[0];
|
|
pickup.Setup(LoadItemSprite(itemType), itemType);
|
|
pickup.transform.localPosition = GetParentScaleCompensatedPosition(GetItemPosition(reservedItemPattern));
|
|
pickup.ResetPickup();
|
|
}
|
|
|
|
private GameManager.TutorialItemType GetTutorialItemType(ItemPattern itemPattern) {
|
|
switch(itemPattern)
|
|
{
|
|
case ItemPattern.InvincibleRamen:
|
|
return GameManager.TutorialItemType.InvincibleRamen;
|
|
case ItemPattern.Shield:
|
|
return GameManager.TutorialItemType.Shield;
|
|
case ItemPattern.SpeedShoes:
|
|
return GameManager.TutorialItemType.SpeedShoes;
|
|
case ItemPattern.MileageCard:
|
|
return GameManager.TutorialItemType.MileageCard;
|
|
case ItemPattern.HealthSushi:
|
|
default:
|
|
return GameManager.TutorialItemType.HealthSushi;
|
|
}
|
|
}
|
|
|
|
private Vector2 GetItemPosition(ItemPattern itemPattern) {
|
|
const float frontX = -1.45f;
|
|
|
|
switch(itemPattern)
|
|
{
|
|
case ItemPattern.HealthSushi:
|
|
return new Vector2(frontX, 1.55f);
|
|
case ItemPattern.InvincibleRamen:
|
|
return new Vector2(frontX, 1.55f);
|
|
case ItemPattern.Shield:
|
|
return new Vector2(frontX, 1.55f);
|
|
case ItemPattern.SpeedShoes:
|
|
return new Vector2(frontX, 1.55f);
|
|
case ItemPattern.MileageCard:
|
|
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 = "";
|
|
|
|
switch(itemType)
|
|
{
|
|
case GameManager.TutorialItemType.InvincibleRamen:
|
|
assetPath = "Assets/Sprites/Items/Item_Invincible_Ramen.png";
|
|
break;
|
|
case GameManager.TutorialItemType.Shield:
|
|
assetPath = "Assets/Sprites/Items/Item_Shield.png";
|
|
break;
|
|
case GameManager.TutorialItemType.SpeedShoes:
|
|
assetPath = "Assets/Sprites/Items/Item_Speed_Shoes.png";
|
|
break;
|
|
case GameManager.TutorialItemType.MileageCard:
|
|
assetPath = "Assets/Sprites/Items/Item_Mileage_Card.png";
|
|
break;
|
|
case GameManager.TutorialItemType.HealthSushi:
|
|
default:
|
|
assetPath = "Assets/Sprites/Items/Item_Health_Sushi.png";
|
|
break;
|
|
}
|
|
|
|
return AssetDatabase.LoadAssetAtPath<Sprite>(assetPath);
|
|
#else
|
|
return null;
|
|
#endif
|
|
}
|
|
|
|
private void PlaceSafeMileageLine() {
|
|
Vector2[] positions = {
|
|
new Vector2(-2f, 1.35f),
|
|
new Vector2(-1f, 1.35f),
|
|
new Vector2(0f, 1.35f),
|
|
new Vector2(1f, 1.35f),
|
|
new Vector2(2f, 1.35f)
|
|
};
|
|
|
|
PlaceMileageTokens(positions, smallMileageValue);
|
|
}
|
|
|
|
private void PlaceJumpMileageArc(float obstacleX) {
|
|
float widthScale = GetJumpMileageArcWidthScale();
|
|
Vector2[] positions = {
|
|
new Vector2(obstacleX - 2.25f * widthScale, 1.88f),
|
|
new Vector2(obstacleX - 1.15f * widthScale, 2.88f),
|
|
new Vector2(obstacleX, 3.58f),
|
|
new Vector2(obstacleX + 1.15f * widthScale, 2.88f),
|
|
new Vector2(obstacleX + 2.25f * widthScale, 1.88f)
|
|
};
|
|
|
|
PlaceMileageTokens(positions, smallMileageValue);
|
|
SetPickupValue(2, bonusMileageValue);
|
|
}
|
|
|
|
private float GetJumpMileageArcWidthScale() {
|
|
if(GameManager.instance == null)
|
|
{
|
|
return JumpMileageMinWidthScale;
|
|
}
|
|
|
|
float minSpeed = Mathf.Max(0.1f, GameManager.instance.minGameSpeed);
|
|
float maxSpeed = Mathf.Max(minSpeed + 0.1f, GameManager.instance.maxGameSpeed);
|
|
float speedProgress = Mathf.InverseLerp(minSpeed, maxSpeed, GameManager.instance.gameSpeed);
|
|
return Mathf.Lerp(JumpMileageMinWidthScale, JumpMileageMaxWidthScale, speedProgress);
|
|
}
|
|
|
|
private void PlaceSlideMileageLine() {
|
|
Vector2[] positions = {
|
|
new Vector2(-1.5f, 1.05f),
|
|
new Vector2(-0.5f, 1.05f),
|
|
new Vector2(0.5f, 1.05f),
|
|
new Vector2(1.5f, 1.05f)
|
|
};
|
|
|
|
PlaceMileageTokens(positions, smallMileageValue);
|
|
SetPickupValue(2, bonusMileageValue);
|
|
}
|
|
|
|
private void PlaceMileageTokens(Vector2[] positions, int value) {
|
|
int count = Mathf.Min(positions.Length, mileagePickups.Length);
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
mileagePickups[i].Setup(mileageSprite, value);
|
|
mileagePickups[i].transform.localPosition = GetParentScaleCompensatedPosition(positions[i]);
|
|
mileagePickups[i].ResetPickup();
|
|
}
|
|
}
|
|
|
|
private Vector3 GetParentScaleCompensatedVector(float scale) {
|
|
float parentScaleX = Mathf.Approximately(transform.localScale.x, 0f) ? 1f : transform.localScale.x;
|
|
float parentScaleY = Mathf.Approximately(transform.localScale.y, 0f) ? 1f : transform.localScale.y;
|
|
return new Vector3(scale / parentScaleX, scale / parentScaleY, 1f);
|
|
}
|
|
|
|
private Vector3 GetParentScaleCompensatedPosition(Vector2 position) {
|
|
float parentScaleX = Mathf.Approximately(transform.localScale.x, 0f) ? 1f : transform.localScale.x;
|
|
float parentScaleY = Mathf.Approximately(transform.localScale.y, 0f) ? 1f : transform.localScale.y;
|
|
return new Vector3(position.x / parentScaleX, position.y / parentScaleY, 0f);
|
|
}
|
|
|
|
private float GetWorldRelativeX(Transform child) {
|
|
return child.localPosition.x * transform.localScale.x;
|
|
}
|
|
|
|
private void SetPickupValue(int index, int value) {
|
|
if(index < 0 || index >= mileagePickups.Length || !mileagePickups[index].gameObject.activeSelf)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mileagePickups[index].Setup(mileageSprite, value);
|
|
}
|
|
}
|