using AibisDream.Utility; using DG.Tweening; using UnityEngine; namespace AibisDream { public class Shaft : MonoBehaviour { [SerializeField] private int id; [SerializeField] public ShaftType shaftType; // 初始角速度 [SerializeField] private float initialSpeed; // 初始齿轮 [SerializeField] private GearModel gearModel; private GameObject childGear; // 目标角速度 [SerializeField] private float targetSpeed; // 当前角速度 public float speed; /// /// 当前齿轮半径 /// public float GearRadius { get { if (!childGear) { return 0; } if (shaftType == ShaftType.Pluggable) { Gear gear = childGear.GetComponent(); return gear.data.radius; } else { return gearModel.radius; } } } private GearController gearController; private void Awake() { gearController = transform.parent.parent.GetComponent(); } /// /// 初始化当前轴位置 /// public void InitShaft() { // 如果不带齿轮 if (gearModel == null) { return; } // 如果带齿轮,要根据齿轮类型生成 childGear = shaftType == ShaftType.Pluggable ? InitPluggableGear() : InitStaticGear(); speed = initialSpeed; UpdateSpeed(); } private GameObject InitStaticGear() { GameObject staticGear = transform.GetChild(0).gameObject; // 添加齿轮图片 staticGear.SetActive(true); staticGear.GetComponent().sprite = Resources.Load(gearModel.spriteName); // 如果有初速,就要开始转动了 if (!CommonUtil.IsZero(initialSpeed)) { staticGear.transform.DORotate(new Vector3(0, 0, 360), 1 / initialSpeed, RotateMode.LocalAxisAdd) .SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental); } return staticGear; } private GameObject InitPluggableGear() { return gearController.InitGear(transform.position, gearModel, initialSpeed); } public void PlugInGear(Gear gear) { childGear = gear.gameObject; } public void PlugOutGear() { childGear = null; } public void UpdateSpeed() { UpdateSpeedAnima(); CheckGameState(); } /// /// 速度修改后改变动画 /// private void UpdateSpeedAnima() { // 没有齿轮的不需要旋转 if (!HasChildGear()) { return; } if (CommonUtil.IsZero(speed)) { childGear.transform.DOPause(); return; } // 更新动画 childGear.transform.DOKill(); childGear.transform.DORotate(new Vector3(0, 0, 360), 1 / speed, RotateMode.LocalAxisAdd) .SetEase(Ease.Linear).SetLoops(-1, LoopType.Incremental); } private void CheckGameState() { if (shaftType == ShaftType.Target) { if (targetSpeed <= speed) { gearController.Succeed(); } } } /// /// 判断是否带齿轮 /// /// 是否带齿轮 public bool HasChildGear() { return childGear; } /// /// 判断两个轴是否齿轮相接 /// /// 轴1 /// 轴2 /// 是否相接 public static bool IsShaftConnected(Shaft shaft1, Shaft shaft2) { // 如果轴上无齿轮就不计算 if (!shaft1 || !shaft2) { return false; } if (!shaft1.childGear || !shaft2.childGear) { return false; } // 如果两个都有齿轮,就判断是否相邻 float distance = (shaft1.transform.position - shaft2.transform.position).magnitude; float radiusSum = shaft1.GearRadius + shaft2.GearRadius; return distance < radiusSum; } /// /// 求两个轴角速度之比 /// /// 轴1 /// 轴2 /// 角速度之比 public static float CalcAngularVelocityRatio(Shaft shaft1, Shaft shaft2) { return shaft1.GearRadius / shaft2.GearRadius; } } public enum ShaftType { Driver, // 拥有初始速度,没有目标速度,全局仅有一个 Target, // 没有初始速度,有目标速度,全局有多个 Constant, // 没有初始速度,没有目标速度,不可拖动 Pluggable, // 没有初始速度,没有目标速度,可拔插 Outside // 放在身体外面的轴,仅用于放置齿轮 } }