Files
Liubing\LB 3d8d4d18f3 first commit
先修复一下,错误的场景

删除不必要的钓场资产

修复into场景

update:更新meta文件,修复报错

update:修复资源

修复第一章节建造

修复建造第三章

update:删除多余内容

update:更新README.md

update:还原图标

update:更新README

update:更新配置
2026-04-28 02:17:22 +08:00

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
}