fix(heatmap): 按Sprite几何中心旋转风扇避免散架
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -122,7 +122,7 @@ ScriptedImporter:
|
||||
- name: "\xE9\xA3\x8E\xE6\x89\x87"
|
||||
originalName:
|
||||
pivot: {x: 0.5, y: 0.5}
|
||||
alignment: 0
|
||||
alignment: 9
|
||||
border: {x: 0, y: 0, z: 0, w: 0}
|
||||
rect:
|
||||
serializedVersion: 2
|
||||
|
||||
@@ -21,6 +21,8 @@ public class HeatMapController : MonoBehaviour
|
||||
public RectTransform imageToMove; // 需要移动的Image
|
||||
public Transform imageToRotate; // 需要旋转的Image
|
||||
[SerializeField, Min(0f)] private float fanStopDuration = 0.15f;
|
||||
[Tooltip("相对 Sprite 矩形中心的额外旋转轴偏移(本地空间,单位与 Transform 一致)。用于校准扇毂不在图心时的偏心。")]
|
||||
[SerializeField] private Vector2 fanPivotLocalOffset;
|
||||
[Header("低温背景")]
|
||||
[SerializeField] private Color coldBaseColor = new Color(0.005f, 0.02f, 0.55f, 1f);
|
||||
[SerializeField] private Color coldHighlightColor = new Color(0f, 0.3f, 1f, 1f);
|
||||
@@ -45,6 +47,9 @@ public class HeatMapController : MonoBehaviour
|
||||
private Tween _temptureTween;
|
||||
private Tween _fanSpeedTween;
|
||||
private float _fanAngularSpeed;
|
||||
private SpriteRenderer _fanRenderer;
|
||||
private Vector3 _fanLocalPivot; // 相对 imageToRotate 的本地旋转轴
|
||||
private bool _fanPivotReady;
|
||||
|
||||
private const float FanAngularSpeed = 1800f;
|
||||
|
||||
@@ -145,13 +150,53 @@ public class HeatMapController : MonoBehaviour
|
||||
if (imageToRotate == null || Mathf.Approximately(_fanAngularSpeed, 0f))
|
||||
return;
|
||||
|
||||
imageToRotate.Rotate(0f, 0f, _fanAngularSpeed * Time.deltaTime, Space.Self);
|
||||
EnsureFanPivot();
|
||||
float angle = _fanAngularSpeed * Time.deltaTime;
|
||||
// 绕 Sprite 几何中心转,避免 pivot 不在扇叶中心时整圈公转(看起来像散架)。
|
||||
Vector3 worldPivot = imageToRotate.TransformPoint(_fanLocalPivot);
|
||||
imageToRotate.RotateAround(worldPivot, imageToRotate.forward, angle);
|
||||
}
|
||||
|
||||
private void EnsureFanPivot()
|
||||
{
|
||||
if (_fanPivotReady)
|
||||
return;
|
||||
|
||||
_fanLocalPivot = Vector3.zero;
|
||||
if (imageToRotate == null)
|
||||
{
|
||||
_fanPivotReady = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_fanRenderer = imageToRotate.GetComponent<SpriteRenderer>();
|
||||
if (_fanRenderer != null && _fanRenderer.sprite != null)
|
||||
{
|
||||
var sprite = _fanRenderer.sprite;
|
||||
// transform 在 sprite.pivot;矩形几何中心相对 pivot 的本地偏移。
|
||||
// Aseprite Canvas 空间 pivot 会远超出 [0,1],直接 Rotate 会整圈公转。
|
||||
Vector2 size = sprite.rect.size;
|
||||
Vector2 pivotPx = sprite.pivot;
|
||||
float ppu = sprite.pixelsPerUnit;
|
||||
if (ppu > 0f)
|
||||
{
|
||||
_fanLocalPivot = new Vector3(
|
||||
(size.x * 0.5f - pivotPx.x) / ppu,
|
||||
(size.y * 0.5f - pivotPx.y) / ppu,
|
||||
0f);
|
||||
}
|
||||
}
|
||||
|
||||
_fanLocalPivot += (Vector3)fanPivotLocalOffset;
|
||||
_fanPivotReady = true;
|
||||
}
|
||||
|
||||
private void StartFan()
|
||||
{
|
||||
_fanSpeedTween?.Kill();
|
||||
_fanSpeedTween = null;
|
||||
_fanPivotReady = false;
|
||||
EnsureFanPivot();
|
||||
_fanAngularSpeed = FanAngularSpeed;
|
||||
}
|
||||
|
||||
@@ -182,6 +227,7 @@ public class HeatMapController : MonoBehaviour
|
||||
void Start()
|
||||
{
|
||||
bodyModuleSystem = FindObjectOfType<BodyModuleSystem>();
|
||||
EnsureFanPivot();
|
||||
SetDataToMaterial();
|
||||
}
|
||||
|
||||
@@ -319,4 +365,34 @@ public class HeatMapController : MonoBehaviour
|
||||
.SetEase(Ease.InOutQuad)
|
||||
.SetTarget(this);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
if (imageToRotate == null)
|
||||
return;
|
||||
|
||||
// 编辑器下也能预览旋转轴(不依赖 Play 时缓存)。
|
||||
var sr = imageToRotate.GetComponent<SpriteRenderer>();
|
||||
Vector3 localPivot = (Vector3)fanPivotLocalOffset;
|
||||
if (sr != null && sr.sprite != null && sr.sprite.pixelsPerUnit > 0f)
|
||||
{
|
||||
var sprite = sr.sprite;
|
||||
Vector2 size = sprite.rect.size;
|
||||
Vector2 pivotPx = sprite.pivot;
|
||||
float ppu = sprite.pixelsPerUnit;
|
||||
localPivot += new Vector3(
|
||||
(size.x * 0.5f - pivotPx.x) / ppu,
|
||||
(size.y * 0.5f - pivotPx.y) / ppu,
|
||||
0f);
|
||||
}
|
||||
|
||||
Vector3 worldPivot = imageToRotate.TransformPoint(localPivot);
|
||||
Gizmos.color = new Color(1f, 0.45f, 0.1f, 0.9f);
|
||||
Gizmos.DrawWireSphere(worldPivot, 0.08f);
|
||||
Gizmos.color = new Color(0.3f, 0.9f, 0.55f, 0.7f);
|
||||
Gizmos.DrawLine(worldPivot + Vector3.left * 0.2f, worldPivot + Vector3.right * 0.2f);
|
||||
Gizmos.DrawLine(worldPivot + Vector3.down * 0.2f, worldPivot + Vector3.up * 0.2f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user