From 447b3d6d911f6673922e7b5230b6c60d8aa12f58 Mon Sep 17 00:00:00 2001 From: kimura Date: Thu, 2 Sep 2021 12:47:39 +0900 Subject: [PATCH] =?UTF-8?q?=E3=81=8A=E5=AE=A2=E3=81=95=E3=82=93=E3=81=AE?= =?UTF-8?q?=E5=8B=95=E3=81=8D=E6=94=B9=E5=96=84/=E8=B2=A9=E5=A3=B2?= =?UTF-8?q?=E3=83=AD=E3=82=B8=E3=83=83=E3=82=AF=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scenes/marketing/Prefabs/Customer.prefab | 36 +- .../marketing/Scripts/CustomerController.cs | 208 ++++++++--- .../MyGame/Scenes/marketing/Scripts/Market.cs | 347 ++++++++++++------ .../MyGame/Scenes/marketing/marketing.unity | 19 +- popcorn/Assets/MyGame/Scripts/HeartMeter.cs | 76 ++-- 5 files changed, 489 insertions(+), 197 deletions(-) diff --git a/popcorn/Assets/MyGame/Scenes/marketing/Prefabs/Customer.prefab b/popcorn/Assets/MyGame/Scenes/marketing/Prefabs/Customer.prefab index 83a7cb51..a5723c16 100644 --- a/popcorn/Assets/MyGame/Scenes/marketing/Prefabs/Customer.prefab +++ b/popcorn/Assets/MyGame/Scenes/marketing/Prefabs/Customer.prefab @@ -55,12 +55,13 @@ MonoBehaviour: walkSideTopPosition: -0.6 walkSideMidPos: -4 walkSideBottomPos: -6.7 + walkSideLeavePos: -1 stopPosision: 0 - stopPositionRange: 1 + stopPositionRange: 3 orderStayPositions: [] orderPosision: 0.5 orderPositionRange: 2 - waitOrderPosision: -0.6 + waitOrderPosision: -1.5 walkSideSpeed: 1.3 walkFrontBackSpeed: 1 --- !u!114 &1385243083193661112 @@ -78,6 +79,32 @@ MonoBehaviour: bigHeart: {fileID: 7988005957398545984} smallHeart: {fileID: 992423202615605163} target: {fileID: 0} +--- !u!61 &3337152902562194938 +BoxCollider2D: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5409985851491668855} + m_Enabled: 1 + m_Density: 1 + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_UsedByEffector: 0 + m_UsedByComposite: 0 + m_Offset: {x: 0, y: 0} + m_SpriteTilingProperty: + border: {x: 0, y: 0, z: 0, w: 0} + pivot: {x: 0, y: 0} + oldSize: {x: 0, y: 0} + newSize: {x: 0, y: 0} + adaptiveTilingThreshold: 0 + drawMode: 0 + adaptiveTiling: 0 + m_AutoTiling: 0 + serializedVersion: 2 + m_Size: {x: 2, y: 2} + m_EdgeRadius: 0 --- !u!210 &7449452199590198578 SortingGroup: m_ObjectHideFlags: 0 @@ -156,6 +183,11 @@ PrefabInstance: propertyPath: m_Name value: NormalBody objectReference: {fileID: 0} + - target: {fileID: 4886416729068509251, guid: db654393793a67d45a7d0b70a68b73a6, + type: 3} + propertyPath: m_IsActive + value: 1 + objectReference: {fileID: 0} - target: {fileID: 4886416729748261544, guid: db654393793a67d45a7d0b70a68b73a6, type: 3} propertyPath: m_IsActive diff --git a/popcorn/Assets/MyGame/Scenes/marketing/Scripts/CustomerController.cs b/popcorn/Assets/MyGame/Scenes/marketing/Scripts/CustomerController.cs index 24ddf91c..9e273d1b 100644 --- a/popcorn/Assets/MyGame/Scenes/marketing/Scripts/CustomerController.cs +++ b/popcorn/Assets/MyGame/Scenes/marketing/Scripts/CustomerController.cs @@ -7,16 +7,27 @@ using Random = UnityEngine.Random; public enum CustomerMovingType { - WalkFront, WalkSide, - WalkBack, - WalkBackHalf, - StayBack, - StayBackLook, - WalkFrontEat, WalkSideEat, WalkCenter, + StayBack, + StayBackLook, + WalkBack, + WalkBackHalf, + WalkFront, + WalkFrontEat, } + +public enum CustomerState +{ + Walk, + Want, + Wait, + Order, + Leave, + EatingLeave, +} + public class CustomerController : MonoBehaviour { private static readonly int WalkFront = Animator.StringToHash("WalkFront"); @@ -40,6 +51,7 @@ public class CustomerController : MonoBehaviour [SerializeField] private float walkSideTopPosition; [SerializeField] private float walkSideMidPos; [SerializeField] private float walkSideBottomPos; + [SerializeField] private float walkSideLeavePos; // 立ち止まる範囲 [SerializeField] private float stopPosision = 0f; [SerializeField] private float stopPositionRange = 2f; @@ -47,33 +59,47 @@ public class CustomerController : MonoBehaviour [SerializeField] private List orderStayPositions = new List(); // 購入ポジ [SerializeField] private float orderPosision = .5f; - [SerializeField] private float orderPositionRange = 2f; + [SerializeField] private float orderPositionRange = 1f; [SerializeField] private float waitOrderPosision = .2f; // 歩行速度 [SerializeField] private float walkSideSpeed = 1.3f; // 1.3f [SerializeField] private float walkFrontBackSpeed = 1.0f; // 1.0f - private float speed = 0f; + private static readonly float leftEndPosision = -10f; private Vector3 beginPos; private Vector3 wayPoint; - private List moves = new List(); - private static readonly float leftEndPosision = -10f; - // 停止時間 + private CustomerMovingType currentMovingType; + private List<(CustomerMovingType type, float duration)> moves = new List<(CustomerMovingType, float)>(); + private float speed = 0f; + private float completedDuration; + private float durationDelta; // 左右どちらから出るか private float walkSideDirection; - private Subject orderSubject = new Subject(); - public IObservable OrderObservable => orderSubject; - + public IReadOnlyReactiveProperty MoveEndObservable => moveEndSubject; + private readonly ReactiveProperty moveEndSubject = new ReactiveProperty(); + public IReadOnlyReactiveProperty CustomerState => customerState; + private readonly ReactiveProperty customerState = new ReactiveProperty(); + private void Start() { + customerState.AddTo(this); + durationDelta = 0f; this.UpdateAsObservable().Subscribe(_ => { transform.localPosition = Vector3.MoveTowards(transform.localPosition, wayPoint, speed * Time.deltaTime); if (Vector3.Distance(transform.localPosition, wayPoint) < .01f) { + if (durationDelta < completedDuration) + { + durationDelta += Time.deltaTime; + return; + } + durationDelta = 0f; + moveEndSubject.Value = currentMovingType; if (moves.Count > 0) { - SetMove(moves[0]); + var move = moves[0]; moves.RemoveAt(0); + SetMove(move.type, move.duration); } } }).AddTo(this); @@ -82,81 +108,152 @@ public class CustomerController : MonoBehaviour public void Setup() { walkSideDirection = Mathf.Sign(Random.value - .5f); - if (walkSideDirection < 0) - { - transform.localRotation = Quaternion.Euler(Vector3.up * 180); - } beginPos = Vector3.zero; beginPos.x = leftEndPosision * walkSideDirection; beginPos.y = Random.Range(walkSideMidPos, walkSideBottomPos); - beginPos.z = beginPos.y + Mathf.Abs(walkSideBottomPos); transform.localPosition = beginPos; + currentMovingType = CustomerMovingType.StayBack; SetWayPoint(beginPos); } - public void AddMove(CustomerMovingType type) + public void ChangeCustomerState(CustomerState state) { - moves.Add(type); + customerState.Value = state; + Debug.Log(state); + switch (state) + { + case global::CustomerState.Walk: + SetMove(CustomerMovingType.WalkCenter); + // 数秒立ち止まる + AddMove(CustomerMovingType.StayBackLook, 2f); + AddMove(CustomerMovingType.WalkSide); + break; + case global::CustomerState.Want: + // 店に向かう + moves.Clear(); + if (currentMovingType == CustomerMovingType.StayBackLook) + { + SetMove(CustomerMovingType.WalkBackHalf); + break; + } + SetMove(CustomerMovingType.WalkCenter); + break; + case global::CustomerState.Wait: + // 順番待ち + // 近くの場合その場に待機 + // まだ遠い場合待機場所に移動 + AddMove(CustomerMovingType.WalkBackHalf); + AddMove(CustomerMovingType.StayBackLook); + break; + case global::CustomerState.Order: + // 受付まで行く + AddMove(CustomerMovingType.WalkBack); + AddMove(CustomerMovingType.StayBack); + break; + case global::CustomerState.Leave: + moves.Clear(); + SetMove(CustomerMovingType.WalkSide); + break; + case global::CustomerState.EatingLeave: + AddMove(CustomerMovingType.WalkFrontEat); + AddMove(CustomerMovingType.WalkSideEat); + break; + default: + throw new ArgumentOutOfRangeException(nameof(state), state, null); + } + } + + private void AddMove(CustomerMovingType type, float duration = 0f) + { + moves.Add((type, duration)); } // キャラの奥行き描画順のため、y方向に対応したz軸を設定 - private void SetMove(CustomerMovingType type) + private void SetMove(CustomerMovingType type, float duration = 0f) { + if (currentMovingType == type) + { + return; + } + completedDuration = duration; switch (type) { - case CustomerMovingType.WalkFront: - SetWayPoint(new Vector3(wayPoint.x, Random.Range(walkSideMidPos, walkSideTopPosition))); - speed = walkFrontBackSpeed; - animator.SetTrigger(WalkFront); - break; case CustomerMovingType.WalkSide: SetWayPoint(new Vector3(-leftEndPosision * walkSideDirection, wayPoint.y)); speed = walkSideSpeed; + // アニメーション違和感回避 + if (currentMovingType == CustomerMovingType.WalkCenter) + { + break; + } animator.SetTrigger(WalkSide); break; - case CustomerMovingType.WalkBack: - SetWayPoint(new Vector3((Random.value - .5f) * 2 * orderPositionRange, orderPosision)); - speed = walkFrontBackSpeed; - animator.SetTrigger(WalkBack); - break; - case CustomerMovingType.WalkBackHalf: - SetWayPoint(new Vector3(stopPosision + (Random.value - .5f) * 2 * stopPositionRange, waitOrderPosision)); - speed = walkFrontBackSpeed; - animator.SetTrigger(WalkBack); - break; - case CustomerMovingType.StayBack: - speed = 0f; - animator.SetTrigger(StayBack); - orderSubject.OnNext(Unit.Default); - break; - case CustomerMovingType.StayBackLook: - speed = 0f; - animator.SetTrigger(StayBackLook); - break; - case CustomerMovingType.WalkFrontEat: - SetWayPoint(new Vector3(wayPoint.x, Random.Range(walkSideMidPos, walkSideTopPosition))); - speed = walkFrontBackSpeed; - animator.SetTrigger(WalkFrontEat); - break; case CustomerMovingType.WalkSideEat: SetWayPoint(new Vector3(-leftEndPosision * walkSideDirection, wayPoint.y)); speed = walkSideSpeed; animator.SetTrigger(WalkSideEat); break; case CustomerMovingType.WalkCenter: - SetWayPoint(new Vector3(stopPosision + (Random.value - .5f) * 2 * stopPositionRange, beginPos.y)); + // 通り過ぎた人はwalkSideDirection基準にするとあるき過ぎるので改善したい + // 立ち止まったあと戻ってしまう場合があるので、中央付近だと戻りがないようにする + if (Mathf.Abs(transform.localPosition.x - stopPosision) <= stopPositionRange) + { + SetWayPoint(new Vector3(transform.localPosition.x, beginPos.y)); + } + else + { + SetWayPoint(new Vector3(stopPosision - Random.value * stopPositionRange * walkSideDirection, beginPos.y)); + } speed = walkSideSpeed; + // アニメーション違和感回避 + if (currentMovingType == CustomerMovingType.WalkSide) + { + break; + } animator.SetTrigger(WalkSide); break; + case CustomerMovingType.StayBack: + // オーダー + speed = 0f; + animator.SetTrigger(StayBack); + break; + case CustomerMovingType.StayBackLook: + speed = 0f; + animator.SetTrigger(StayBackLook); + break; + case CustomerMovingType.WalkBack: + SetWayPoint(new Vector3(Random.value * orderPositionRange * walkSideDirection, orderPosision)); + speed = walkFrontBackSpeed; + animator.SetTrigger(WalkBack); + break; + case CustomerMovingType.WalkBackHalf: + // 待機列に入る + SetWayPoint(new Vector3(wayPoint.x, waitOrderPosision)); + speed = walkFrontBackSpeed; + animator.SetTrigger(WalkBack); + break; + case CustomerMovingType.WalkFront: + // 購入場所に行く + SetWayPoint(new Vector3(wayPoint.x, Random.Range(walkSideLeavePos, walkSideTopPosition))); + speed = walkFrontBackSpeed; + animator.SetTrigger(WalkFront); + break; + case CustomerMovingType.WalkFrontEat: + SetWayPoint(new Vector3(wayPoint.x, Random.Range(walkSideLeavePos, walkSideTopPosition))); + speed = walkFrontBackSpeed; + animator.SetTrigger(WalkFrontEat); + break; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } + currentMovingType = type; } private void SetWayPoint(Vector3 point) { wayPoint = point; wayPoint.z = wayPoint.y + Mathf.Abs(walkSideBottomPos); + transform.localRotation = Quaternion.Euler((wayPoint - transform.localPosition).x >= 0 ? Vector3.zero : Vector3.up * 180); } public void ChangeWantFlavor(int flavor) @@ -176,9 +273,4 @@ public class CustomerController : MonoBehaviour wantFlavorSprite.sprite = defaultSprite; } } - - public void SetCustomerType() - { - - } } \ No newline at end of file diff --git a/popcorn/Assets/MyGame/Scenes/marketing/Scripts/Market.cs b/popcorn/Assets/MyGame/Scenes/marketing/Scripts/Market.cs index c48c2e47..71f5c3cc 100644 --- a/popcorn/Assets/MyGame/Scenes/marketing/Scripts/Market.cs +++ b/popcorn/Assets/MyGame/Scenes/marketing/Scripts/Market.cs @@ -3,9 +3,17 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using UniRx; +using UniRx.Triggers; using UnityEngine; using Random = UnityEngine.Random; +public enum ShopState +{ + Open, + Busy, + Close, +} + public class Market : MonoBehaviour { public static readonly int ShopStockCount = 20; @@ -18,29 +26,51 @@ public class Market : MonoBehaviour private readonly List allRecipe = RecipeData.GetAllRecipe(); private List displayFlavors; private List shuffledOrder; + private ReactiveProperty shopState = new ReactiveProperty(); + private ReactiveCollection waitCustomerList = new ReactiveCollection(); + private Subject requestSubject = new Subject(); // Start is called before the first frame update void Start() { + shopState.AddTo(this); + waitCustomerList.AddTo(this); + requestSubject.AddTo(this); + var gameData = GameDataManager.GameData; CoinManager.Instance.ChangeCoin(gameData.coin); - HeartMeter.Instance.Initialize(new List{ - 0, - 10, - 30, - 50, - 80, - 130, - 210, - 320, - 470, - 650, - }); + + var shopLevelList = new List<(int level, int heart, int tenMinCustomer)> + { + (1, 0, 10), + (2, 10, 15), + (3, 30, 20), + (4, 50, 25), + (5, 80, 30), + (6, 130, 35), + (7, 210, 40), + (8, 320, 45), + (9, 470, 50), + (10, 650, 55), + (11, 870, 60), + (12, 1120, 65), + (13, 1420, 70), + (14, 1870, 75), + (15, 2470, 80), + (16, 3170, 85), + (17, 4070, 90), + (18, 5470, 95), + (19, 7070, 100), + (20, 9070, 105), + }; + + HeartMeter.Instance.Initialize(shopLevelList.Select(x => x.heart).ToList()); HeartMeter.Instance.SetHeart(15); + // 在庫数表示 stockView.SetStock(gameData.StorageTanks); - FixStock(); + CheckAndFixStock(); StockFlavorLog(); // 陳列 @@ -50,66 +80,214 @@ public class Market : MonoBehaviour // 売り順決定 shuffledOrder = ShuffleOrder(displayFlavors.Count); - // お客さん出現パターン確率計算と行動パターン計算 + // お店の状態設定 + shopState.Value = gameData.ShopStock.Count == 0 ? ShopState.Close : ShopState.Open; - var customerObservable = Observable.Interval(TimeSpan.FromSeconds(60f)).Select(_ => + // 購入リクエスト + shopState + .Where(x => x == ShopState.Open) + .Where(_ => waitCustomerList.Count > 0) + .Select(_ => waitCustomerList[0]) + .Merge(waitCustomerList.ObserveAdd().Select(x => x.Value)) + .BatchFrame() + .Select(x => x.RandomChoose()) // 同時にリクエストが有った場合1人選ぶ + .Where(_ => shopState.Value == ShopState.Open) // 他に購入中の客がいないことを確認 + .Subscribe(x => + { + Debug.Log($"RequestComfirmed"); + waitCustomerList.Remove(x); + // 購入へ + x.ChangeCustomerState(CustomerState.Order); + shopState.Value = ShopState.Busy; + }).AddTo(this); + + // お客さん一覧 + var customerList = new ReactiveCollection(); + customerList.AddTo(this); + // 購入客 + customerList.ObserveAdd() + .Select(x => x.Value) + .Subscribe(customerController => + { + // 店に向かう + customerController.ChangeCustomerState(CustomerState.Want); + waitCustomerList.Add(customerController); + + shopState.Subscribe(x => + { + switch (x) + { + case ShopState.Open: + break; + case ShopState.Busy: + // 自分が購入中 + if (customerController.CustomerState.Value == CustomerState.Order) + { + return; + } + // 待機 + customerController.ChangeCustomerState(CustomerState.Wait); + break; + case ShopState.Close: + // 売り切れの場合帰る + customerController.ChangeCustomerState(CustomerState.Leave); + break; + default: + throw new ArgumentOutOfRangeException(nameof(x), x, null); + } + }).AddTo(customerController); + }).AddTo(this); + + requestSubject.Subscribe(customerController => { - return 0; - }); - var walkerObservable = Observable.Timer(TimeSpan.FromSeconds(2f), TimeSpan.FromSeconds(5f)) + // 売り切れ + if (gameData.ShopStock.Count == 0) + { + shopState.Value = ShopState.Close; + return; + } + // shuffledOrder順に販売 + Debug.Log(shuffledOrder.Aggregate("", (s, i) => s + i)); + var orderNum = shuffledOrder[0]; + shuffledOrder.RemoveAt(0); + // コーンの味吹き出しを設定 + customerController.ChangeWantFlavor(displayFlavors[orderNum]); + this.CallWaitForSeconds(1.5f, () => + { + // 購入 + SellPopcorn(orderNum); + blueView.SellAction(); + // 自動補充 refill + RefillOneProduct(); + StockFlavorLog(); + var setStockFlag = false; + // 補充された場合フレーバー再設定 + if (gameData.ShopStock.Count == ShopStockCount) + { + shuffledOrder.Add(orderNum); + displayFlavors[orderNum] = gameData.ShopStock.Last(); + } + else if (gameData.ShopStock.Count <= 13 && shuffledOrder.Exists(x => x > 13)) + { + displayFlavors = gameData.ShopStock.Select(x => x).ToList(); + shuffledOrder = ShuffleOrder(displayFlavors.Count); + setStockFlag = true; + } + else if (gameData.ShopStock.Count <= 7 && shuffledOrder.Exists(x => x > 7)) + { + displayFlavors = gameData.ShopStock.Select(x => x).ToList(); + shuffledOrder = ShuffleOrder(displayFlavors.Count); + setStockFlag = true; + } + + // 表示更新 + this.CallWaitForSeconds(1f, () => + { + var heartAnimation = customerController.GetComponent(); + heartAnimation.GetHeart(() => + { + HeartMeter.Instance.AddHeart(3); + }); + customerController.ChangeCustomerState(CustomerState.EatingLeave); + + stockView.SetStock(gameData.StorageTanks); + if (gameData.ShopStock.Count == ShopStockCount) + { + // 補充したフレーバーのスキンを設定 + cartView.Refill(orderNum, displayFlavors[orderNum]); + } + else if (setStockFlag) + { + cartView.SetStock(displayFlavors); + } + }); + shopState.Value = gameData.ShopStock.Count == 0 ? ShopState.Close : ShopState.Open; + }); + }).AddTo(this); + + // お客さん出現タイマー(店舗レベル連動 + var changeCustomerFlowObservable = HeartMeter.Instance.ShopLevel + .Select(x => (float)60 * 10 / shopLevelList.First(y => y.level == x).tenMinCustomer); // 10分間期待値から来客の間隔を算出 + var customerObservable = changeCustomerFlowObservable + .Select(x => Observable.Interval(TimeSpan.FromSeconds(x)) + .Select(_ => + { + Debug.Log($"customer:{GetHashCode()}"); + // 一般客orセレブ + // 複数パターンある場合ChooseRandom + return (isCustomer: true, isSpecial: false); + })) + .Switch(); + + // 歩行者出現頻度、立ち止まり確率も設定(歩行者タイマー1分間に6人 + var walkerObservable = Observable.Timer(TimeSpan.FromSeconds(2f), TimeSpan.FromSeconds(10f)) .Select(x => { - return 0; + Debug.Log($"walker:{GetHashCode()}"); + // 一般客orセレブ + // 複数パターンある場合ChooseRandom + return (isCustomer: false, isSpecial: false); }); - Observable.Merge(customerObservable, walkerObservable) - // .Take(5) - .Subscribe(_ => + + // 宣伝時、タップすると60秒だけ稼働するストリーム + // タップ, リアクティブコマンドで60秒押せない,その後復活 + var adClickObservable = new Subject(); + adClickObservable.AddTo(this); + var adWalkerObservable = Observable.Interval(TimeSpan.FromSeconds(3f)) + .Take(20) + .Select(x => { - var customer = Instantiate(customerPrefab); - var heartAnimation = customer.GetComponent(); - var customerController = customer.GetComponent(); - customerController.Setup(); - if (Random.value < .4f) + Debug.Log($"adWalker"); + return (isCustomer: false, isSpecial: false); + }); + var adClickWalkerObservable = adClickObservable + .Do(_ => { Debug.Log($"clicked");}) + .Delay(TimeSpan.FromSeconds(2f)) + .Select(x => adWalkerObservable).Switch(); + // Observable.Timer(TimeSpan.FromSeconds(3f)).Subscribe(_ => { adClickObservable.OnNext(default); }).AddTo(this); + + // キャラ生成 + Observable.Merge(walkerObservable, customerObservable) + // .Merge(adClickWalkerObservable) + .Subscribe(x => + { + var customer = Instantiate(customerPrefab); + var customerController = customer.GetComponent(); + customerController.Setup(); + customerController.MoveEndObservable.SkipLatestValueOnSubscribe().DistinctUntilChanged().Subscribe(type => + { + // Debug.Log($"move end {type}"); + switch (type) { - customerController.AddMove(CustomerMovingType.WalkSide); + case CustomerMovingType.WalkSide: + case CustomerMovingType.WalkSideEat: + customerList.Remove(customerController); + Destroy(customer); + break; + case CustomerMovingType.StayBack: + requestSubject.OnNext(customerController); + break; + default: + break; } - else + }).AddTo(customerController); + + if (x.isCustomer) + { + // 購入客リスト追加 + customerList.Add(customerController); + } + else + { + // 歩行者はタップ後購入客 + customerController.ChangeCustomerState(CustomerState.Walk); + var eventTrigger = customer.transform.GetChild(0).gameObject.AddComponent(); + eventTrigger.OnPointerClickAsObservable().Take(1).Subscribe(_ => { - customerController.AddMove(CustomerMovingType.WalkCenter); - customerController.AddMove(CustomerMovingType.WalkBack); - customerController.AddMove(CustomerMovingType.StayBack); - } - customerController.OrderObservable.Subscribe(__ => - { - // 購入 - if (gameData.ShopStock.Count == 0) - { - customerController.AddMove(CustomerMovingType.WalkFront); - customerController.AddMove(CustomerMovingType.WalkSide); - return; - } - // shuffledOrder順に販売 - var orderNum = shuffledOrder[0]; - shuffledOrder.RemoveAt(0); - // コーンの味吹き出しを設定 - customerController.ChangeWantFlavor(displayFlavors[orderNum]); - this.CallWaitForSeconds(2f, () => - { - SellPopcorn(orderNum); - blueView.SellAction(); - this.CallWaitForSeconds(2f, () => - { - heartAnimation.GetHeart(() => - { - HeartMeter.Instance.AddHeart(3); - }); - customerController.AddMove(CustomerMovingType.WalkFrontEat); - customerController.AddMove(CustomerMovingType.WalkSideEat); - Destroy(customer.gameObject, 10f); - }); - }); - }); - }).AddTo(this); + customerList.Add(customerController); + }).AddTo(customerController); + } + }).AddTo(this); } private void SellPopcorn(int orderNum) @@ -134,45 +312,6 @@ public class Market : MonoBehaviour CoinManager.Instance.AddCoinWithEffect(flavor.Price * (1 + bonusRate / 100), () => { }); gameData.coin = CoinManager.Instance.OwnCoin; GameDataManager.SaveGameData(); - - // 自動補充 refill - RefillOneProduct(); - var setStockFlag = false; - // 補充された場合フレーバー再設定 - if (gameData.ShopStock.Count == ShopStockCount) - { - shuffledOrder.Add(orderNum); - displayFlavors[orderNum] = gameData.ShopStock.Last(); - } - else if (gameData.ShopStock.Count <= 13 && shuffledOrder.Exists(x => x > 13)) - { - displayFlavors = gameData.ShopStock.Select(x => x).ToList(); - shuffledOrder = ShuffleOrder(displayFlavors.Count); - setStockFlag = true; - } - else if (gameData.ShopStock.Count <= 7 && shuffledOrder.Exists(x => x > 7)) - { - displayFlavors = gameData.ShopStock.Select(x => x).ToList(); - shuffledOrder = ShuffleOrder(displayFlavors.Count); - setStockFlag = true; - } - - // 表示更新 - this.CallWaitForSeconds(1f, () => - { - stockView.SetStock(gameData.StorageTanks); - if (gameData.ShopStock.Count == ShopStockCount) - { - // 補充したフレーバーのスキンを設定 - cartView.Refill(orderNum, displayFlavors[orderNum]); - } - else if (setStockFlag) - { - cartView.SetStock(displayFlavors); - } - }); - - StockFlavorLog(); } private List ShuffleOrder(int length) @@ -199,7 +338,7 @@ public class Market : MonoBehaviour GameDataManager.SaveGameData(); } - private void FixStock() + private void CheckAndFixStock() { if (GameDataManager.GameData.ShopStock.Count > ShopStockCount) { diff --git a/popcorn/Assets/MyGame/Scenes/marketing/marketing.unity b/popcorn/Assets/MyGame/Scenes/marketing/marketing.unity index 447a982e..6ef659a8 100644 --- a/popcorn/Assets/MyGame/Scenes/marketing/marketing.unity +++ b/popcorn/Assets/MyGame/Scenes/marketing/marketing.unity @@ -1601,6 +1601,7 @@ GameObject: - component: {fileID: 658354830} - component: {fileID: 658354829} - component: {fileID: 658354828} + - component: {fileID: 658354831} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -1673,6 +1674,22 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &658354831 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 658354827} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 56666c5a40171f54783dd416a44f42bf, type: 3} + m_Name: + m_EditorClassIdentifier: + m_EventMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_MaxRayIntersections: 0 --- !u!1 &676633148 GameObject: m_ObjectHideFlags: 0 @@ -11566,7 +11583,7 @@ PrefabInstance: - target: {fileID: 5409985849651702441, guid: 6fbb038c9aae840f2bea57bce30740f7, type: 3} propertyPath: m_LocalPosition.y - value: -0.02 + value: -1.07 objectReference: {fileID: 0} - target: {fileID: 5409985849651702441, guid: 6fbb038c9aae840f2bea57bce30740f7, type: 3} diff --git a/popcorn/Assets/MyGame/Scripts/HeartMeter.cs b/popcorn/Assets/MyGame/Scripts/HeartMeter.cs index 6c911e6c..1278ab2e 100644 --- a/popcorn/Assets/MyGame/Scripts/HeartMeter.cs +++ b/popcorn/Assets/MyGame/Scripts/HeartMeter.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using System.Linq; using TMPro; +using UniRx; using UnityEngine; using UnityEngine.UI; @@ -9,50 +11,61 @@ public class HeartMeter : SingletonMonoBehaviour [SerializeField] private Slider slider; [SerializeField] private TextMeshProUGUI heartLevel; + private Coroutine coroutine; private List levelList = new List(); private int currentHeartCount; - private float tmpHeart; - private Coroutine coroutine; + private readonly ReactiveProperty viewHeartCount = new ReactiveProperty(); + public IReadOnlyReactiveProperty ShopLevel => shopLevel; + private readonly ReactiveProperty shopLevel = new ReactiveProperty(); + private CompositeDisposable compositeDisposable = new CompositeDisposable(); + + private void Awake() + { + if (CheckInstance()) return; + } + + private void Start() + { + shopLevel.AddTo(this); + viewHeartCount.AddTo(this); + compositeDisposable.AddTo(this); + } public void Initialize(List list) { levelList = list; + compositeDisposable.Clear(); + shopLevel.Subscribe(x => + { + heartLevel.text = $"{x}"; + }).AddTo(compositeDisposable); + viewHeartCount.SkipLatestValueOnSubscribe().Subscribe(heartCount => + { + if (levelList.Empty()) + { + return; + } + shopLevel.Value = GetShopLevel(Mathf.FloorToInt(heartCount)) + 1; + if (levelList.Count == shopLevel.Value) + { + slider.value = 1; + } + else + { + slider.value = (heartCount - levelList[shopLevel.Value - 1]) / (levelList[shopLevel.Value] - levelList[shopLevel.Value - 1]); + } + }).AddTo(compositeDisposable); } public void SetHeart(int heartCount) { - Debug.Log($"{currentHeartCount}, {tmpHeart}"); currentHeartCount = heartCount; - tmpHeart = heartCount; - SetView(currentHeartCount); + viewHeartCount.SetValueAndForceNotify(heartCount); } - private void SetView(float heartCount) + private int GetShopLevel(int heartCount) { - var index = GetNextLevel(Mathf.FloorToInt(heartCount)); - SetLevelView(index); - SetMeterView(heartCount, index); - } - - private void SetLevelView(int level) - { - heartLevel.text = $"{level}"; - } - - private void SetMeterView(float heartCount, int index) - { - - slider.value = (heartCount - levelList[index - 1]) / (levelList[index] - levelList[index - 1]); - } - - private int GetNextLevel(int heartCount) - { - var index = levelList.FindIndex(x => x > heartCount); - if (levelList.Last() < heartCount) - { - index = levelList.Count - 1; - } - return index; + return levelList.FindLastIndex(x => x <= heartCount); } public void AddHeart(int value) @@ -65,8 +78,7 @@ public class HeartMeter : SingletonMonoBehaviour }); this.CallLerp(1f, f => { - tmpHeart += value * Time.deltaTime; - SetView(Mathf.Min(currentHeartCount, tmpHeart)); + viewHeartCount.Value = Mathf.Min(currentHeartCount, viewHeartCount.Value + value * Time.deltaTime); }); } } \ No newline at end of file