using AibisDream.FixSystem; using AibisDream.Framework; using AibisDream.Utility; using DG.Tweening; using UnityEngine; using UnityEngine.EventSystems; using Random = UnityEngine.Random; namespace AibisDream { public class Gear : MonoBehaviour, IInteraction { private const int ShakeAngle = 15; public float radius; public Sprite gearSprite; public string gearProp; public bool isBroken; public bool isDisc; public bool isConstant; public float speed; private Tweener _rotationTweener; #region 引用 private GearSystem _gearSystem; private CircleCollider2D _circleCollider; private SpriteRenderer _spriteRenderer; private EventTriggerEx _trigger; #endregion public Shaft targetShaft; private void Awake() { _circleCollider = GetComponent(); _spriteRenderer = GetComponent(); _trigger = GetComponent(); _trigger.Register(EventTriggerType.Drag, OnDrag); _trigger.Register(EventTriggerType.BeginDrag, StartMove); _trigger.Register(EventTriggerType.EndDrag, StopMove); } private void Start() { _gearSystem = FixSystemCenter.SystemDic.Get(); // 给齿轮赋值 InitGearModel(); } /// /// 设置齿轮信息 /// private void InitGearModel() { // 给齿轮赋值 _spriteRenderer.sprite = gearSprite; _circleCollider.radius = radius; _spriteRenderer.size = new Vector2(radius * 2, radius * 2); } public void UpdateRotation(float newSpeed, float speedScale) { // 初始化速度 speed = Mathf.Abs(newSpeed); var target = newSpeed >= 0 ? new Vector3(0, 0, 360) : new Vector3(0, 0, -360); _rotationTweener?.Kill(); // 打开动画 if (isBroken) { _rotationTweener = transform.DORotate(new Vector3(0, 0, ShakeAngle), ShakeAngle / speed / 360, RotateMode.LocalAxisAdd) .SetEase(Ease.Linear) .SetLoops(-1, LoopType.Yoyo) .SetDelay(0.1f); } else { _rotationTweener = transform.DORotate(target, 1 / Mathf.Abs(speed), RotateMode.LocalAxisAdd) .SetEase(Ease.Linear) .SetLoops(-1, LoopType.Incremental); } _rotationTweener.timeScale = speedScale; } public void UpdateSpeedScale(float speedScale) { _rotationTweener.timeScale = speedScale; } #region 移动相关 private void StartMove(BaseEventData eventData) { // 这里是一些阻碍拖动的情况 if (!IsActive) return; // 正常情况下不会出错 if (eventData is not PointerEventData pointerData) return; transform.position = CommonUtil.GetMouseWorldPos(pointerData.position, transform); targetShaft?.PlugOutGear(); transform.DOPause(); } public void StopMove(BaseEventData eventData) { // 正常情况下不会出错 if (eventData is not PointerEventData pointerData) return; if (targetShaft) { transform.position = targetShaft.transform.position; targetShaft.PlugInGear(this); } } private void OnDrag(BaseEventData eventData) { // 这里是一些阻碍拖动的情况 if (!IsActive) return; // 正常情况下不会出错 if (eventData is not PointerEventData pointerData) return; transform.position = CommonUtil.GetMouseWorldPos(pointerData.position, transform); var tempShaft = _gearSystem.CheckClosestShaft(transform.position, radius); if (!tempShaft) return; if (_gearSystem.CheckGearSuitable(tempShaft, radius)) { targetShaft = tempShaft; } } public void Popup() { // 先激活刚体 var rb = GetComponent(); rb.bodyType = RigidbodyType2D.Dynamic; rb.mass = 0.5f; rb.gravityScale = 1f; // 施加一个随机方向的力 var randomDirection = Random.insideUnitCircle.normalized; rb.AddForce(randomDirection * 3, ForceMode2D.Impulse); // 一段时间后销毁 _ = CommonUtil.Delay(2000, () => { Destroy(gameObject); }); } private void OnDestroy() { transform.DOKill(); } #endregion #region 交互锁定相关 public bool IsActive => !isConstant; public bool IsAvailable => _gearSystem.isAvailable; public GameObject GetGameObject() { return gameObject; } #endregion } }