备份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
|
||||
}
|
||||
Reference in New Issue
Block a user