先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
217 lines
7.0 KiB
C#
217 lines
7.0 KiB
C#
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
|
|
}
|