Merge pull request 'feature/CheckSkill_Cuong' (#442) from feature/CheckSkill_Cuong into develop
Reviewed-on: https://git.pthub.vn/Unity/perfect-world-unity/pulls/442
This commit is contained in:
@@ -5,6 +5,12 @@ using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts.UI.Inventory
|
||||
{
|
||||
public enum PreviewDistanceScaleMode
|
||||
{
|
||||
AspectRatio,
|
||||
ViewportHeight
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the current host-player visual model into a dedicated preview rig for the inventory UI.
|
||||
/// </summary>
|
||||
@@ -45,6 +51,17 @@ namespace BrewMonster.Scripts.UI.Inventory
|
||||
[SerializeField] private float minAutoCameraDistance = 1.25f;
|
||||
[SerializeField] private float maxAutoCameraDistance = 8f;
|
||||
|
||||
[Header("Device Framing")]
|
||||
[Tooltip("Design-time screen width (1920x1080 baseline); previewCameraDistance/offset tuned for this.")]
|
||||
[SerializeField] private float referenceScreenWidth = 1920f;
|
||||
[Tooltip("Design-time screen height (1920x1080 baseline); previewCameraDistance/offset tuned for this.")]
|
||||
[SerializeField] private float referenceScreenHeight = 1080f;
|
||||
[Tooltip("Use previewFrame pixel size when available; otherwise Screen.width/height.")]
|
||||
[SerializeField] private bool useRawImageViewport = true;
|
||||
[SerializeField] private PreviewDistanceScaleMode distanceScaleMode = PreviewDistanceScaleMode.AspectRatio;
|
||||
[Tooltip("Scale previewCameraOffset.y by viewport height vs 1080p reference (1.0 at 1920x1080).")]
|
||||
[SerializeField] private bool scaleCameraOffsetYByViewport = true;
|
||||
|
||||
private bool _cameraStateCached;
|
||||
private Vector3 _cachedCameraPosition;
|
||||
private Quaternion _cachedCameraRotation;
|
||||
@@ -396,7 +413,8 @@ namespace BrewMonster.Scripts.UI.Inventory
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 focusPoint = modelRoot.TransformPoint(cameraFocusOffset) + previewCameraOffset;
|
||||
Vector3 effectiveOffset = ComputeEffectiveCameraOffset();
|
||||
Vector3 focusPoint = modelRoot.TransformPoint(cameraFocusOffset) + effectiveOffset;
|
||||
|
||||
Vector3 viewDirection = modelRoot.forward;
|
||||
viewDirection.y = 0f;
|
||||
@@ -407,10 +425,178 @@ namespace BrewMonster.Scripts.UI.Inventory
|
||||
|
||||
viewDirection.Normalize();
|
||||
|
||||
_previewCamera.transform.position = focusPoint + viewDirection * previewCameraDistance;
|
||||
float effectiveDistance = ComputeEffectiveCameraDistance(modelRoot, focusPoint, viewDirection);
|
||||
_previewCamera.transform.position = focusPoint + viewDirection * effectiveDistance;
|
||||
_previewCamera.transform.LookAt(focusPoint);
|
||||
}
|
||||
|
||||
private bool TryGetViewportSize(out float width, out float height)
|
||||
{
|
||||
if (useRawImageViewport && previewFrame != null)
|
||||
{
|
||||
RectTransform rt = previewFrame.rectTransform;
|
||||
Canvas canvas = previewFrame.canvas;
|
||||
float scale = canvas != null ? canvas.scaleFactor : 1f;
|
||||
width = rt.rect.width * scale;
|
||||
height = rt.rect.height * scale;
|
||||
|
||||
if (width > 1f && height > 1f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
width = Screen.width;
|
||||
height = Screen.height;
|
||||
return width > 0f && height > 0f;
|
||||
}
|
||||
|
||||
private float ComputeAspectScaledDistance()
|
||||
{
|
||||
float distance = previewCameraDistance * ComputeViewportFramingScale();
|
||||
return Mathf.Clamp(distance, minAutoCameraDistance, maxAutoCameraDistance);
|
||||
}
|
||||
|
||||
private float ComputeViewportFramingScale()
|
||||
{
|
||||
if (!TryGetViewportSize(out float viewportWidth, out float viewportHeight))
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
float refWidth = Mathf.Max(1f, referenceScreenWidth);
|
||||
float refHeight = Mathf.Max(1f, referenceScreenHeight);
|
||||
|
||||
switch (distanceScaleMode)
|
||||
{
|
||||
case PreviewDistanceScaleMode.ViewportHeight:
|
||||
return viewportHeight / refHeight;
|
||||
default:
|
||||
float refAspect = refWidth / refHeight;
|
||||
float viewAspect = viewportWidth / viewportHeight;
|
||||
return viewAspect / refAspect;
|
||||
}
|
||||
}
|
||||
|
||||
private float ComputeViewportHeightScale()
|
||||
{
|
||||
if (!TryGetViewportSize(out _, out float viewportHeight))
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
float refHeight = Mathf.Max(1f, referenceScreenHeight);
|
||||
return viewportHeight / refHeight;
|
||||
}
|
||||
|
||||
private Vector3 ComputeEffectiveCameraOffset()
|
||||
{
|
||||
if (!scaleCameraOffsetYByViewport)
|
||||
{
|
||||
return previewCameraOffset;
|
||||
}
|
||||
|
||||
// Tuned at 1920x1080: scale is 1.0 so previewCameraOffset.y is unchanged on reference resolution.
|
||||
float offsetYScale = ComputeViewportHeightScale();
|
||||
return new Vector3(
|
||||
previewCameraOffset.x,
|
||||
previewCameraOffset.y * offsetYScale,
|
||||
previewCameraOffset.z);
|
||||
}
|
||||
|
||||
private float ComputeBoundsFitDistance(Transform modelRoot, Vector3 focusPoint, Vector3 viewDirection)
|
||||
{
|
||||
if (modelRoot == null)
|
||||
{
|
||||
return previewCameraDistance;
|
||||
}
|
||||
|
||||
var renderers = modelRoot.GetComponentsInChildren<Renderer>(true);
|
||||
if (renderers == null || renderers.Length == 0)
|
||||
{
|
||||
return previewCameraDistance;
|
||||
}
|
||||
|
||||
Bounds bounds = renderers[0].bounds;
|
||||
for (int i = 1; i < renderers.Length; i++)
|
||||
{
|
||||
if (renderers[i] != null)
|
||||
{
|
||||
bounds.Encapsulate(renderers[i].bounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (bounds.size.sqrMagnitude < 0.0001f)
|
||||
{
|
||||
return previewCameraDistance;
|
||||
}
|
||||
|
||||
if (!TryGetViewportSize(out float viewportWidth, out float viewportHeight))
|
||||
{
|
||||
return previewCameraDistance;
|
||||
}
|
||||
|
||||
Vector3 cameraForward = -viewDirection;
|
||||
Vector3 cameraRight = Vector3.Cross(cameraForward, Vector3.up);
|
||||
if (cameraRight.sqrMagnitude < 0.0001f)
|
||||
{
|
||||
cameraRight = Vector3.Cross(cameraForward, Vector3.forward);
|
||||
}
|
||||
cameraRight.Normalize();
|
||||
Vector3 cameraUp = Vector3.Cross(cameraRight, cameraForward).normalized;
|
||||
|
||||
Vector3 boundsMin = bounds.min;
|
||||
Vector3 boundsMax = bounds.max;
|
||||
float maxHorizontal = 0f;
|
||||
float maxVertical = 0f;
|
||||
|
||||
for (int x = 0; x <= 1; x++)
|
||||
{
|
||||
for (int y = 0; y <= 1; y++)
|
||||
{
|
||||
for (int z = 0; z <= 1; z++)
|
||||
{
|
||||
Vector3 corner = new Vector3(
|
||||
x == 0 ? boundsMin.x : boundsMax.x,
|
||||
y == 0 ? boundsMin.y : boundsMax.y,
|
||||
z == 0 ? boundsMin.z : boundsMax.z);
|
||||
Vector3 offset = corner - focusPoint;
|
||||
maxHorizontal = Mathf.Max(maxHorizontal, Mathf.Abs(Vector3.Dot(offset, cameraRight)));
|
||||
maxVertical = Mathf.Max(maxVertical, Mathf.Abs(Vector3.Dot(offset, cameraUp)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float viewAspect = viewportWidth / viewportHeight;
|
||||
float verticalFovRad = previewFieldOfView * Mathf.Deg2Rad;
|
||||
float halfVerticalTan = Mathf.Tan(verticalFovRad * 0.5f);
|
||||
if (halfVerticalTan < 0.0001f)
|
||||
{
|
||||
return previewCameraDistance;
|
||||
}
|
||||
|
||||
float halfHorizontalTan = halfVerticalTan * viewAspect;
|
||||
float distanceForHeight = maxVertical / halfVerticalTan;
|
||||
float distanceForWidth = maxHorizontal / Mathf.Max(halfHorizontalTan, 0.0001f);
|
||||
float boundsDistance = Mathf.Max(distanceForHeight, distanceForWidth);
|
||||
|
||||
return boundsDistance * autoFramePadding;
|
||||
}
|
||||
|
||||
private float ComputeEffectiveCameraDistance(Transform modelRoot, Vector3 focusPoint, Vector3 viewDirection)
|
||||
{
|
||||
float aspectScaledDistance = ComputeAspectScaledDistance();
|
||||
float effectiveDistance = aspectScaledDistance;
|
||||
|
||||
if (autoFrameByBounds)
|
||||
{
|
||||
float boundsDistance = ComputeBoundsFitDistance(modelRoot, focusPoint, viewDirection);
|
||||
effectiveDistance = Mathf.Max(aspectScaledDistance, boundsDistance);
|
||||
}
|
||||
|
||||
return Mathf.Clamp(effectiveDistance, minAutoCameraDistance, maxAutoCameraDistance);
|
||||
}
|
||||
|
||||
//private void StripRuntimeScripts(GameObject cloneRoot)
|
||||
//{
|
||||
// if (cloneRoot == null)
|
||||
|
||||
@@ -500,10 +500,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 588.35, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &9112205963990496432
|
||||
CanvasRenderer:
|
||||
@@ -907,10 +907,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 479.18, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3997873020355048166
|
||||
CanvasRenderer:
|
||||
@@ -1238,10 +1238,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 370.01, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4479228720555407959
|
||||
CanvasRenderer:
|
||||
@@ -4929,10 +4929,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 42.5, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7052320096474271168
|
||||
CanvasRenderer:
|
||||
@@ -11103,9 +11103,18 @@ MonoBehaviour:
|
||||
autoFocusCamera: 1
|
||||
cameraFocusOffset: {x: 0, y: 0, z: 0}
|
||||
previewCameraDistance: 3.3
|
||||
previewCameraOffset: {x: 0.06, y: 1.07, z: 0}
|
||||
previewCameraOffset: {x: 0.06, y: 2.04, z: 0}
|
||||
overrideFieldOfView: 1
|
||||
previewFieldOfView: 44
|
||||
autoFrameByBounds: 1
|
||||
autoFramePadding: 1.15
|
||||
minAutoCameraDistance: 1.25
|
||||
maxAutoCameraDistance: 8
|
||||
referenceScreenWidth: 1920
|
||||
referenceScreenHeight: 1080
|
||||
useRawImageViewport: 1
|
||||
distanceScaleMode: 0
|
||||
scaleCameraOffsetYByViewport: 1
|
||||
--- !u!1 &5473020210238587200
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -12366,6 +12375,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
skillNameText: {fileID: 0}
|
||||
imageProgress: {fileID: 0}
|
||||
btnCancel: {fileID: 0}
|
||||
inventoryPackButtons:
|
||||
- {fileID: 8631960679953241981}
|
||||
- {fileID: 7087549554151292240}
|
||||
@@ -14070,10 +14080,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 151.67, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &4452551064742165538
|
||||
CanvasRenderer:
|
||||
@@ -19517,10 +19527,10 @@ RectTransform:
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7166820878650541780}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 260.84, y: -59.5}
|
||||
m_SizeDelta: {x: 85, y: 85}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5155025384962724770
|
||||
CanvasRenderer:
|
||||
|
||||
Reference in New Issue
Block a user