备份CatanBuilding瘦身独立工程
This commit is contained in:
216
Assets/Scripts/InfiniteBuilding/Block.cs
Normal file
216
Assets/Scripts/InfiniteBuilding/Block.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using DG.Tweening;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
public class Block : MonoBehaviour
|
||||
{
|
||||
private Rigidbody2D _rb;
|
||||
private BoxCollider2D _bc;
|
||||
public BlockState State;
|
||||
private bool _freezable = false;
|
||||
private Tables _tables;
|
||||
private InfiniteBuildingConf _cfg;
|
||||
public int Idx;
|
||||
public IEventAggregator EventAggregator;
|
||||
public bool Freezable => _freezable;
|
||||
//private Transform _focus;
|
||||
public Rigidbody2D Rb => _rb;
|
||||
private List<Furniture> _furnitureList;
|
||||
private class Furniture
|
||||
{
|
||||
public readonly GameObject Go;
|
||||
public readonly Vector3 TargetScale;
|
||||
public Furniture(GameObject go, Vector3 targetScale)
|
||||
{
|
||||
Go = go;
|
||||
TargetScale = targetScale;
|
||||
}
|
||||
}
|
||||
public float Height
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_tables.TbConstructionUnits.DataMap.ContainsKey(Idx)) return _tables.TbConstructionUnits[Idx].Height;
|
||||
Debug.LogError($"Block index {Idx} is not in the table.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
public float Width => _bc.size.x;
|
||||
public float WorldHeight => transform.position.y + _bc.offset.y + _bc.size.y / 2;
|
||||
public bool IsCurrentBlockStill
|
||||
=> Rb.velocity.magnitude <= _cfg.blockFreezeVelocity
|
||||
&& Mathf.Abs(Rb.angularVelocity) <= _cfg.blockFreezeAngularVelocity
|
||||
&& _acc.magnitude <= _cfg.blockFreezeAcc
|
||||
&& Mathf.Abs(_angularAcc) <= _cfg.blockFreezeAngularAcc;
|
||||
|
||||
public int FallPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
Assert.IsTrue(_tables.TbConstructionUnits.DataMap.ContainsKey(Idx),
|
||||
$"Block index {Idx} is not in the table.");
|
||||
return _tables.TbConstructionUnits[Idx].FallPoint;
|
||||
}
|
||||
}
|
||||
public int StackPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
Assert.IsTrue(_tables.TbConstructionUnits.DataMap.ContainsKey(Idx),
|
||||
$"Block index {Idx} is not in the table.");
|
||||
return _tables.TbConstructionUnits[Idx].StackPoint;
|
||||
}
|
||||
}
|
||||
private void Awake()
|
||||
{
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
_bc = GetComponent<BoxCollider2D>();
|
||||
_tables = GContext.container.Resolve<Tables>();
|
||||
}
|
||||
private Vector2 previousVelocity, _acc;
|
||||
private float previousAngularVelocity, _angularAcc;
|
||||
public Vector2 Acc => _acc;
|
||||
public float AngularAcc => _angularAcc;
|
||||
private void Start()
|
||||
{
|
||||
previousAngularVelocity = _rb.angularVelocity;
|
||||
previousVelocity = _rb.velocity;
|
||||
}
|
||||
private void FixedUpdate()
|
||||
{
|
||||
_acc = (_rb.velocity - previousVelocity) / Time.fixedDeltaTime;
|
||||
_angularAcc = (_rb.angularVelocity - previousAngularVelocity) / Time.fixedDeltaTime;
|
||||
previousVelocity = _rb.velocity;
|
||||
previousAngularVelocity = _rb.angularVelocity;
|
||||
}
|
||||
public void InitHangingBlock(BlockState s, int idx, IEventAggregator ea, InfiniteBuildingConf config)
|
||||
{
|
||||
State = BlockState.Hanging;
|
||||
_furnitureList = new List<Furniture>();
|
||||
GetFurnitures(transform, 0, _furnitureList);
|
||||
State = s;
|
||||
Idx = idx;
|
||||
EventAggregator = ea;
|
||||
_cfg = config;
|
||||
foreach (var fur in _furnitureList)
|
||||
SetFurnitureScale(fur, 0);
|
||||
}
|
||||
public void InitRecordBlock(InfiniteBuildingConf config)
|
||||
{
|
||||
_cfg = config;
|
||||
_furnitureList = new List<Furniture>();
|
||||
GetFurnitures(transform, 0, _furnitureList);
|
||||
}
|
||||
private void OnCollisionEnter2D(Collision2D collision)
|
||||
{
|
||||
//Debug.Log($"<color=red>Play audio from {gameObject.name} to {collision.gameObject.name}</color>");
|
||||
int a = gameObject.GetHashCode();
|
||||
int b = collision.gameObject.GetHashCode();
|
||||
if (a > b)
|
||||
(a, b) = (b, a);
|
||||
string hash = string.Format("{0}{1}", a, b);
|
||||
EventAggregator.Publish(new EventInfiniteBuildingCollisionSound(hash));
|
||||
if (_freezable == false && State == BlockState.Free)
|
||||
EventAggregator.Publish(new EventInfiniteBuildingFirstCollision(this));
|
||||
_freezable = true;
|
||||
}
|
||||
private void OnCollisionExit2D(Collision2D collision)
|
||||
{
|
||||
//Debug.Log($"<color=blue>Detach audio from {gameObject.name} to {collision.gameObject.name}</color>");
|
||||
}
|
||||
private int targetDepth = 2;
|
||||
private void GetFurnitures(Transform parent, int currentDepth, List<Furniture> result)
|
||||
{
|
||||
if (currentDepth == targetDepth)
|
||||
{
|
||||
result.Add(new Furniture(parent.gameObject, parent.gameObject.transform.localScale));
|
||||
return;
|
||||
}
|
||||
foreach (Transform child in parent)
|
||||
{
|
||||
GetFurnitures(child, currentDepth + 1, result);
|
||||
}
|
||||
}
|
||||
private void SetFurnitureScale(Furniture f, float scale)
|
||||
{
|
||||
if (!f.Go.name.StartsWith("B999_glass"))
|
||||
f.Go.transform.localScale = f.TargetScale * scale;
|
||||
}
|
||||
public void PlayFurnitureAnimation()
|
||||
{
|
||||
foreach (var fur in _furnitureList)
|
||||
{
|
||||
if (fur.Go.name.StartsWith("B999_glass"))
|
||||
StartCoroutine(GlassTransfer(fur));
|
||||
else
|
||||
fur.Go.transform.DOScale(fur.TargetScale,
|
||||
Random.Range(_cfg.animationDurationRange.x, _cfg.animationDurationRange.y));
|
||||
}
|
||||
}
|
||||
private IEnumerator GlassTransfer(Furniture f)
|
||||
{
|
||||
yield return new WaitForSeconds(_cfg.animationDurationRange.y);
|
||||
Material mat = f.Go.GetComponent<MeshRenderer>().material;
|
||||
float t = 0;
|
||||
while (t <= _cfg.animationDurationRange.z)
|
||||
{
|
||||
t += Time.deltaTime;
|
||||
mat.SetColor("_EmissionColor", Color.Lerp(Color.black, _cfg.glassColor,
|
||||
t / _cfg.animationDurationRange.z));
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
public void LitBlock()
|
||||
{
|
||||
foreach (var fur in _furnitureList)
|
||||
{
|
||||
if (fur.Go.name.StartsWith("B999_glass"))
|
||||
fur.Go.GetComponent<MeshRenderer>().material
|
||||
.SetColor("_EmissionColor", _cfg.glassColor);
|
||||
}
|
||||
}
|
||||
public void Drop()
|
||||
{
|
||||
//_djl.breakForce = 0;
|
||||
//_djr.breakForce = 0;
|
||||
State = BlockState.Free;
|
||||
Rb.drag = 0;
|
||||
//DestroyCountDown();
|
||||
}
|
||||
public void Rest()
|
||||
{
|
||||
//_cts.Cancel();
|
||||
//_cts.Dispose();
|
||||
State = BlockState.Resting;
|
||||
//_rb.velocity = Vector3.zero;
|
||||
//_rb.isKinematic = true;
|
||||
//Debug.Log(_focus.position);
|
||||
//Debug.Log(Height);
|
||||
//_rb.MovePosition(new Vector2(_rb.position.x, _focus.position.y));
|
||||
//OnRest?.Invoke(delta);
|
||||
}
|
||||
//public void DestroySelf()
|
||||
//{
|
||||
// Debug.Log($"awsl {gameObject}");
|
||||
// try
|
||||
// {
|
||||
// _cts?.Cancel();
|
||||
// _cts?.Dispose();
|
||||
// }
|
||||
// catch(ObjectDisposedException e)
|
||||
// {
|
||||
// Debug.Log($"source disposed: {e}");
|
||||
// }
|
||||
// if (_state == BlockState.Free)
|
||||
// OnDestroy?.Invoke();
|
||||
// Destroy(gameObject);
|
||||
//}
|
||||
}
|
||||
public enum BlockState
|
||||
{
|
||||
Hanging, Free, Resting, Locked
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/Block.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/Block.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ba06163a44f9bd40a3df71c58a8be15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
17
Assets/Scripts/InfiniteBuilding/BlockDeathNotifier.cs
Normal file
17
Assets/Scripts/InfiniteBuilding/BlockDeathNotifier.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using asap.core;
|
||||
using UnityEngine;
|
||||
|
||||
public class BlockDeathNotifier : MonoBehaviour
|
||||
{
|
||||
private EventAggregator _eventAggregator;
|
||||
public void Init(EventAggregator e)
|
||||
{
|
||||
_eventAggregator = e;
|
||||
}
|
||||
private void OnTriggerEnter2D(Collider2D collision)
|
||||
{
|
||||
if (collision.gameObject.TryGetComponent(out Block b))
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingBlockDeath(b.State));
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Scripts/InfiniteBuilding/BlockDeathNotifier.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/BlockDeathNotifier.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7483ff4d84b7f8458273fd57fdb8fb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
338
Assets/Scripts/InfiniteBuilding/BlockManager.cs
Normal file
338
Assets/Scripts/InfiniteBuilding/BlockManager.cs
Normal file
@@ -0,0 +1,338 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using cfg;
|
||||
using asap.core;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
public class BlockManager : MonoBehaviour
|
||||
{
|
||||
private Dictionary<string, GameObject> _blockPrefabs = new Dictionary<string, GameObject>();
|
||||
//[SerializeField] private BoxCollider2D _deathWall;
|
||||
[SerializeField] List<Block> _blocks = new List<Block>();
|
||||
[SerializeField] private Transform _focus;
|
||||
public Block CurrentBlock;
|
||||
private TbConstructionBasicUnits _blockTypesTable;
|
||||
private TbConstructionUnits _blocksTable;
|
||||
private TbConstructionHeightEvent _heightEventTable;
|
||||
private InfiniteBuildingConf _cfg;
|
||||
private InfiniteBuildingData _data;
|
||||
private EventAggregator _eventAggregator;
|
||||
private List<AsyncOperationHandle> _prefabOps;
|
||||
public List<Block> Blocks => _blocks;
|
||||
private void Start()
|
||||
{
|
||||
_blockTypesTable = GContext.container.Resolve<Tables>().TbConstructionBasicUnits;
|
||||
_blocksTable = GContext.container.Resolve<Tables>().TbConstructionUnits;
|
||||
_prefabOps = new List<AsyncOperationHandle>();
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
foreach (var op in _prefabOps)
|
||||
Addressables.Release(op);
|
||||
}
|
||||
public void Init(InfiniteBuildingConf cfg, InfiniteBuildingData data, EventAggregator ea)
|
||||
{
|
||||
_cfg = cfg;
|
||||
_data = data;
|
||||
_eventAggregator = ea;
|
||||
_heightEventTable = GContext.container.Resolve<Tables>().TbConstructionHeightEvent;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get prefab according to PrefabID, will be used in init and block generation
|
||||
/// </summary>
|
||||
/// <param name="id">name of the prefab in addressables</param>
|
||||
/// <returns>the prefab GameObject</returns>
|
||||
private async System.Threading.Tasks.Task<GameObject> GetBlockPrefab(string id)
|
||||
{
|
||||
if (_blockPrefabs.TryGetValue(id, out var prefab))
|
||||
return prefab;
|
||||
_prefabOps.Add(Addressables.LoadAssetAsync<object>(id));
|
||||
var go = (GameObject) await _prefabOps[^1].Task;
|
||||
_blockPrefabs.Add(id, go);
|
||||
return go;
|
||||
}
|
||||
private int GetRandomIDFromWeightTable(Dictionary<int, float> weightTable)
|
||||
{
|
||||
Dictionary<int, float> weightSum = new Dictionary<int, float>();
|
||||
float sum = 0;
|
||||
foreach (var e in weightTable)
|
||||
{
|
||||
sum += e.Value;
|
||||
weightSum.Add(e.Key, sum);
|
||||
}
|
||||
float randomNum = UnityEngine.Random.Range(0, sum);
|
||||
foreach (var e in weightSum)
|
||||
{
|
||||
if (randomNum <= e.Value)
|
||||
{
|
||||
return e.Key;
|
||||
}
|
||||
}
|
||||
Debug.LogError($"Random ID not available. WeightTable entries count: {weightTable.Count}.");
|
||||
return -1;
|
||||
}
|
||||
public async System.Threading.Tasks.Task<Block> GenerateBlock(Vector3 spawnPos, bool isFirst = false)
|
||||
{
|
||||
Block generatedBlock;
|
||||
Dictionary<int, float> weightTable = new Dictionary<int, float>();
|
||||
//_crane.ResetPosition();
|
||||
//await Awaiters.NextFrame;
|
||||
int type, block;
|
||||
foreach (var bt in _blockTypesTable.DataList)
|
||||
{
|
||||
weightTable.Add(bt.ID, bt.Weight);
|
||||
}
|
||||
type = GetRandomIDFromWeightTable(weightTable);
|
||||
weightTable.Clear();
|
||||
foreach (int blockID in _blockTypesTable[type].UnitList)
|
||||
{
|
||||
if (_data.Lvl < _blocksTable[blockID].UnlockedHeight)
|
||||
continue;
|
||||
weightTable.Add(blockID, _blocksTable[blockID].Weight);
|
||||
}
|
||||
block = GetRandomIDFromWeightTable(weightTable);
|
||||
if (isFirst && _data.LastHangingBlock != -1)
|
||||
{
|
||||
block = _data.LastHangingBlock;
|
||||
_data.LastHangingBlock = -1;
|
||||
}
|
||||
TbConstructionInfiniteInit initTable = GContext.container.Resolve<Tables>().TbConstructionInfiniteInit;
|
||||
if (_data.Lvl < initTable.DataList.Count)
|
||||
block = GContext.container.Resolve<Tables>().TbConstructionInfiniteInit.DataList[_data.Lvl].UnitID;
|
||||
#if UNITY_EDITOR
|
||||
if (_cfg.NextBlockToSpawn != -1 && _blocksTable.DataMap.ContainsKey(_cfg.NextBlockToSpawn))
|
||||
block = _cfg.NextBlockToSpawn;
|
||||
#endif
|
||||
string id = _blocksTable[block].Prefab;
|
||||
GameObject prefab = await GetBlockPrefab(id);
|
||||
//GameObject prefab = await GetBlockPrefab("block_000");//Get test prefab
|
||||
//Debug.Log($"<color=red>{_crane.transform.position}</color>");
|
||||
//Debug.Log($"<color=red>{_cfg.blockSpawnOffset}</color>");
|
||||
generatedBlock = Instantiate(prefab, spawnPos + _blocksTable[block].Height * Vector3.down,
|
||||
prefab.transform.rotation, transform).GetComponent<Block>();
|
||||
generatedBlock.InitHangingBlock(BlockState.Hanging, block, _eventAggregator, _cfg);
|
||||
generatedBlock.Rb.angularDrag = GetDataByIBLvl(_data.Lvl, _heightEventTable.DataList).AngularDrag;
|
||||
generatedBlock.Rb.drag = GetDataByIBLvl(_data.Lvl, _heightEventTable.DataList).LinearDrag;
|
||||
//_currentBlock.SetParams(_cfg, _deathWall.name, block, _focus);
|
||||
//generatedBlock.OnRest += async d => await OnBlockRest(d);
|
||||
//generatedBlock.OnDestroy += async () => await OnBlockDestroy();
|
||||
//_currentBlock.AttachJoints(_crane);
|
||||
//_crane.AttachJoints(generatedBlock);
|
||||
//await _crane.Descend();
|
||||
//if (doSwitchState)
|
||||
// _stateMachine.SetState(EInfiniteBuildingState.PlayerCtrl);
|
||||
return generatedBlock;
|
||||
}
|
||||
private async System.Threading.Tasks.Task<GameObject> GenerateBlock(InfiniteBuildingData.BlockRecord record, IEventAggregator ea)
|
||||
{
|
||||
GameObject b = Instantiate(await GetBlockPrefab(record.PrefabID),
|
||||
new Vector3(record.Pos.x, record.Pos.y, _cfg.blockDepth), Quaternion.identity, transform);
|
||||
b.GetComponent<Rigidbody2D>().isKinematic = true;
|
||||
b.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
|
||||
b.GetComponent<Block>().Idx = record.ID;
|
||||
b.GetComponent<Block>().EventAggregator = ea;
|
||||
//_blocks[^1].SetParams(_cfg, _deathWall.name, record.id, _focus);
|
||||
return b;
|
||||
}
|
||||
|
||||
public int GetExcellentScore()
|
||||
{
|
||||
int fallingBlockScore = _blocksTable[CurrentBlock.Idx].FallPoint;
|
||||
int stackedBlockScore = _blocks is { Count: > 0 } ? _blocksTable[_blocks[^1].Idx].StackPoint : 0;
|
||||
// Debug.Log($"<color=red>Incoming: {fallingBlockScore}, stacked: {stackedBlockScore}</color>");
|
||||
return fallingBlockScore + stackedBlockScore;
|
||||
}
|
||||
public bool TrySnap()
|
||||
{
|
||||
if (_blocks is not { Count: > 0 })
|
||||
{
|
||||
if (Mathf.Abs(CurrentBlock.Rb.position.x - _focus.position.x) > _cfg.snapThresh)
|
||||
return false;
|
||||
CurrentBlock.Rb.MovePosition(new Vector2(_focus.position.x, CurrentBlock.Rb.position.y));
|
||||
return true;
|
||||
}
|
||||
if (Mathf.Abs(CurrentBlock.Rb.position.x - _blocks[^1].Rb.position.x) > _cfg.snapThresh)
|
||||
return false;
|
||||
CurrentBlock.Rb.MovePosition(new Vector2(_blocks[^1].Rb.position.x, CurrentBlock.Rb.position.y));
|
||||
return true;
|
||||
}
|
||||
public async void AlignBlocks(IEventAggregator ea)
|
||||
{
|
||||
Block b;
|
||||
for (int j = _blocks.Count - 1; j >= 0; j--)
|
||||
{
|
||||
b = _blocks[j];
|
||||
//_blocks.RemoveAt(j);
|
||||
if (b != null)
|
||||
Destroy(b.gameObject);
|
||||
}
|
||||
Vector3 pivot = _focus.position;
|
||||
for (int i = _data.Record.Count - 1; i >= 0; i--)
|
||||
{
|
||||
InfiniteBuildingData.BlockRecord r = _data.Record[i];
|
||||
b = Instantiate(await GetBlockPrefab(r.PrefabID),
|
||||
pivot + r.Height * Vector3.down,
|
||||
Quaternion.identity, transform).GetComponent<Block>();
|
||||
pivot += r.Height * Vector3.down;
|
||||
//_blocks[_data.Record.Count - 1 - i] = b;
|
||||
_blocks[i] = b;
|
||||
b.Rb.isKinematic = true;
|
||||
b.Rb.velocity = Vector2.zero;
|
||||
b.Idx = r.ID;
|
||||
b.EventAggregator = ea;
|
||||
}
|
||||
for (int i = _blocks.Count - 1; i >= 0; i--)
|
||||
{
|
||||
b = _blocks[i];
|
||||
if (b.WorldHeight < _focus.position.y + _cfg.blockDestroyOffset)
|
||||
{
|
||||
_blocks.RemoveAt(i);
|
||||
Destroy(b.gameObject);
|
||||
}
|
||||
else if (b.WorldHeight < _focus.position.y + _cfg.blockRestingOffset)
|
||||
{
|
||||
b.Rb.isKinematic = true;
|
||||
b.State = BlockState.Locked;
|
||||
}
|
||||
else
|
||||
{
|
||||
b.Rb.isKinematic = false;
|
||||
b.State = BlockState.Resting;
|
||||
}
|
||||
}
|
||||
//for (int i = 0; i < _blocks.Count; i++)
|
||||
//{
|
||||
// if (_blocks[i] == null)
|
||||
// continue;
|
||||
// _blocks[i].Rb.MovePosition(new Vector2(0, _data.Record[i].pos.y));
|
||||
//}
|
||||
}
|
||||
private float _blockDestructionTimer = 1000f;
|
||||
public void BlockFallFixedUpdate()
|
||||
{
|
||||
float rot = CurrentBlock.Rb.rotation;
|
||||
_blockDestructionTimer -= Time.fixedDeltaTime;
|
||||
if (_blockDestructionTimer < 0)
|
||||
{
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingFail());
|
||||
return;
|
||||
}
|
||||
if (!CurrentBlock.Freezable || !CurrentBlock.IsCurrentBlockStill)
|
||||
return;
|
||||
|
||||
if ((rot <= _cfg.blockDestroyThreshAngle && rot > -_cfg.blockDestroyThreshAngle)
|
||||
|| (rot >= 180 - _cfg.blockDestroyThreshAngle && rot <= 180)
|
||||
|| (rot >= -180 && rot <= -180 + _cfg.blockDestroyThreshAngle))
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingSucceed());
|
||||
else
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingFail());
|
||||
}
|
||||
public void StartDestroyCountDown()
|
||||
{
|
||||
//Debug.Log("111111111111111");
|
||||
_blockDestructionTimer = _cfg.blockDestroyDelay;
|
||||
}
|
||||
public void ResetDestroyCountDown()
|
||||
{
|
||||
_blockDestructionTimer = float.PositiveInfinity;
|
||||
}
|
||||
public void AddCurrentBlock()
|
||||
{
|
||||
_blocks.Add(CurrentBlock);
|
||||
}
|
||||
private void CurrentBlockFail()
|
||||
{
|
||||
Debug.Log("Build failure.");
|
||||
}
|
||||
/// <summary>
|
||||
/// Lock or clear blocks according to their height, need focus updated first
|
||||
/// </summary>
|
||||
public void LockOrClearBlocks(bool isFilterOnly = false)
|
||||
{
|
||||
for (int i = _blocks.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Block b = _blocks[i];
|
||||
if (b.WorldHeight < _cfg.blockDestroyOffset + _focus.position.y)
|
||||
{
|
||||
_blocks.RemoveAt(i);
|
||||
Destroy(b.gameObject);
|
||||
}
|
||||
else if (b.WorldHeight < _cfg.blockRestingOffset + _focus.position.y )
|
||||
{
|
||||
b.Rb.velocity = Vector2.zero;
|
||||
b.Rb.rotation = 0;
|
||||
b.Rb.angularVelocity = 0;
|
||||
b.Rb.isKinematic = true;
|
||||
}
|
||||
else if (!isFilterOnly)
|
||||
b.Rb.isKinematic = false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Clear stage, generate blocks according to data, and reset focus position
|
||||
/// </summary>
|
||||
/// <returns>Task</returns>
|
||||
public async System.Threading.Tasks.Task RebuildAllBlocks()
|
||||
{
|
||||
//clear the act
|
||||
if (CurrentBlock != null)
|
||||
Destroy(CurrentBlock.gameObject);
|
||||
await RebuildBlocks();
|
||||
}
|
||||
/// <summary>
|
||||
/// reset stage, bug leave the current block alone
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async System.Threading.Tasks.Task RebuildBlocks(bool doesLockAll = false)
|
||||
{
|
||||
Block b;
|
||||
for (int j = _blocks.Count - 1; j >= 0; j--)
|
||||
{
|
||||
b = _blocks[j];
|
||||
_blocks.RemoveAt(j);
|
||||
if (b != null)
|
||||
Destroy(b.gameObject);
|
||||
}
|
||||
//regenerate
|
||||
_focus.position = new Vector3(_focus.position.x, 0, _focus.position.z);
|
||||
foreach (var record in _data.Record)
|
||||
{
|
||||
b = (await GenerateBlock(record, _eventAggregator)).GetComponent<Block>();
|
||||
b.InitRecordBlock(_cfg);
|
||||
b.LitBlock();
|
||||
_blocks.Add(b);
|
||||
if (_focus.position.y < b.WorldHeight)
|
||||
_focus.position = new Vector3(_focus.position.x, b.WorldHeight, _focus.position.z);
|
||||
}
|
||||
for (int i = _blocks.Count - 1; i >= 0; i--)
|
||||
{
|
||||
b = _blocks[i];
|
||||
if (b.WorldHeight < _focus.position.y + _cfg.blockDestroyOffset)
|
||||
{
|
||||
_blocks.RemoveAt(i);
|
||||
Destroy(b.gameObject);
|
||||
}
|
||||
else if (b.WorldHeight < _focus.position.y + _cfg.blockRestingOffset || doesLockAll)
|
||||
{
|
||||
b.Rb.isKinematic = true;
|
||||
b.State = BlockState.Locked;
|
||||
}
|
||||
else
|
||||
{
|
||||
b.Rb.isKinematic = false;
|
||||
b.State = BlockState.Resting;
|
||||
}
|
||||
}
|
||||
}
|
||||
private ConstructionHeightEvent GetDataByIBLvl(int lvl, List<ConstructionHeightEvent> dataList)
|
||||
{
|
||||
for (int i = 0; i < dataList.Count - 1; i++)
|
||||
{
|
||||
if (lvl < dataList[i + 1].Height)
|
||||
return dataList[i];
|
||||
}
|
||||
return dataList[^1];
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/BlockManager.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/BlockManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07289b2d3209cfa409936717be62c45d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
118
Assets/Scripts/InfiniteBuilding/CameraCtrl.cs
Normal file
118
Assets/Scripts/InfiniteBuilding/CameraCtrl.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using cfg;
|
||||
using asap.core;
|
||||
using PlayFab.GroupsModels;
|
||||
|
||||
public class CameraCtrl : MonoBehaviour
|
||||
{
|
||||
private Transform _focus;
|
||||
private float _blockDepth, _skyLoopTriggerheight, _skyLoopOffsetDelta;
|
||||
private MeshRenderer _sky;
|
||||
private Material _skyMat;
|
||||
private InfiniteBuildingConf _cfg;
|
||||
private InfiniteBuildingData _data;
|
||||
private List<int> _lvlThresh;
|
||||
private List<float> _depth, _yOffset;
|
||||
|
||||
private TbConstructionHeightEvent _tableHeightEvent;
|
||||
private readonly string MatOffsetKey = "_Offset";
|
||||
|
||||
//[SerializeField]private CinemachineVirtualCamera _cam;
|
||||
/* public Vector3 LowerLimit
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 pos = Camera.main.ViewportToWorldPoint(
|
||||
new Vector3(0.5f, 0, _blockDepth - transform.position.z));
|
||||
//Debug.Log(pos);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
*/
|
||||
public float CamDepth
|
||||
{
|
||||
get { return GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _depth); }
|
||||
}
|
||||
|
||||
public void Init(Transform focus, InfiniteBuildingConf cfg, MeshRenderer sky,
|
||||
InfiniteBuildingData data)
|
||||
{
|
||||
_tableHeightEvent = GContext.container.Resolve<Tables>().TbConstructionHeightEvent;
|
||||
_focus = focus;
|
||||
_blockDepth = cfg.blockDepth;
|
||||
_sky = sky;
|
||||
_skyMat = sky.sharedMaterial;
|
||||
_skyLoopTriggerheight = cfg.skyLoopTriggerHeight;
|
||||
_skyLoopOffsetDelta = cfg.skyLoopOffsetDelta;
|
||||
if (focus.position.y >= cfg.skyLoopTriggerHeight)
|
||||
{
|
||||
Vector3 pos = _sky.transform.position;
|
||||
_sky.transform.position = new Vector3(pos.x, transform.position.y, pos.z);
|
||||
}
|
||||
|
||||
_cfg = cfg;
|
||||
_data = data;
|
||||
_lvlThresh = new List<int>();
|
||||
_depth = new List<float>();
|
||||
_yOffset = new List<float>();
|
||||
foreach (var c in _tableHeightEvent.DataList)
|
||||
{
|
||||
_lvlThresh.Add(c.Height);
|
||||
_depth.Add(c.CameraDepth);
|
||||
_yOffset.Add(c.CameraYOffest);
|
||||
}
|
||||
|
||||
transform.position = new Vector3(0,
|
||||
focus.position.y + GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _yOffset),
|
||||
focus.position.z - CamDepth);
|
||||
if (_focus.position.y >= _skyLoopTriggerheight)
|
||||
_sky.transform.position =
|
||||
new Vector3(0, transform.position.y, _sky.transform.position.z);
|
||||
_skyMat.SetVector(MatOffsetKey, Vector4.zero);
|
||||
}
|
||||
|
||||
public void FollowFocus(float duration = 0.5f)
|
||||
{
|
||||
transform.DOMove(new Vector3(0,
|
||||
_focus.position.y + GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _yOffset),
|
||||
transform.position.z), duration);
|
||||
if (_focus.position.y < _skyLoopTriggerheight)
|
||||
return;
|
||||
_sky.transform.DOMove(new Vector3(0, transform.position.y, _sky.transform.position.z),
|
||||
duration);
|
||||
//Vector2 oldOffset = _skyMat.GetTextureOffset("_Texture2D");
|
||||
//Debug.Log(oldOffset);
|
||||
//_skyMat.DOOffset(oldOffset + Vector2.up * _skyLoopOffsetDelta, duration);
|
||||
Vector2 offset = _skyMat.GetVector(MatOffsetKey);
|
||||
float t = 0;
|
||||
DOTween.To(() => t, (value) => t = value, _skyLoopOffsetDelta, duration)
|
||||
.OnUpdate(() => _skyMat.SetVector(MatOffsetKey, offset + t * Vector2.up)).OnComplete(() =>
|
||||
{
|
||||
var v = _skyMat.GetVector(MatOffsetKey);
|
||||
while (v.y > 0.5f) v.y -= 1f;
|
||||
while (v.y < -0.5f) v.y += 1f;
|
||||
_skyMat.SetVector(MatOffsetKey, v);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private T GetDataByIBLvl<T>(int lvl, List<int> lvlThresh, List<T> dataList)
|
||||
{
|
||||
if (lvlThresh.Count != dataList.Count)
|
||||
{
|
||||
Debug.LogError($"lvlTresh count {lvlThresh.Count} does not" +
|
||||
$"match dataList count {dataList.Count}");
|
||||
return default(T);
|
||||
}
|
||||
|
||||
for (int i = 0; i < lvlThresh.Count - 1; i++)
|
||||
{
|
||||
if (lvl < lvlThresh[i + 1])
|
||||
return dataList[i];
|
||||
}
|
||||
|
||||
return dataList[^1];
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/CameraCtrl.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/CameraCtrl.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d4602d0c872ad44db4dadd40e89a12e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Scripts/InfiniteBuilding/CampInfoPanel.cs
Normal file
27
Assets/Scripts/InfiniteBuilding/CampInfoPanel.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class CampInfoPanel : MonoBehaviour
|
||||
{
|
||||
private TMP_Text _textPrice;
|
||||
private RewardItemNew _reward;
|
||||
private Button _btnClose;
|
||||
private void Awake()
|
||||
{
|
||||
_btnClose = transform.Find("btn_close").GetComponent<Button>();
|
||||
_textPrice = transform.Find("root/info2/btn_construct2/text_cost").GetComponent<TMP_Text>();
|
||||
_reward = transform.Find("root/info4/reward").GetComponent<RewardItemNew>();
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
_btnClose.onClick.AddListener(() => UIManager.Instance.DestroyUI(UITypes.CampInfoPanel));
|
||||
_textPrice.text = ((int) (GContext.container.Resolve<Tables>().TbMapData.DataMap[114].ConstrutionCost
|
||||
* GContext.container.Resolve<Tables>().TbConstructionInfiniteConfig.CashMagList[0])).ToString();
|
||||
_reward.SetData(GContext.container.Resolve<PlayerItemData>().GetItemDataOne(
|
||||
GContext.container.Resolve<Tables>().TbConstructionInfiniteReward[1].DropID));
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/CampInfoPanel.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/CampInfoPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95d373774d7918a4ab3dda76290aa9d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/Scripts/InfiniteBuilding/CampSettlementPanel.cs
Normal file
36
Assets/Scripts/InfiniteBuilding/CampSettlementPanel.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using asap.core;
|
||||
using cfg;
|
||||
|
||||
|
||||
public class CampSettlementPanel : BasePanel
|
||||
{
|
||||
private Button _btnClose, _btnRetry, _btnAlign;
|
||||
private TMP_Text _textAlignCost;
|
||||
//public Action Retry, Align;
|
||||
private IEventAggregator _eventAggregator;
|
||||
private void Awake()
|
||||
{
|
||||
_btnClose = transform.Find("root_fail/btn_close").GetComponent<Button>();
|
||||
_btnRetry = transform.Find("root_fail/station_advert/btn_retry/btn_green").GetComponent<Button>();
|
||||
_btnAlign = transform.Find("root_fail/station_advert/btn_fix/btn_green").GetComponent <Button>();
|
||||
_textAlignCost = transform.Find("root_fail/station_advert/btn_fix/cost/text_num").GetComponent<TMP_Text>();
|
||||
}
|
||||
public void Init(IEventAggregator ea)
|
||||
{
|
||||
_eventAggregator = ea;
|
||||
_textAlignCost.text = ConvertTools.GetNumberString(
|
||||
GContext.container.Resolve<Tables>().TbConstructionInfiniteConfig.ResetCost);
|
||||
}
|
||||
protected override void Start()
|
||||
{
|
||||
_btnClose.onClick.AddListener(
|
||||
() => _eventAggregator.Publish(new EventInfiniteBuildingRetry()));
|
||||
_btnRetry.onClick.AddListener(
|
||||
() => _eventAggregator.Publish(new EventInfiniteBuildingRetry()));
|
||||
_btnAlign.onClick.AddListener(
|
||||
() => _eventAggregator.Publish(new EventInfiniteBuildingAlign()));
|
||||
base.Start();
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/CampSettlementPanel.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/CampSettlementPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d480c71be6942b48b397d885f4bf847
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
306
Assets/Scripts/InfiniteBuilding/CampSkyscraperPanel.cs
Normal file
306
Assets/Scripts/InfiniteBuilding/CampSkyscraperPanel.cs
Normal file
@@ -0,0 +1,306 @@
|
||||
using UnityEngine.UI;
|
||||
using game;
|
||||
using asap.core;
|
||||
using GameCore;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using cfg;
|
||||
using DG.Tweening;
|
||||
using UniRx;
|
||||
|
||||
//using System.Threading;
|
||||
public class CampSkyscraperPanel : BasePanel
|
||||
{
|
||||
private Button _btnClose, _btnLeft, _btnConstruct, _btnInfo, _btnConstructGray;
|
||||
//public Action OnClickConstruct, OnClickBtnClose;
|
||||
public GameObject fxRating, goCombo;
|
||||
private TMP_Text _textPrice, _textIBLvl, _textStepProgress, _textPriceGray, _comboText1, _comboText2, _comboText3;
|
||||
TMP_Text text_cost_buff, text_old;//, text_cost_buffGray, text_oldGray;
|
||||
private InfiniteBuildingData _ibd;
|
||||
private ulong _price;
|
||||
private Image _bar;
|
||||
private RewardItemNew _reward, _flyMoney;
|
||||
private Tables _tables;
|
||||
private PlayerData _pd;
|
||||
private PlayerItemData _pid;
|
||||
private Animation _rewardAni, _lvlUpAni;
|
||||
private TbConstructionInfiniteReward _rewardTable;
|
||||
private EventAggregator _eventAggregator;
|
||||
CanvasGroup canvasGroup;
|
||||
private void Awake()
|
||||
{
|
||||
//Debug.Log($"<color=red>UI thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
_btnClose = transform.Find("safearea/DownPanel/btn_close").GetComponent<Button>();
|
||||
_btnLeft = transform.Find("safearea/DownPanel/btn_left").GetComponent<Button>();
|
||||
_btnConstruct = transform.Find("safearea/DownPanel/btn_construct").GetComponent<Button>();
|
||||
_btnConstructGray = transform.Find("safearea/DownPanel/btn_construct_gray").GetComponent<Button>();
|
||||
fxRating = transform.Find("safearea/MiddlePanel/FX_info_piercing").gameObject;
|
||||
_textPrice = transform.Find("safearea/DownPanel/btn_construct/text_cost").GetComponent<TMP_Text>();
|
||||
_textPriceGray = transform.Find("safearea/DownPanel/btn_construct_gray/text_cost").GetComponent<TMP_Text>();
|
||||
|
||||
text_cost_buff = transform.Find("safearea/DownPanel/btn_construct/text_cost_buff").GetComponent<TMP_Text>();
|
||||
text_old = transform.Find("safearea/DownPanel/btn_construct/text_cost_buff/text_old").GetComponent<TMP_Text>();
|
||||
|
||||
//text_cost_buffGray = transform.Find("safearea/DownPanel/btn_construct_gray/text_cost_buff").GetComponent<TMP_Text>();
|
||||
//text_oldGray = transform.Find("safearea/DownPanel/btn_construct_gray/text_cost_buff/text_old").GetComponent<TMP_Text>();
|
||||
|
||||
_textIBLvl = transform.Find("top_area/level/icon_grade/text_grade").GetComponent<TMP_Text>();
|
||||
_bar = transform.Find("safearea/MiddlePanel/skyscraper_target/bar").GetComponent<Image>();
|
||||
_reward = transform.Find("safearea/MiddlePanel/skyscraper_target/reward").GetComponent<RewardItemNew>();
|
||||
_btnInfo = transform.Find("top_area/level").GetComponent<Button>();
|
||||
_textStepProgress = transform.Find("safearea/MiddlePanel/skyscraper_target/text_progress").GetComponent<TMP_Text>();
|
||||
_rewardAni = transform.Find("safearea/MiddlePanel/skyscraper_target").GetComponent<Animation>();
|
||||
//_lvlUpAni = transform.Find("fx_anim_campskyscraper_levelup_d_01")
|
||||
_lvlUpAni = transform.Find("top_area/particle/fx_ui_campskyscraper_levelup_01 1").GetComponent<Animation>();
|
||||
_flyMoney = transform.Find("RewardFlyPanel/reward").GetComponent<RewardItemNew>();
|
||||
_pd = GContext.container.Resolve<PlayerData>();
|
||||
_tables = GContext.container.Resolve<Tables>();
|
||||
_pid = GContext.container.Resolve<PlayerItemData>();
|
||||
_rewardTable = GContext.container.Resolve<Tables>().TbConstructionInfiniteReward;
|
||||
goCombo = transform.Find("safearea/MiddlePanel/combo").gameObject;
|
||||
_comboText1 = goCombo.transform.Find("text_num1").GetComponent<TMP_Text>();
|
||||
_comboText2 = goCombo.transform.Find("text_num2").GetComponent<TMP_Text>();
|
||||
_comboText3 = goCombo.transform.Find("text_num3").GetComponent<TMP_Text>();
|
||||
canvasGroup = transform.GetComponent<CanvasGroup>();
|
||||
}
|
||||
protected override void Start()
|
||||
{
|
||||
//GContext.container.Resolve<CampData>().IsCanSkyscraper
|
||||
//建造按钮是否置灰 !IsCanSkyscraper
|
||||
bool t = GContext.container.Resolve<CampDataMM>().IsCanSkyscraper;
|
||||
//t = false;
|
||||
_btnConstruct.gameObject.SetActive(t);
|
||||
_btnConstructGray.gameObject.SetActive(!t);
|
||||
//Init();
|
||||
base.Start();
|
||||
GContext.OnEvent<RestartShowHomeUIEvent>().Subscribe(_ =>
|
||||
{
|
||||
canvasGroup.alpha = 1;
|
||||
canvasGroup.blocksRaycasts = true;
|
||||
}).AddTo(disposables);
|
||||
|
||||
GContext.OnEvent<HideHomePanelEvent>().Subscribe(_ =>
|
||||
{
|
||||
canvasGroup.alpha = 0;
|
||||
canvasGroup.blocksRaycasts = false;
|
||||
}).AddTo(disposables);
|
||||
GContext.OnEvent<ChangeLanguageEvent>().Subscribe(OnChangeLanguage).AddTo(disposables);
|
||||
}
|
||||
private void OnClickClose()
|
||||
{
|
||||
//OnClickBtnClose?.Invoke();
|
||||
GContext.Publish(new UnloadActToNextAct());
|
||||
}
|
||||
private int target;
|
||||
public void Init(InfiniteBuildingData ibd, EventAggregator ea)
|
||||
{
|
||||
_ibd = ibd;
|
||||
|
||||
int price = SetPrice();
|
||||
|
||||
_textPriceGray.text = ConvertTools.GetNumberString(price);
|
||||
_textIBLvl.text = _ibd.Lvl.ToString();
|
||||
target = _tables.TbConstructionInfiniteReward[_ibd.StepLvl].Step;
|
||||
_textStepProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", string.Format("{0}/{1}", _ibd.Step, target));
|
||||
_bar.fillAmount = (float)_ibd.Step / (float)target;
|
||||
_reward.SetData(_pid.GetItemDataOne(_rewardTable[_ibd.StepLvl].DropID));
|
||||
_eventAggregator = ea;
|
||||
}
|
||||
|
||||
void OnChangeLanguage(ChangeLanguageEvent changeLanguageEvent)
|
||||
{
|
||||
_textStepProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", string.Format("{0}/{1}", _ibd.Step, target));
|
||||
}
|
||||
|
||||
|
||||
public async System.Threading.Tasks.Task<bool> UpdateUIWhenSuccess()
|
||||
{
|
||||
if (_ibd == null)
|
||||
{
|
||||
Debug.LogError("Infinite building data is null in UI sript.");
|
||||
return false;
|
||||
}
|
||||
PlayLvlUpAnimation();
|
||||
target = _rewardTable[_ibd.StepLvl].Step;
|
||||
if (_ibd.Step < target)
|
||||
{
|
||||
_bar.DOFillAmount((float)_ibd.Step / (float)target, 0.5f).onComplete +=
|
||||
() => _textStepProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", string.Format("{0}/{1}", _ibd.Step, target));
|
||||
SetPrice();
|
||||
//_textStepProgress.text = string.Format("Step {0}/{1}", target, target);
|
||||
return false;
|
||||
}
|
||||
_textStepProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", string.Format("{0}/{1}", _ibd.Step, target));
|
||||
await _bar.DOFillAmount(1, 0.5f).AsyncWaitForCompletion();
|
||||
return true;
|
||||
//step target achieved!!!
|
||||
}
|
||||
private async System.Threading.Tasks.Task PlayLvlUpAnimation()
|
||||
{
|
||||
_lvlUpAni.gameObject.SetActive(false);
|
||||
_lvlUpAni.gameObject.SetActive(true);
|
||||
await System.Threading.Tasks.Task.Delay(1000 * 55 / 60);
|
||||
int lvl = int.Parse(_textIBLvl.text);
|
||||
DOTween.To(() => lvl, value => lvl = value, _ibd.Lvl, 0.3f)
|
||||
.OnUpdate(() => { _textIBLvl.text = lvl.ToString(); });
|
||||
//_textIBLvl.text = _ibd.Lvl.ToString();
|
||||
}
|
||||
public async System.Threading.Tasks.Task ReceiveReward()
|
||||
{
|
||||
_rewardAni.Play("campskyscraper_target");
|
||||
await System.Threading.Tasks.Task.Delay(1000 * 92 / 60);
|
||||
int dropID = _rewardTable[_ibd.StepLvl].DropID;
|
||||
_pid.AddItemByDrop(dropID, true);
|
||||
GContext.Publish(new ShowData());
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingGetReward(dropID));
|
||||
_bar.fillAmount = 0;
|
||||
_ibd.Step -= target;
|
||||
_ibd.StepLvl++;
|
||||
_ibd.StepLvl = ((_ibd.StepLvl - 1) % _rewardTable.DataList.Count) + 1;
|
||||
target = _rewardTable[_ibd.StepLvl].Step;
|
||||
//Debug.Log($"<color=red>stepLvl: {_ibd.StepLvl}," +
|
||||
// $"dropID: {_pid.GetItemDataOne(_rewardTable[_ibd.StepLvl].DropID)}</color>");
|
||||
_reward.SetData(_pid.GetItemDataOne(_rewardTable[_ibd.StepLvl].DropID));
|
||||
_textStepProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", string.Format("{0}/{1}", _ibd.Step, target));
|
||||
SetPrice();
|
||||
|
||||
_ibd.UploadData();
|
||||
}
|
||||
int SetPrice()
|
||||
{
|
||||
int price = _ibd.ConstructPrice;
|
||||
var buffTimeData = GContext.container.Resolve<BuffDataCenter>().GetWeelyBuffTimeData<ConstructionCost>();
|
||||
bool isConstructionCost = buffTimeData != null;
|
||||
text_cost_buff.gameObject.SetActive(isConstructionCost);
|
||||
_textPrice.gameObject.SetActive(!isConstructionCost);
|
||||
if (isConstructionCost)
|
||||
{
|
||||
text_old.text = ConvertTools.GetNumberString(price);
|
||||
_price = (ulong)(price * (1 - buffTimeData.Param));
|
||||
text_cost_buff.text = ConvertTools.GetNumberString(_price);
|
||||
}
|
||||
else
|
||||
{
|
||||
_price = (ulong)price;
|
||||
_textPrice.text = ConvertTools.GetNumberString(price);
|
||||
}
|
||||
return price;
|
||||
}
|
||||
async void InBuildAct()
|
||||
{
|
||||
var campData = GContext.container.Resolve<CampDataMM>();
|
||||
ILoadResourceService loadResourceService = GContext.container.Resolve<ILoadResourceService>();
|
||||
bool isCanEnter = await loadResourceService.Loads(campData.AllPrefabs);
|
||||
if (isCanEnter)
|
||||
{
|
||||
GContext.Publish(new UnloadActToNextAct("BuildAct"));
|
||||
}
|
||||
else
|
||||
{
|
||||
var panel = await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
|
||||
panel.GetComponent<CloudTransitionPanel>().SetBtn(true, () => GContext.Publish(new UnloadActToNextAct("BuildAct")));
|
||||
//var panel = await UIManager.Instance.ShowUI(UITypes.FishingDownLoadPopupPanel);
|
||||
//panel.GetComponent<FishingDownLoadPopupPanel>().SetBtn(null, () => GContext.Publish(new UnloadActToNextAct("BuildAct")));
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayComboFx(int comboCount)
|
||||
{
|
||||
if (comboCount <= 1)
|
||||
return;
|
||||
goCombo.SetActive(false);
|
||||
switch (comboCount)
|
||||
{
|
||||
case > 10:
|
||||
_comboText3.text = comboCount.ToString();
|
||||
_comboText1.gameObject.SetActive(false);
|
||||
_comboText2.gameObject.SetActive(false);
|
||||
_comboText3.gameObject.SetActive(true);
|
||||
break;
|
||||
case > 5:
|
||||
_comboText2.text = comboCount.ToString();
|
||||
_comboText1.gameObject.SetActive(false);
|
||||
_comboText2.gameObject.SetActive(true);
|
||||
_comboText3.gameObject.SetActive(false);
|
||||
break;
|
||||
default:
|
||||
_comboText1.text = comboCount.ToString();
|
||||
_comboText1.gameObject.SetActive(true);
|
||||
_comboText2.gameObject.SetActive(false);
|
||||
_comboText3.gameObject.SetActive(false);
|
||||
break;
|
||||
}
|
||||
goCombo.SetActive(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Play the rating fx.
|
||||
/// </summary>
|
||||
/// <param name="rating">0 for nothing, 1 for good, 2 for fantastic.</param>
|
||||
public void PlayRatingFx(int rating)
|
||||
{
|
||||
if (rating == 0)
|
||||
return;
|
||||
fxRating.gameObject.SetActive(false);
|
||||
fxRating.transform.Find("1").gameObject.SetActive(rating == 2);
|
||||
fxRating.transform.Find("2").gameObject.SetActive(rating == 1);
|
||||
fxRating.gameObject.SetActive(true);
|
||||
}
|
||||
public async System.Threading.Tasks.Task PlayCashFlyAnimation(int count)
|
||||
{
|
||||
// PerfectAni.SetActive(false);
|
||||
// PerfectAni.SetActive(true);
|
||||
_flyMoney.gameObject.SetActive(true);
|
||||
_flyMoney.SetRewardPopupData(new ItemData(1002, count));
|
||||
_flyMoney.GetComponent<Animation>().Play("reward_common_open");
|
||||
await System.Threading.Tasks.Task.Delay(16 * 1000 / 60);
|
||||
_flyMoney.GetComponent<Animation>().Play("reward_common_close");
|
||||
await System.Threading.Tasks.Task.Delay(16 * 1000 / 60);
|
||||
await _flyMoney.ParticleAttractor();
|
||||
_flyMoney.gameObject.SetActive(false);
|
||||
GContext.Publish(new ResAddEvent(1002));
|
||||
}
|
||||
public void ActivateBtns()
|
||||
{
|
||||
//if (!_btnConstruct.gameObject.activeSelf)
|
||||
// return;
|
||||
|
||||
_btnConstruct.onClick.AddListener(OnClickPlay);
|
||||
_btnConstructGray.onClick.AddListener(
|
||||
() => ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_77")));
|
||||
_btnClose.onClick.AddListener(OnClickClose);
|
||||
_btnLeft.onClick.AddListener(InBuildAct);
|
||||
//_btnConstruct.onClick.AddListener(OnClickPlay);
|
||||
_btnInfo.onClick.AddListener(() => UIManager.Instance.ShowUI(UITypes.CampInfoPanel));
|
||||
}
|
||||
public void DeactivateBtns()
|
||||
{
|
||||
_btnConstruct.onClick.RemoveAllListeners();
|
||||
_btnConstructGray.onClick.RemoveAllListeners();
|
||||
_btnClose.onClick.RemoveAllListeners();
|
||||
_btnLeft.onClick.RemoveAllListeners();
|
||||
_btnInfo.onClick.RemoveAllListeners();
|
||||
}
|
||||
private void OnClickPlay()
|
||||
{
|
||||
//Debug.Log("Play!!!!!!!!!!!");
|
||||
_btnConstruct.gameObject.GetComponent<Animator>().Play("clicked");
|
||||
if ((ulong)_pd.gold >= _price)
|
||||
{
|
||||
_btnConstruct.onClick.RemoveAllListeners();
|
||||
_pd.SetGold(_pd.gold - _price);
|
||||
GContext.Publish(new ResAddEvent(1002));
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingConstruct(_price));
|
||||
}
|
||||
else
|
||||
{
|
||||
ToastPanel.Show(LocalizationMgr.GetText("UI_CampPanel_8"));
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
//private void OnGUI()
|
||||
//{
|
||||
// GUI.Box(new Rect(20, 110, 200, 20), _btnConstruct.isActiveAndEnabled.ToString());
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
11
Assets/Scripts/InfiniteBuilding/CampSkyscraperPanel.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/CampSkyscraperPanel.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e0a4de406af4d04799275c431df2e63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
193
Assets/Scripts/InfiniteBuilding/CraneCtrl.cs
Normal file
193
Assets/Scripts/InfiniteBuilding/CraneCtrl.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using cfg;
|
||||
using asap.core;
|
||||
|
||||
public class CraneCtrl : MonoBehaviour
|
||||
{
|
||||
private DistanceJoint2D _djL, _djR;
|
||||
[SerializeField] private Rigidbody2D _rb;
|
||||
private Vector2 _direction = Vector2.zero, _craneAnchorOffset;
|
||||
private float _driftOffset, _craneCycleHalfDistance,
|
||||
_blockAnchorCoefficient, _lineThickness, _blockDepth;
|
||||
private Block _currentBlock = null;
|
||||
private bool _maxDistanceOnly, _hasAutoDistance, _needKicking = false;
|
||||
private Transform _focus;
|
||||
private List<int> _LvlThresh;
|
||||
private List<float> _craneHeightRise, _craneHeightDescend, _craneCycleTime, _craneRiseTime;
|
||||
private InfiniteBuildingData _data;
|
||||
[SerializeField] private LineRenderer _lineL, _lineR;
|
||||
private TbConstructionHeightEvent _tableHeightEvent;
|
||||
private IEventAggregator _eventAggregator;
|
||||
private float CraneRiseTime { get => GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneRiseTime); }
|
||||
public Rigidbody2D Rb { get => _rb; }
|
||||
private float CraneAcc {
|
||||
get
|
||||
{
|
||||
float t = GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneCycleTime) / 4;
|
||||
return 2 * _craneCycleHalfDistance / t / t;
|
||||
}
|
||||
}
|
||||
private float CraneMaxSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
float t = GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneCycleTime) / 4;
|
||||
return 2 * _craneCycleHalfDistance / t;
|
||||
}
|
||||
}
|
||||
public void Init(InfiniteBuildingConf config, Transform focus, InfiniteBuildingData data, IEventAggregator ea)
|
||||
{
|
||||
_eventAggregator = ea;
|
||||
_tableHeightEvent = GContext.container.Resolve<Tables>().TbConstructionHeightEvent;
|
||||
_craneCycleTime = new List<float>();
|
||||
_LvlThresh = new List<int>();
|
||||
_craneHeightRise = new List<float>();
|
||||
_craneHeightDescend = new List<float>();
|
||||
_craneRiseTime = new List<float>();
|
||||
foreach (var c in _tableHeightEvent.DataList)
|
||||
{
|
||||
_craneCycleTime.Add(c.CraneCycleTime);
|
||||
_LvlThresh.Add(c.Height);
|
||||
_craneHeightRise.Add(c.CraneHeightRise);
|
||||
_craneHeightDescend.Add(c.CraneHeightToFocus);
|
||||
_craneRiseTime.Add(c.CraneRiseTime);
|
||||
}
|
||||
_craneCycleHalfDistance = config.craneCycleHalfDistance;
|
||||
_craneAnchorOffset = config.craneAnchorOffset;
|
||||
_blockAnchorCoefficient = config.blockAnchorCoefficient;
|
||||
_maxDistanceOnly = config.maxDistanceOnly;
|
||||
_hasAutoDistance = config.hasAutoDistance;
|
||||
_driftOffset = config.blockDriftOffset;
|
||||
_lineThickness = config.craneLineThickness;
|
||||
_blockDepth = config.blockDepth;
|
||||
_focus = focus;
|
||||
_data = data;
|
||||
_lineL.startWidth = _lineL.endWidth = _lineR.startWidth = _lineR.endWidth = _lineThickness;
|
||||
}
|
||||
public void PlayerCtrlFixedUpdate()
|
||||
{
|
||||
if (_rb.position.x < 0)
|
||||
_direction = Vector2.right;
|
||||
else
|
||||
_direction = Vector2.left;
|
||||
if (_needKicking)
|
||||
{
|
||||
_needKicking = false;
|
||||
_rb.velocity = Mathf.Lerp(0, CraneMaxSpeed,
|
||||
1 - Mathf.Abs(_rb.position.x) / _craneCycleHalfDistance)
|
||||
*_direction;
|
||||
//Debug.Log($"Kick!!!!!!!!!!{_rb.velocity}");
|
||||
}
|
||||
|
||||
_rb.velocity += CraneAcc * Time.fixedDeltaTime * _direction;
|
||||
//draw line
|
||||
if (_djL != null && _djR != null && _lineL != null && _lineR != null
|
||||
&& _lineL.gameObject.activeSelf && _lineR.gameObject.activeSelf
|
||||
&& _currentBlock != null)
|
||||
SetJointPosition();
|
||||
}
|
||||
public void Kick()
|
||||
{
|
||||
_needKicking = true;
|
||||
}
|
||||
public void AttachJoints(Block block)
|
||||
{
|
||||
_currentBlock = block;
|
||||
_djL = gameObject.AddComponent<DistanceJoint2D>();
|
||||
_djR = gameObject.AddComponent<DistanceJoint2D>();
|
||||
if (_djL == null || _djR == null || _lineL == null || _lineR == null)
|
||||
{
|
||||
Debug.LogError($"Components not generated for {gameObject}");
|
||||
}
|
||||
_lineL.gameObject.SetActive(true);
|
||||
_lineR.gameObject.SetActive(true);
|
||||
SetJointPosition();
|
||||
_djL.anchor = new Vector2(-_craneAnchorOffset.x, _craneAnchorOffset.y);
|
||||
_djR.anchor = _craneAnchorOffset;
|
||||
_djL.connectedBody = block.Rb;
|
||||
_djR.connectedBody = block.Rb;
|
||||
_djL.connectedAnchor = new Vector2(-block.Width * _blockAnchorCoefficient / 2, block.Height);
|
||||
_djR.connectedAnchor = new Vector2(block.Width * _blockAnchorCoefficient / 2, block.Height);
|
||||
_djL.maxDistanceOnly = _maxDistanceOnly;
|
||||
_djR.maxDistanceOnly = _maxDistanceOnly;
|
||||
_djL.autoConfigureDistance = _hasAutoDistance;
|
||||
_djR.autoConfigureDistance = _hasAutoDistance;
|
||||
_djL.breakAction = JointBreakAction2D.Destroy;
|
||||
_djR.breakAction = JointBreakAction2D.Destroy;
|
||||
if (!_hasAutoDistance)
|
||||
{
|
||||
float jd = Mathf.Sqrt(
|
||||
(block.Width * 0.5f * _blockAnchorCoefficient)
|
||||
* (block.Width * 0.5f * _blockAnchorCoefficient)
|
||||
+ _driftOffset * _driftOffset);
|
||||
_djL.distance = jd;
|
||||
_djR.distance = jd;
|
||||
}
|
||||
}
|
||||
public IEnumerator DropBlockAndRise()
|
||||
{
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingPlayAudio("BlockFall"));
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingPlayAudio("CraneRise"));
|
||||
_currentBlock = null;
|
||||
_rb.velocity = Vector2.zero;
|
||||
_djL.breakForce = 0;
|
||||
_djR.breakForce = 0;
|
||||
_lineL.gameObject.SetActive(false);
|
||||
_lineR.gameObject.SetActive(false);
|
||||
yield return new WaitForFixedUpdate();
|
||||
//await Task.Delay((int)(Time.deltaTime * 1000 * 2));
|
||||
float h = GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneHeightRise);
|
||||
_rb.DOMoveY(_focus.position.y + h, CraneRiseTime);
|
||||
//await Rise();
|
||||
}
|
||||
public void ResetPosition()
|
||||
{
|
||||
transform.position = new Vector3(0, _focus.position.y +
|
||||
GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneHeightRise), _blockDepth);
|
||||
}
|
||||
public async System.Threading.Tasks.Task Descend()
|
||||
{
|
||||
// ResetPosition();
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingPlayAudio("CraneDescend"));
|
||||
await _rb.DOMoveY(_focus.position.y +
|
||||
GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneHeightDescend),
|
||||
CraneRiseTime).AsyncWaitForCompletion();
|
||||
}
|
||||
//public async Task Rise(float duration = 0.5f)
|
||||
//{
|
||||
// _rb.velocity = Vector2.zero;
|
||||
// await _rb.DOMoveY(_focus.position.y +
|
||||
// GetDataByIBLvl<float>(_data.Lvl, _LvlThresh, _craneHeightRise),
|
||||
// duration).AsyncWaitForCompletion();
|
||||
//}
|
||||
private void SetJointPosition()
|
||||
{
|
||||
Vector3 cranePointL = gameObject.transform.position + (Vector3)_djL.anchor;
|
||||
Vector3 cranePointR = gameObject.transform.position + (Vector3)_djR.anchor;
|
||||
Vector3 blockPointL = _currentBlock.transform.position + Quaternion.AngleAxis(
|
||||
_currentBlock.Rb.rotation, Vector3.forward) * (Vector3)_djL.connectedAnchor;
|
||||
Vector3 blockPointR = _currentBlock.transform.position + Quaternion.AngleAxis(
|
||||
_currentBlock.Rb.rotation, Vector3.forward) * (Vector3)_djR.connectedAnchor;
|
||||
_lineL.SetPositions(new Vector3[] { cranePointL, blockPointL });
|
||||
_lineR.SetPositions(new Vector3[] { cranePointR, blockPointR });
|
||||
}
|
||||
private T GetDataByIBLvl<T>(int lvl, List<int> lvlThresh, List<T> dataList)
|
||||
{
|
||||
if (lvlThresh.Count != dataList.Count)
|
||||
{
|
||||
Debug.LogError($"lvlTresh count {lvlThresh.Count} does not" +
|
||||
$"match dataList count {dataList.Count}");
|
||||
return default(T);
|
||||
}
|
||||
for (int i = 0; i < lvlThresh.Count - 1; i++)
|
||||
{
|
||||
if (lvl < lvlThresh[i + 1])
|
||||
return dataList[i];
|
||||
}
|
||||
return dataList[^1];
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Scripts/InfiniteBuilding/CraneCtrl.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/CraneCtrl.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13702d906a14554478d2807d74039cca
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
806
Assets/Scripts/InfiniteBuilding/InfiniteBuildingAct.cs
Normal file
806
Assets/Scripts/InfiniteBuilding/InfiniteBuildingAct.cs
Normal file
@@ -0,0 +1,806 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using asap.core;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using GameCore;
|
||||
using cfg;
|
||||
using UniRx;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using Game;
|
||||
|
||||
public class InfiniteBuildingAct : AGameAct
|
||||
{
|
||||
private PlayerData _playerData;
|
||||
private InfiniteBuildingData _data;
|
||||
private InfiniteBuildingConf _cfg;
|
||||
|
||||
private class FSM : AFSM<EInfiniteBuildingState>
|
||||
{
|
||||
}
|
||||
|
||||
private IFSM<EInfiniteBuildingState> _sm;
|
||||
private FSMHandler<IFSM<EInfiniteBuildingState>, EInfiniteBuildingState> _smHandler;
|
||||
[SerializeField] private CraneCtrl _crane;
|
||||
[SerializeField] private BlockManager _blockManager;
|
||||
private Tables _tables;
|
||||
[SerializeField] private CameraCtrl _cam;
|
||||
private const int blockDepth = 20;
|
||||
private CampSkyscraperPanel _mainPanel;
|
||||
[SerializeField] private Transform _focus;
|
||||
[SerializeField] private BlockDeathNotifier _deathWall;
|
||||
private PlayerItemData _playerItemData;
|
||||
private readonly EventAggregator _eventAggregator = new EventAggregator();
|
||||
private float BlockRestingHeight => _cfg.blockRestingOffset + _focus.position.y;
|
||||
[SerializeField] private MeshRenderer _skyLoop;
|
||||
private HashSet<string> _collisionSounds;
|
||||
private int _EVConstructionState, _EVRetryType, _EVHookRewardGot, _EVCashRewardGot, _EVRating, _EVCombo;
|
||||
private ulong _EVCost, _EVCashBack;
|
||||
|
||||
[SerializeField] GameObject _light;
|
||||
GameObject Building999Main;
|
||||
|
||||
private CompositeDisposable _disposables = new CompositeDisposable();
|
||||
|
||||
//IDisposable disposable;
|
||||
private const string ComboKey = "InfiniteBuildingCombo";
|
||||
|
||||
public override async System.Threading.Tasks.Task<bool> StartAsync()
|
||||
{
|
||||
Building999Main = transform.GetChild(0).gameObject;
|
||||
//Debug.Log($"<color=red>Main thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
_collisionSounds = new HashSet<string>();
|
||||
_data = new InfiniteBuildingData();
|
||||
_sm = new FSM();
|
||||
_smHandler = new FSMHandler<IFSM<EInfiniteBuildingState>, EInfiniteBuildingState>(this, _sm);
|
||||
_cfg = (InfiniteBuildingConf)await Addressables.LoadAssetAsync<System.Object>("InfiniteBuildingConf").Task;
|
||||
_playerData = GContext.container.Resolve<PlayerData>();
|
||||
_tables = GContext.container.Resolve<Tables>();
|
||||
_playerItemData = GContext.container.Resolve<PlayerItemData>();
|
||||
|
||||
_disposables.Add(GContext.OnEvent<InGradeAquariumEvent>().Subscribe(OnInAquariumEnevt));
|
||||
_disposables.Add(GContext.OnEvent<EventMainBGM>().Subscribe(OnEventMainBGM));
|
||||
|
||||
GContext.OnEvent<MapShowEvent>().Subscribe(e =>
|
||||
{
|
||||
SetMapShow(e.isShow);
|
||||
}).AddTo(_disposables);
|
||||
|
||||
_data.DownloadData(_playerData.InfiniteBuildingData);
|
||||
// Debug.Log($"<color=red>Debug in progress!!!!!!!!!!!!!!!!</color>");
|
||||
// _data.DownloadData("0,0,1,-1");
|
||||
//_data.DownloadData("1199,0,1,-1," +
|
||||
// "209,-0.9679986,1191.69006," +
|
||||
// "212,-0.9312674,1192.70402," +
|
||||
// "1201,-0.1499511,1193.71932," +
|
||||
// "103,-0.288533,1195.73021," +
|
||||
// "211,-0.03252038,1196.74632," +
|
||||
// "203,-0.06627272,1197.76019," +
|
||||
// "201,0.08355299,1198.77346," +
|
||||
// "101,-0.3572269,1199.79065");
|
||||
_crane.Init(_cfg, _focus, _data, _eventAggregator);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingAlign>()
|
||||
.Subscribe(async _ => await TryAlignBlocks()).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingRetry>()
|
||||
.Subscribe(_ =>
|
||||
{
|
||||
_EVRetryType = 1;
|
||||
_sm.SetState(EInfiniteBuildingState.InitLoop);
|
||||
UIManager.Instance.DestroyUI(UITypes.CampSettlementPanel);
|
||||
}).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingConstruct>()
|
||||
.Subscribe(e =>
|
||||
{
|
||||
_sm.SetState(EInfiniteBuildingState.BlockFall);
|
||||
_EVCost = e.ConstructionCost;
|
||||
}).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingBlockDeath>()
|
||||
.Subscribe(e => HandleBlockDeath(e)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingFail>()
|
||||
.Subscribe(_ => _sm.SetState(EInfiniteBuildingState.Failure)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingSucceed>()
|
||||
.Subscribe(_ => _sm.SetState(EInfiniteBuildingState.Success)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingPlayAudio>()
|
||||
.Subscribe(async e => await PlayAudio(e.AudioName)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingCollisionSound>()
|
||||
.Subscribe(e => OnCollisionSound(e.Hash)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingFirstCollision>()
|
||||
.Subscribe(e => HandleFirstCollision(e.block)).AddTo(_disposables);
|
||||
_eventAggregator.GetEvent<EventInfiniteBuildingGetReward>()
|
||||
.Subscribe(e => HandleReceiveReward(e)).AddTo(_disposables);
|
||||
await LoadAudioClips();
|
||||
PlayBGM();
|
||||
//Debug.Log($"<color=red>{_pd.InfiniteBuildingData}</color>");
|
||||
_mainPanel = (await UIManager.Instance.ShowUI(UITypes.CampSkyscraperPanel))
|
||||
.GetComponent<CampSkyscraperPanel>();
|
||||
_mainPanel.Init(_data, _eventAggregator);
|
||||
BoxCollider2D initBC =
|
||||
transform.Find("Building999Main/static/B999_initial/Collision2D").GetComponent<BoxCollider2D>();
|
||||
_focus.position = initBC.transform.position + new Vector3(initBC.offset.x, initBC.offset.y) +
|
||||
initBC.size.y / 2f * Vector3.up;
|
||||
_blockManager.Init(_cfg, _data, _eventAggregator);
|
||||
await _blockManager.RebuildAllBlocks();
|
||||
_deathWall.Init(_eventAggregator);
|
||||
GetFX();
|
||||
_sm.SetState(EInfiniteBuildingState.Init);
|
||||
return await base.StartAsync();
|
||||
}
|
||||
|
||||
void SetMapShow(bool isShow)
|
||||
{
|
||||
if (Building999Main != null)
|
||||
{
|
||||
Building999Main.SetActive(isShow);
|
||||
}
|
||||
}
|
||||
|
||||
void OnInAquariumEnevt(InGradeAquariumEvent e)
|
||||
{
|
||||
Debug.Log("OnInAquariumEnevt");
|
||||
|
||||
if (_light != null)
|
||||
{
|
||||
_light.SetActive(e.type == 1);
|
||||
}
|
||||
}
|
||||
|
||||
void OnEventMainBGM(EventMainBGM e)
|
||||
{
|
||||
PlayBGM();
|
||||
}
|
||||
|
||||
public override async System.Threading.Tasks.Task StopAsync()
|
||||
{
|
||||
UIManager.Instance.DestroyUI(UITypes.CampSkyscraperPanel);
|
||||
await base.StopAsync();
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (_sm == null)
|
||||
return;
|
||||
if (_sm.State == EInfiniteBuildingState.PlayerCtrl
|
||||
#if UNITY_EDITOR
|
||||
&& !_cfg.FreezeCrane
|
||||
#endif
|
||||
)
|
||||
{
|
||||
_crane.PlayerCtrlFixedUpdate();
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
float v = 0.2f;
|
||||
if (Input.GetKeyDown(KeyCode.A) && _sm.State == EInfiniteBuildingState.PlayerCtrl)
|
||||
{
|
||||
_crane.Rb.position += v * Vector2.left;
|
||||
}
|
||||
|
||||
if (Input.GetKeyUp(KeyCode.D) && _sm.State == EInfiniteBuildingState.PlayerCtrl)
|
||||
{
|
||||
_crane.Rb.position += v * Vector2.right;
|
||||
}
|
||||
#endif
|
||||
else if (_sm.State == EInfiniteBuildingState.BlockFall)
|
||||
{
|
||||
_blockManager.BlockFallFixedUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
_collisionSounds?.Clear();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
Debug.Log("Act Destroyed!");
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
private void OnGUI()
|
||||
{
|
||||
if (_sm != null)
|
||||
GUI.Box(new Rect(20, 40, 200, 20), _sm.State.ToString());
|
||||
//Debug.DrawLine(new Vector3(-10, _cam.LowerLimit.y, blockDepth),
|
||||
//new Vector3(10, _cam.LowerLimit.y, blockDepth), Color.red);
|
||||
if (_blockManager.CurrentBlock != null)
|
||||
{
|
||||
GUI.Box(new Rect(20, 60, 200, 20), $"Acc: {_blockManager.CurrentBlock.Acc.magnitude}");
|
||||
GUI.Box(new Rect(20, 90, 200, 20), $"Angular Acc: {_blockManager.CurrentBlock.AngularAcc}");
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Box(new Rect(20, 60, 200, 20), $"Empty");
|
||||
GUI.Box(new Rect(20, 90, 200, 20), $"Empty");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (_focus != null && _cfg != null)
|
||||
Debug.DrawLine(new Vector3(-10, BlockRestingHeight, blockDepth),
|
||||
new Vector3(10, BlockRestingHeight, blockDepth), Color.red);
|
||||
//Debug.DrawLine(new Vector3(-20, _cam.LowerLimit.y, blockDepth),
|
||||
// new Vector3(-20, _cam.LowerLimit.y, blockDepth), Color.red);
|
||||
}
|
||||
#endif
|
||||
private void UpdateLastHangingBlock()
|
||||
{
|
||||
_data.LastHangingBlock = _blockManager.CurrentBlock.Idx;
|
||||
_data.UploadData();
|
||||
}
|
||||
|
||||
private void UpdateData(int lvlDelta = 0)
|
||||
{
|
||||
_data.Lvl += lvlDelta;
|
||||
_data.Record = new List<InfiniteBuildingData.BlockRecord>();
|
||||
foreach (var block in _blockManager.Blocks)
|
||||
{
|
||||
//Debug.Log($"{block}");
|
||||
//Debug.Log($"{block.Rb.position}");
|
||||
//Debug.Log($"{block.transform.position}");
|
||||
_data.Record.Add(new InfiniteBuildingData.BlockRecord(block.Idx, block.Rb.position));
|
||||
}
|
||||
|
||||
_data.UploadData();
|
||||
}
|
||||
|
||||
protected override void OnStopped()
|
||||
{
|
||||
//_data.LastHangingBlock = _blockManager.CurrentBlock.Idx;
|
||||
//UpdateData();
|
||||
foreach (var e in _audioClips)
|
||||
{
|
||||
Addressables.Release(e.Value.Op);
|
||||
}
|
||||
|
||||
_disposables.Dispose();
|
||||
base.OnStopped();
|
||||
}
|
||||
|
||||
public void HandleBlockDeath(EventInfiniteBuildingBlockDeath e)
|
||||
{
|
||||
PlayFX("collapse", _focus.position + _cfg.fxCollapse);
|
||||
if (_sm.State != EInfiniteBuildingState.BlockFall)
|
||||
{
|
||||
PlayFX("replay",
|
||||
Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 1f, _cfg.blockDepth)));
|
||||
_blockManager.RebuildBlocks(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.stateBeforeDeath == BlockState.Free)
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingFail());
|
||||
if (e.stateBeforeDeath == BlockState.Resting)
|
||||
{
|
||||
_eventAggregator.Publish(new EventInfiniteBuildingFail());
|
||||
PlayFX("replay",
|
||||
Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 1f, Camera.main.nearClipPlane)));
|
||||
_blockManager.RebuildAllBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task TryAlignBlocks()
|
||||
{
|
||||
int alignCost = _tables.TbConstructionInfiniteConfig.ResetCost;
|
||||
if (_playerData.diamond < alignCost)
|
||||
{
|
||||
//Debug.LogWarning("inssuficient diamond");
|
||||
GameObject ui = await UIManager.Instance.ShowUI(UITypes.LackOfResourceConfirmPopupPanel);
|
||||
//ui.GetComponent<CampSettlementPanel>().Init(_eventAggregator);
|
||||
return;
|
||||
}
|
||||
|
||||
_EVRetryType = 2;
|
||||
PlayAudio("Reset");
|
||||
PlayFX("reset", Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0f, _cfg.blockDepth)));
|
||||
_playerData.AddDiamond(-alignCost);
|
||||
_blockManager.AlignBlocks(_eventAggregator);
|
||||
UpdateData();
|
||||
_sm.SetState(EInfiniteBuildingState.InitLoop);
|
||||
UIManager.Instance.DestroyUI(UITypes.CampSettlementPanel);
|
||||
}
|
||||
|
||||
private void HandleFirstCollision(Block b)
|
||||
{
|
||||
//Debug.Log($"name: {b.name}");
|
||||
PlayFX("fall", b.transform.position + _cfg.fxFall);
|
||||
_blockManager.StartDestroyCountDown();
|
||||
//PlayAudio("BlockFall");
|
||||
}
|
||||
|
||||
private void HandleReceiveReward(EventInfiniteBuildingGetReward e)
|
||||
{
|
||||
var drop = _tables.TbDrop[e.DropID];
|
||||
if (drop.DropList.DropIDList[0] == 1001)
|
||||
_EVHookRewardGot = drop.DropList.DropCountList[0];
|
||||
else if (drop.DropList.DropIDList[0] == 1002)
|
||||
_EVCashRewardGot = _playerItemData.GetExtraCoinMag(drop.DropList.DropCountList[0]);
|
||||
}
|
||||
|
||||
private int GetConstructionPrice()
|
||||
{
|
||||
int price = _data.ConstructPrice;
|
||||
var buffTimeData = GContext.container.Resolve<BuffDataCenter>().GetWeelyBuffTimeData<ConstructionCost>();
|
||||
bool isConstructionCost = buffTimeData != null;
|
||||
if (isConstructionCost)
|
||||
{
|
||||
price = (int)(price * (1 - buffTimeData.Param));
|
||||
}
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
private int GetRating()
|
||||
{
|
||||
int excellentScore = _blockManager.GetExcellentScore();
|
||||
if (excellentScore >= _tables.TbConstructionInfiniteConfig.GoodRankClamp[0] &&
|
||||
excellentScore <= _tables.TbConstructionInfiniteConfig.GoodRankClamp[1])
|
||||
{
|
||||
Debug.Log($"<color=red>Good.</color>");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// else if (excellentScore >= _tables.TbConstructionInfiniteConfig.GreatRankClamp[0] &&
|
||||
// excellentScore <= _tables.TbConstructionInfiniteConfig.GreatRankClamp[1])
|
||||
// Debug.Log($"<color=red>Great.</color>");
|
||||
if (excellentScore >= _tables.TbConstructionInfiniteConfig.FantasticRankClamp[0] &&
|
||||
excellentScore <= _tables.TbConstructionInfiniteConfig.FantasticRankClamp[1])
|
||||
{
|
||||
Debug.Log($"<color=red>Fantastic.</color>");
|
||||
return 2;
|
||||
}
|
||||
|
||||
Debug.Log($"<color=red>Undefined.</color>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int CountCombo(bool doesComboContinue = true)
|
||||
{
|
||||
if (!doesComboContinue)
|
||||
{
|
||||
PlayerPrefs.SetInt(ComboKey, 0);
|
||||
Debug.Log($"<color=red>Combo reset.</color>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int comboCount = PlayerPrefs.GetInt(ComboKey) + 1;
|
||||
PlayerPrefs.SetInt(ComboKey, comboCount);
|
||||
// if (comboCount >= 2)
|
||||
// Debug.Log($"<color=red>Combo: {comboCount}</color>");
|
||||
return comboCount;
|
||||
}
|
||||
|
||||
#region Audio
|
||||
|
||||
private readonly Dictionary<string, string> _audioAliases = new Dictionary<string, string>()
|
||||
{
|
||||
["CraneRise"] = "audio_ui_skyscraper_1",
|
||||
["CraneDescend"] = "audio_ui_skyscraper_2",
|
||||
["BlockFall"] = "audio_ui_skyscraper_3",
|
||||
["BlockHit"] = "audio_ui_skyscraper_4",
|
||||
["BlockPerfect"] = "audio_ui_skyscraper_5",
|
||||
["Collapse"] = "audio_ui_skyscraper_6",
|
||||
["Reset"] = "audio_ui_skyscraper_7",
|
||||
["BGM"] = "audio_ui_skyscraper_bgm"
|
||||
};
|
||||
|
||||
private readonly Dictionary<string, InfiniteBuildingAudioClip> _audioClips =
|
||||
new Dictionary<string, InfiniteBuildingAudioClip>();
|
||||
|
||||
private struct InfiniteBuildingAudioClip
|
||||
{
|
||||
public string Name;
|
||||
public string Address;
|
||||
public AudioClip Clip;
|
||||
public AsyncOperationHandle Op;
|
||||
|
||||
public InfiniteBuildingAudioClip(string name, string addr, AudioClip clip, AsyncOperationHandle op)
|
||||
{
|
||||
Name = name;
|
||||
Clip = clip;
|
||||
Address = addr;
|
||||
Op = op;
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task LoadAudioClips()
|
||||
{
|
||||
foreach (var e in _audioAliases)
|
||||
{
|
||||
AsyncOperationHandle<AudioClip> op = Addressables.LoadAssetAsync<AudioClip>(e.Value);
|
||||
_audioClips.Add(e.Key, new InfiniteBuildingAudioClip(e.Key, e.Value, await op.Task, op));
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task PlayAudio(string audioName)
|
||||
{
|
||||
if (!_audioAliases.ContainsKey(audioName))
|
||||
{
|
||||
Debug.LogError($"Audio name {audioName} not found in dictionary.");
|
||||
return;
|
||||
}
|
||||
|
||||
Sound s = GContext.container.Resolve<ISoundService>()
|
||||
.GetNewFishingSound(clip: _audioClips[audioName].Clip);
|
||||
s.soundMainType = SoundMainType.Fishing;
|
||||
s.audioSource.Play();
|
||||
await System.Threading.Tasks.Task.Delay((int)(_audioClips[audioName].Clip.length * 1000));
|
||||
s.ReturnPool();
|
||||
}
|
||||
|
||||
private void PlayBGM()
|
||||
{
|
||||
GContext.Publish(new EventBGMSound(_audioAliases["BGM"]));
|
||||
}
|
||||
|
||||
private void OnCollisionSound(string hash)
|
||||
{
|
||||
if (_sm.State != EInfiniteBuildingState.BlockFall || _collisionSounds.Contains(hash))
|
||||
return;
|
||||
_collisionSounds.Add(hash);
|
||||
PlayAudio("BlockHit");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FX
|
||||
|
||||
private readonly List<string> _fxNames = new List<string>()
|
||||
{
|
||||
"fx_infinitebuilding_cloud",
|
||||
"fx_infinitebuilding_collapse",
|
||||
"fx_infinitebuilding_reset",
|
||||
"fx_infinitebuilding_replay",
|
||||
"fx_infinitebuilding_fall",
|
||||
"fx_infinitebuilding_fallperfact"
|
||||
};
|
||||
|
||||
[SerializeField] private Dictionary<string, GameObject> _fxDic = new Dictionary<string, GameObject>();
|
||||
|
||||
private void GetFX()
|
||||
{
|
||||
foreach (string name in _fxNames)
|
||||
{
|
||||
_fxDic.Add(name.Split('_')[^1], transform.Find("Building999Main/fx/" + name).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayFX(string name, Vector3 pos)
|
||||
{
|
||||
_fxDic[name].transform.position = pos;
|
||||
_fxDic[name].SetActive(false);
|
||||
_fxDic[name].SetActive(true);
|
||||
}
|
||||
|
||||
private void MoveFx(string name, Vector3 pos)
|
||||
{
|
||||
_fxDic[name].transform.position = pos;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region State Machine Driver
|
||||
|
||||
private void Init_Enter()
|
||||
{
|
||||
//Debug.Log("Init_Enter!");
|
||||
//Debug.Log($"<color=red>Init_Enter thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
InitEnterAsync();
|
||||
//GenerateBlock().ContinueWith(_ => _sm.SetState(EInfiniteBuildingState.PlayerCtrl));
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task InitEnterAsync()
|
||||
{
|
||||
//Debug.Log($"<color=red>InitEnterAsync thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
await _blockManager.RebuildBlocks();
|
||||
_cam.Init(_focus, _cfg, _skyLoop, _data);
|
||||
_deathWall.transform.position = _focus.position + Vector3.up * _cfg.deathWallOffset;
|
||||
_crane.ResetPosition();
|
||||
Block b = await _blockManager.GenerateBlock(_crane.transform.position + _cfg.blockSpawnOffset, true);
|
||||
_blockManager.CurrentBlock = b;
|
||||
_data.LastHangingBlock = b.Idx;
|
||||
UpdateData();
|
||||
_crane.AttachJoints(b);
|
||||
if (_focus.position.y > _cfg.fxCloudAppearHeight)
|
||||
PlayFX("cloud", _focus.position + _cfg.fxCloud);
|
||||
_sm.SetState(EInfiniteBuildingState.PlayerCtrl);
|
||||
}
|
||||
|
||||
private void Init_Exit()
|
||||
{
|
||||
//Debug.Log("Init_Exit!");
|
||||
}
|
||||
|
||||
private void InitLoop_Enter()
|
||||
{
|
||||
//Debug.Log("InitLoop_Enter!");
|
||||
//GenerateBlock().ContinueWith(_ => _sm.SetState(EInfiniteBuildingState.PlayerCtrl));
|
||||
InitLoopEnterAsync();
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task InitLoopEnterAsync()
|
||||
{
|
||||
// Debug.Log($"construction_state: {_EVConstructionState}");
|
||||
// Debug.Log($"construction_lvl: {_data.Lvl}");
|
||||
// Debug.Log($"retry_type: {_EVRetryType}");
|
||||
// Debug.Log($"hook_count: {_playerData.GetEnergyRM()}");
|
||||
// Debug.Log($"cost_cash: {_EVCost}");
|
||||
// Debug.Log($"reward_hook: {_EVHookRewardGot}");
|
||||
// Debug.Log($"reward_cash: {_EVCashRewardGot}");
|
||||
// Debug.Log($"rating: {_EVRating}");
|
||||
// Debug.Log($"combo_count: {_EVCombo}");
|
||||
// Debug.Log($"cash_back: {_EVCashBack}");
|
||||
#if AGG
|
||||
using (var e = GEvent.GameEvent("infinite_construction"))
|
||||
{
|
||||
e.AddContent("construction_state", _EVConstructionState)
|
||||
.AddContent("construction_lv", _data.Lvl)
|
||||
.AddContent("retry_type", _EVRetryType)
|
||||
.AddContent("hook_count", _playerData.GetEnergyRM())
|
||||
.AddContent("cost_cash", _EVCost)
|
||||
.AddContent("reward_hook", _EVHookRewardGot)
|
||||
.AddContent("reward_cash", _EVCashRewardGot)
|
||||
.AddContent("rating", _EVRating)
|
||||
.AddContent("combo_count", _EVCombo)
|
||||
.AddContent("cash_back", _EVCashBack);
|
||||
}
|
||||
#endif
|
||||
var b = await _blockManager.GenerateBlock(_crane.transform.position + _cfg.blockSpawnOffset);
|
||||
_blockManager.CurrentBlock = b;
|
||||
_data.LastHangingBlock = b.Idx;
|
||||
UpdateData();
|
||||
_crane.AttachJoints(b);
|
||||
_sm.SetState(EInfiniteBuildingState.PlayerCtrl);
|
||||
}
|
||||
|
||||
private void InitLoop_Exit()
|
||||
{
|
||||
//Debug.Log("InitLoop_Exit!");
|
||||
}
|
||||
|
||||
private void PlayerCtrl_Enter()
|
||||
{
|
||||
//Debug.Log("PlayerCtrl_Enter!");
|
||||
//Debug.Log($"<color=red>Player Ctrl thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
PlayerCtrlEnterAsync();
|
||||
//Debug.Log(_crane.gameObject);
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task PlayerCtrlEnterAsync()
|
||||
{
|
||||
await _crane.Descend();
|
||||
_crane.Kick();
|
||||
_mainPanel.ActivateBtns();
|
||||
}
|
||||
|
||||
private void PlayerCtrl_Exit()
|
||||
{
|
||||
//Debug.Log("PlayerCtrl_Exit!");
|
||||
_mainPanel.DeactivateBtns();
|
||||
}
|
||||
|
||||
private void BlockFall_Enter()
|
||||
{
|
||||
//Debug.Log("BlockFall_Enter!");
|
||||
//Debug.Log($"<color=red>Block Fall thread id: {Thread.CurrentThread.ManagedThreadId}</color>");
|
||||
StartCoroutine(_crane.DropBlockAndRise());
|
||||
_blockManager.CurrentBlock.Drop();
|
||||
//_currentBlock.Drop();
|
||||
//DestroyCountDown();
|
||||
}
|
||||
|
||||
private void BlockFall_Exit()
|
||||
{
|
||||
//Debug.Log("BlockFall_Exit!");
|
||||
_blockManager.ResetDestroyCountDown();
|
||||
}
|
||||
|
||||
private void Success_Enter()
|
||||
{
|
||||
//Debug.Log("Success_Enter!");
|
||||
SuccessEnterAsync();
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task SuccessEnterAsync()
|
||||
{
|
||||
int newHeight = (int)_blockManager.CurrentBlock.WorldHeight;
|
||||
int oldHeight = (int)_focus.position.y;
|
||||
int deltaLvl = newHeight > oldHeight ? (int)_blockManager.CurrentBlock.Height : 0;
|
||||
//_blockManager.CurrentBlock.Rb.position =
|
||||
// new Vector2(_blockManager.CurrentBlock.Rb.position.x, _focus.position.y);
|
||||
_blockManager.CurrentBlock.PlayFurnitureAnimation();
|
||||
int combo = CountCombo();
|
||||
int rating = GetRating();
|
||||
bool isPerfect = _blockManager.TrySnap();
|
||||
_EVCombo = combo;
|
||||
_EVRating = rating;
|
||||
if (isPerfect)
|
||||
{
|
||||
_ = PlayAudio("BlockPerfect");
|
||||
PlayFX("fallperfact", _blockManager.CurrentBlock.transform.position + _cfg.fxPerfect);
|
||||
_EVConstructionState = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_EVConstructionState = 1;
|
||||
}
|
||||
|
||||
float refundRatio = 0.0f;
|
||||
if (combo >= 2)
|
||||
refundRatio += Mathf.Min(combo - 1, _tables.TbConstructionInfiniteConfig.ComboReturnMaxCount) *
|
||||
_tables.TbConstructionInfiniteConfig.ComboOnceReturnPoint;
|
||||
if (rating != 0)
|
||||
refundRatio += rating == 1
|
||||
? _tables.TbConstructionInfiniteConfig.GoodReturnPoint
|
||||
: _tables.TbConstructionInfiniteConfig.FantasticReturnPoint;
|
||||
if (isPerfect)
|
||||
refundRatio += _tables.TbConstructionInfiniteConfig.PerfectReturnPoint;
|
||||
// Debug.Log($"<color=red>RefundRatio: {refundRatio}</color>");
|
||||
_mainPanel.PlayRatingFx(rating);
|
||||
_mainPanel.PlayComboFx(combo);
|
||||
_EVCashBack = 0;
|
||||
if (refundRatio != 0.0f)
|
||||
{
|
||||
int price = GetConstructionPrice();
|
||||
int amount = (int)(refundRatio * price);
|
||||
_EVCashBack = (ulong)amount;
|
||||
_playerData.SetGold(_playerData.gold + (ulong)amount);
|
||||
await _mainPanel.PlayCashFlyAnimation(amount);
|
||||
}
|
||||
|
||||
_EVRetryType = 0;
|
||||
_EVHookRewardGot = 0;
|
||||
_EVCashRewardGot = 0;
|
||||
_data.Step++;
|
||||
if (await _mainPanel.UpdateUIWhenSuccess())
|
||||
{
|
||||
await _mainPanel.ReceiveReward();
|
||||
}
|
||||
|
||||
if (newHeight > oldHeight)
|
||||
_focus.position = new Vector3(_focus.position.x, _blockManager.CurrentBlock.WorldHeight, _focus.position.z);
|
||||
_cam.FollowFocus();
|
||||
_blockManager.AddCurrentBlock();
|
||||
_blockManager.LockOrClearBlocks(true);
|
||||
UpdateData(deltaLvl);
|
||||
//leyuanniubi!!!
|
||||
if (deltaLvl > 0)
|
||||
{
|
||||
GContext.Publish(new ConditionTypeEvent(ConditionType.ConstructionCount, deltaLvl));
|
||||
GContext.container.Resolve<LeadboardData>().AwaitSetLvData();
|
||||
}
|
||||
|
||||
_deathWall.transform.position += deltaLvl * Vector3.up;
|
||||
MoveFx(name: "cloud", pos: _focus.position + _cfg.fxCloud);
|
||||
_sm.SetState(EInfiniteBuildingState.InitLoop);
|
||||
}
|
||||
|
||||
private void Success_Exit()
|
||||
{
|
||||
//Debug.Log("Success_Exit!");
|
||||
}
|
||||
|
||||
private void Failure_Enter()
|
||||
{
|
||||
//Debug.Log("Failure_Enter!");
|
||||
FailureEnterAsync();
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task FailureEnterAsync()
|
||||
{
|
||||
_EVCombo = CountCombo(false);
|
||||
_EVConstructionState = 0;
|
||||
_EVRating = 0;
|
||||
_EVCashBack = 0;
|
||||
PlayAudio("Collapse");
|
||||
CampSettlementPanel ui = (await UIManager.Instance.ShowUI(UITypes.CampSettlementPanel))
|
||||
.GetComponent<CampSettlementPanel>();
|
||||
ui.Init(_eventAggregator);
|
||||
await _blockManager.RebuildAllBlocks();
|
||||
_blockManager.LockOrClearBlocks();
|
||||
}
|
||||
|
||||
private void Failure_Exit()
|
||||
{
|
||||
//Debug.Log("Failure_Exit!");
|
||||
}
|
||||
|
||||
//private void BlockDestroy_Enter()
|
||||
//{
|
||||
// Debug.Log("BlockDestroy_Enter!");
|
||||
// //UIManager.Instance.ShowUI(UITypes.CampSettlementPanel);
|
||||
// EnterBlockDestroyAsync();
|
||||
// //_sm.SetState(EInfiniteBuildingState.InitLoop);
|
||||
//}
|
||||
//private void BlockDestroy_Exit()
|
||||
//{
|
||||
// Debug.Log("BlockDestroy_Exit!");
|
||||
//}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum EInfiniteBuildingState
|
||||
{
|
||||
Default,
|
||||
Init,
|
||||
InitLoop,
|
||||
PlayerCtrl,
|
||||
BlockFall,
|
||||
Success,
|
||||
Failure
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingRetry
|
||||
{
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingAlign
|
||||
{
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingBlockDeath
|
||||
{
|
||||
public BlockState stateBeforeDeath { get; set; }
|
||||
|
||||
public EventInfiniteBuildingBlockDeath(BlockState stateBeforeDeath)
|
||||
{
|
||||
this.stateBeforeDeath = stateBeforeDeath;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingConstruct
|
||||
{
|
||||
public ulong ConstructionCost;
|
||||
|
||||
public EventInfiniteBuildingConstruct(ulong cost)
|
||||
{
|
||||
ConstructionCost = cost;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingFail
|
||||
{
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingSucceed
|
||||
{
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingPlayAudio
|
||||
{
|
||||
public string AudioName { get; set; }
|
||||
|
||||
public EventInfiniteBuildingPlayAudio(string audioName)
|
||||
{
|
||||
AudioName = audioName;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingCollisionSound
|
||||
{
|
||||
public string Hash { get; set; }
|
||||
|
||||
public EventInfiniteBuildingCollisionSound(string hash)
|
||||
{
|
||||
Hash = hash;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingFirstCollision
|
||||
{
|
||||
public readonly Block block;
|
||||
|
||||
public EventInfiniteBuildingFirstCollision(Block b)
|
||||
{
|
||||
block = b;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventInfiniteBuildingGetReward
|
||||
{
|
||||
public readonly int DropID;
|
||||
|
||||
public EventInfiniteBuildingGetReward(int dropID)
|
||||
{
|
||||
DropID = dropID;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingAct.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingAct.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ed1a7b98cf4e12428de88bccd086c60
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
56
Assets/Scripts/InfiniteBuilding/InfiniteBuildingConf.cs
Normal file
56
Assets/Scripts/InfiniteBuilding/InfiniteBuildingConf.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
[CreateAssetMenu(fileName = "InfiniteBuildingConf",
|
||||
menuName = "ScriptableObjects/InfiniteBuildingConf", order = 1)]
|
||||
public class InfiniteBuildingConf : ScriptableObject
|
||||
{
|
||||
[Serializable]
|
||||
public class HeightConfigData
|
||||
{
|
||||
public int LvlThresh;
|
||||
public float craneHeightRise;
|
||||
public float craneHeightDescend;
|
||||
public float craneCycleTime;
|
||||
public float cameraDepth = 20f;
|
||||
}
|
||||
[Header("General Debug Settings")]
|
||||
public bool FreezeCrane = false;
|
||||
public int NextBlockToSpawn = -1;
|
||||
[Header("Block Generation Settings")]
|
||||
public int blockDestroyDelay = 4000;//in miliseconds, 1/1000 second
|
||||
public Vector2 craneAnchorOffset = new(0.2f, -0.5f);
|
||||
public float blockAnchorCoefficient = 0.8f;
|
||||
public Vector3 blockSpawnOffset = new(0, -3f, 0);
|
||||
public float blockDriftOffset = 2f;
|
||||
public float blockDestroyThreshAngle = 10f;//in deg
|
||||
public bool maxDistanceOnly = true;
|
||||
public bool hasAutoDistance = true;
|
||||
public float blockRestingOffset = -5f;
|
||||
public float blockDestroyOffset = -8f;
|
||||
public float deathWallOffset = -3;
|
||||
public float snapThresh = 0.5f;
|
||||
public float blockDepth = 20f;
|
||||
public float blockFreezeVelocity = 0.1f;
|
||||
public float blockFreezeAngularVelocity = 0.1f;
|
||||
public float blockFreezeAcc = 1f;
|
||||
public float blockFreezeAngularAcc = 1f;
|
||||
[Header("Crane Settings")]
|
||||
//public float craneRiseTime = 0.5f;
|
||||
//public List<HeightConfigData> heightSpecificConfig = new List<HeightConfigData>();
|
||||
public float craneCycleHalfDistance = 5f;
|
||||
public float craneLineThickness = 0.1f;
|
||||
[Header("Camera Settings")]
|
||||
public float skyLoopTriggerHeight = 1200f;
|
||||
public float skyLoopOffsetDelta = 0.2f;
|
||||
[Header("FX Settings")]
|
||||
public Vector3 fxCollapse = -8f * Vector3.up;
|
||||
public Vector3 fxCloud = -5f * Vector3.up;
|
||||
public float fxCloudAppearHeight = 0f;
|
||||
public Vector3 fxFall = Vector3.zero;
|
||||
public Vector3 fxPerfect = Vector3.zero;
|
||||
[Header("Furniture Animation")]
|
||||
public float3 animationDurationRange = new float3(0.33f, 0.66f, 0.2f);
|
||||
public Color glassColor = new Color(0.7735f, 0.4370f, 0.2298f, 1);
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingConf.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingConf.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 10329b288f550294e831527316fd68c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/Scripts/InfiniteBuilding/InfiniteBuildingData.cs
Normal file
86
Assets/Scripts/InfiniteBuilding/InfiniteBuildingData.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using GameCore;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class InfiniteBuildingData
|
||||
{
|
||||
public int Lvl, Step, StepLvl = 1, LastHangingBlock = -1;
|
||||
public List<BlockRecord> Record = new List<BlockRecord>();
|
||||
// private readonly TbConstructionUnits BlocksTable = GContext.container.Resolve<Tables>().TbConstructionUnits;
|
||||
public int ConstructPrice => (int)
|
||||
(GContext.container.Resolve<Tables>().TbMapData.DataList[^1].ConstrutionCost
|
||||
* GContext.container.Resolve<Tables>().TbConstructionInfiniteConfig.CashMagList[Step]);
|
||||
public struct BlockRecord
|
||||
{
|
||||
public readonly int ID;
|
||||
public Vector2 Pos;
|
||||
public readonly float Height => GContext.container.Resolve<Tables>().TbConstructionUnits[ID].Height;
|
||||
public readonly string PrefabID => GContext.container.Resolve<Tables>().TbConstructionUnits[ID].Prefab;
|
||||
public BlockRecord(int id = 0, Vector2 pos = default)
|
||||
{
|
||||
this.ID = id;
|
||||
this.Pos = pos;
|
||||
}
|
||||
public BlockRecord(int id = 0, float x = 0, float y = 0)
|
||||
{
|
||||
this.ID = id;
|
||||
Pos = new Vector2(x, y);
|
||||
}
|
||||
public readonly override string ToString() => $"{ID},{Pos.x},{Pos.y}";
|
||||
}
|
||||
private string Serialize()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
sb.Append($"{Lvl},{Step},{StepLvl},{LastHangingBlock},");
|
||||
foreach (BlockRecord node in Record)
|
||||
sb.Append($"{node.ToString()},");
|
||||
return sb.ToString().Trim(',');
|
||||
}
|
||||
public void Deserialize(string s)
|
||||
{
|
||||
string[] tokens = s.Split(',');
|
||||
if (tokens == null || tokens.Length < 4 || tokens.Length % 3 != 1)
|
||||
{
|
||||
Debug.LogWarning($"string \"{s}\" cannot be deserialized.");
|
||||
return;
|
||||
}
|
||||
Lvl = int.Parse(tokens[0]);
|
||||
Step = int.Parse(tokens[1]);
|
||||
StepLvl = int.Parse(tokens[2]);
|
||||
LastHangingBlock = int.Parse(tokens[3]);
|
||||
Record = new List<BlockRecord>();
|
||||
for (int i = 4; i < tokens.Length; i+=3)
|
||||
{
|
||||
Record.Add(new BlockRecord(int.Parse(tokens[i]),
|
||||
float.Parse(tokens[i + 1]), float.Parse(tokens[i + 2])));
|
||||
//Debug.Log($"{int.Parse(tokens[i])}, {float.Parse(tokens[i + 1])}, {float.Parse(tokens[i + 2])}");
|
||||
}
|
||||
}
|
||||
public void UploadData()
|
||||
{
|
||||
string s = Serialize();
|
||||
//Debug.Log("Upload!!!!!!!!!!!!!!");
|
||||
//Debug.Log(s);
|
||||
GContext.container.Resolve<PlayerData>().InfiniteBuildingData = s;
|
||||
PlayFabMgr.Instance.UpdateUserDataValue("InfiniteBuildingData", s);
|
||||
}
|
||||
|
||||
public void DownloadData(string s)
|
||||
{
|
||||
Deserialize(s);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
public void PrintSelf()
|
||||
{
|
||||
Debug.Log($"Lvl: {Lvl}");
|
||||
Debug.Log($"Step: {Step}");
|
||||
Debug.Log($"StepLvl: {StepLvl}");
|
||||
foreach (BlockRecord node in Record)
|
||||
{
|
||||
Debug.Log($"node: {node.PrefabID}, {node.Pos}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingData.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingData.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 04013307478c7bd43a953e3a332b768f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cc5cea7e748f4fe8814954cc54a90d6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
public class ConvertFromArtPrefabToGamePrefab : EditorWindow
|
||||
{
|
||||
[MenuItem("Tools/Creat IB Prefabs")]
|
||||
public static void ConvertPrefabs()
|
||||
{
|
||||
Object[] artPrefabs = Selection.objects;
|
||||
PhysicsMaterial2D pm = AssetDatabase.LoadAssetAtPath<PhysicsMaterial2D>("Assets/ABPackage/InfiniteBuildingPrefabs/PhysicMat_Block.physicsMaterial2D");
|
||||
string dest = "Assets/ABPackage/InfiniteBuildingPrefabs/";
|
||||
foreach (Object artGO in artPrefabs)
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(artGO);
|
||||
GameObject artPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||||
GameObject artInstance = PrefabUtility.InstantiatePrefab(artPrefab) as GameObject;
|
||||
Debug.Log(assetPath);
|
||||
if (artInstance == null)
|
||||
continue;
|
||||
string artName = artPrefab.name;
|
||||
BoxCollider artBc = artInstance.GetComponent<BoxCollider>();
|
||||
Vector3 colliderSize = artBc.size;
|
||||
Vector3 colliderCenter = artBc.center;
|
||||
DestroyImmediate(artBc, true);
|
||||
|
||||
GameObject go = new GameObject();
|
||||
go.name = artName;
|
||||
go.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
go.transform.localScale = Vector3.one;
|
||||
artInstance.transform.parent = go.transform;
|
||||
artInstance.transform.position = Vector3.zero;
|
||||
Rigidbody2D rb = go.AddComponent<Rigidbody2D>();
|
||||
rb.drag = 4;
|
||||
rb.angularDrag = 1;
|
||||
BoxCollider2D bc = go.AddComponent<BoxCollider2D>();
|
||||
bc.sharedMaterial = pm;
|
||||
bc.isTrigger = false;
|
||||
bc.offset = new Vector2(-colliderCenter.x, colliderCenter.z);
|
||||
bc.size = new Vector2(colliderSize.x, colliderSize.z);
|
||||
go.AddComponent<Block>();
|
||||
PrefabUtility.SaveAsPrefabAsset(go, dest + go.name + ".prefab");
|
||||
AssetDatabase.SaveAssets();
|
||||
Debug.Log($"Converted colliders in prefab: {go.name}");
|
||||
DestroyImmediate(go, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc6578f9d1b69ad4cb9e685605e185dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "InfiniteBuilding.Editor",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:f720a012c494ab7478b1926183db234f"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ea8c55f787d445a8bcb69e94dd0cf9b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/InfiniteBuilding/InfiniteBuildingFSM.cs
Normal file
18
Assets/Scripts/InfiniteBuilding/InfiniteBuildingFSM.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class InfiniteBuildingFSM
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingFSM.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingFSM.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b13f87b4a1981ac4f94999f3c421c760
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/InfiniteBuilding/InfiniteBuildingUI.cs
Normal file
18
Assets/Scripts/InfiniteBuilding/InfiniteBuildingUI.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class InfiniteBuildingUI : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingUI.cs.meta
Normal file
11
Assets/Scripts/InfiniteBuilding/InfiniteBuildingUI.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f188429e27e05d4a826fb954bd453b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user