Working screen anchoring
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using UnityEngine;
|
||||
using Unity.Cinemachine;
|
||||
using System;
|
||||
|
||||
namespace AppleHillsCamera
|
||||
{
|
||||
@@ -17,6 +18,9 @@ namespace AppleHillsCamera
|
||||
|
||||
[Tooltip("Whether to adjust the camera automatically when the screen size changes")]
|
||||
public bool adjustOnScreenResize = true;
|
||||
|
||||
// Event that other components can subscribe to when camera is adjusted
|
||||
public event Action OnCameraAdjusted;
|
||||
|
||||
private Camera _regularCamera;
|
||||
private CinemachineCamera _virtualCamera;
|
||||
@@ -104,8 +108,20 @@ namespace AppleHillsCamera
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("CameraScreenAdapter: Regular camera is not in orthographic mode.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify subscribers that the camera has been adjusted
|
||||
OnCameraAdjusted?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the camera component being controlled by this adapter
|
||||
/// </summary>
|
||||
public Camera GetControlledCamera()
|
||||
{
|
||||
return _usingCinemachine ? _virtualCamera.GetComponent<Camera>() : _regularCamera;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using UnityEngine;
|
||||
using AppleHills.Core;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
namespace AppleHillsCamera
|
||||
{
|
||||
@@ -8,6 +10,9 @@ namespace AppleHillsCamera
|
||||
[ExecuteInEditMode] // Make it run in the editor
|
||||
public class EdgeAnchor : MonoBehaviour
|
||||
{
|
||||
// Event that fires when the anchor's position is updated
|
||||
public event Action OnPositionUpdated;
|
||||
|
||||
public enum AnchorEdge
|
||||
{
|
||||
Top,
|
||||
@@ -19,6 +24,9 @@ namespace AppleHillsCamera
|
||||
[Tooltip("Reference marker that defines the screen edges and margins")]
|
||||
public ScreenReferenceMarker referenceMarker;
|
||||
|
||||
[Tooltip("Camera adapter to subscribe to for runtime updates")]
|
||||
public CameraScreenAdapter cameraAdapter;
|
||||
|
||||
[Tooltip("Which screen edge to anchor to")]
|
||||
public AnchorEdge anchorEdge = AnchorEdge.Top;
|
||||
|
||||
@@ -37,18 +45,29 @@ namespace AppleHillsCamera
|
||||
[Tooltip("Whether to preserve the object's position on other axes")]
|
||||
public bool preserveOtherAxes = true;
|
||||
|
||||
[Tooltip("Whether to account for this object's size in positioning")]
|
||||
public bool accountForObjectSize = true;
|
||||
|
||||
[Header("Visualization")]
|
||||
[Tooltip("Whether to show the anchor visualization in the editor")]
|
||||
public bool showVisualization = true;
|
||||
|
||||
[Tooltip("Color for the anchor visualization line")]
|
||||
public Color visualizationColor = new Color(1f, 0f, 0f, 0.8f);
|
||||
|
||||
[Tooltip("Show object bounds in visualization")]
|
||||
public bool showObjectBounds = true;
|
||||
|
||||
[Tooltip("Debug mode - print position changes to console")]
|
||||
public bool debugMode = false;
|
||||
|
||||
private Camera _camera;
|
||||
private int _lastScreenWidth;
|
||||
private int _lastScreenHeight;
|
||||
private float _lastOrthoSize = 0f;
|
||||
private Vector3 _originalPosition;
|
||||
private bool _initialized = false;
|
||||
private Bounds _objectBounds;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmos()
|
||||
@@ -56,19 +75,39 @@ namespace AppleHillsCamera
|
||||
if (!showVisualization || referenceMarker == null)
|
||||
return;
|
||||
|
||||
// Draw a line from the object to its anchor point
|
||||
Vector3 anchorPoint = GetAnchorPoint();
|
||||
// Find camera if needed
|
||||
if (_camera == null)
|
||||
FindCamera();
|
||||
|
||||
if (_camera == null)
|
||||
return;
|
||||
|
||||
// Calculate the anchor point (the exact point on the screen edge)
|
||||
Vector3 anchorPoint = CalculateScreenEdgePoint();
|
||||
|
||||
// Save original color
|
||||
Color originalColor = Gizmos.color;
|
||||
|
||||
// Draw line to anchor point
|
||||
Gizmos.color = visualizationColor;
|
||||
Gizmos.DrawLine(gameObject.transform.position, anchorPoint);
|
||||
Gizmos.DrawLine(transform.position, anchorPoint);
|
||||
|
||||
// Draw a small sphere at the anchor point
|
||||
Gizmos.DrawSphere(anchorPoint, 0.1f);
|
||||
|
||||
// Draw object bounds if enabled
|
||||
if (showObjectBounds && accountForObjectSize)
|
||||
{
|
||||
Bounds bounds = GetObjectBounds();
|
||||
if (bounds.size != Vector3.zero)
|
||||
{
|
||||
Color boundsColor = visualizationColor;
|
||||
boundsColor.a *= 0.3f;
|
||||
Gizmos.color = boundsColor;
|
||||
Gizmos.DrawWireCube(bounds.center, bounds.size);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore original color
|
||||
Gizmos.color = originalColor;
|
||||
}
|
||||
@@ -78,6 +117,10 @@ namespace AppleHillsCamera
|
||||
{
|
||||
_originalPosition = transform.position;
|
||||
FindCamera();
|
||||
if (_camera != null)
|
||||
{
|
||||
_lastOrthoSize = _camera.orthographicSize;
|
||||
}
|
||||
_lastScreenWidth = Screen.width;
|
||||
_lastScreenHeight = Screen.height;
|
||||
_initialized = true;
|
||||
@@ -94,6 +137,12 @@ namespace AppleHillsCamera
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
// Subscribe to camera adapter events
|
||||
if (Application.isPlaying && cameraAdapter != null)
|
||||
{
|
||||
cameraAdapter.OnCameraAdjusted += HandleCameraAdjusted;
|
||||
}
|
||||
|
||||
// Adjust position immediately when enabled in editor
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
@@ -103,18 +152,97 @@ namespace AppleHillsCamera
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
// Unsubscribe from camera adapter events
|
||||
if (cameraAdapter != null)
|
||||
{
|
||||
cameraAdapter.OnCameraAdjusted -= HandleCameraAdjusted;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCameraAdjusted()
|
||||
{
|
||||
// Update position when camera is adjusted
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if (debugMode)
|
||||
{
|
||||
Debug.Log($"Camera adjusted event received by {gameObject.name}, updating position");
|
||||
}
|
||||
|
||||
// Ensure we have the latest camera reference
|
||||
FindCamera();
|
||||
UpdatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// If no camera adapter was manually set, try to find one in the scene
|
||||
if (cameraAdapter == null && Application.isPlaying)
|
||||
{
|
||||
FindCameraAdapter();
|
||||
}
|
||||
|
||||
// Ensure we're subscribed to camera adapter events
|
||||
if (cameraAdapter != null && Application.isPlaying)
|
||||
{
|
||||
cameraAdapter.OnCameraAdjusted -= HandleCameraAdjusted; // Remove any duplicate subscriptions
|
||||
cameraAdapter.OnCameraAdjusted += HandleCameraAdjusted; // Subscribe
|
||||
}
|
||||
|
||||
if (adjustOnStart && Application.isPlaying)
|
||||
{
|
||||
UpdatePosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void FindCameraAdapter()
|
||||
{
|
||||
// Try to find the camera adapter in the scene
|
||||
var adapters = FindObjectsOfType<CameraScreenAdapter>();
|
||||
if (adapters != null && adapters.Length > 0)
|
||||
{
|
||||
// Prioritize any adapter that's on the same camera we're using
|
||||
foreach (var adapter in adapters)
|
||||
{
|
||||
if (_camera != null && adapter.GetControlledCamera() == _camera)
|
||||
{
|
||||
cameraAdapter = adapter;
|
||||
Debug.Log($"EdgeAnchor on {gameObject.name} auto-connected to CameraScreenAdapter on {cameraAdapter.gameObject.name}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If no matching camera found, use the first one
|
||||
cameraAdapter = adapters[0];
|
||||
Debug.Log($"EdgeAnchor on {gameObject.name} auto-connected to CameraScreenAdapter on {cameraAdapter.gameObject.name}");
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
bool shouldUpdate = false;
|
||||
|
||||
// Check if we have a valid camera
|
||||
if (_camera == null)
|
||||
{
|
||||
FindCamera();
|
||||
if (_camera != null) shouldUpdate = true;
|
||||
}
|
||||
|
||||
// Check if camera's ortho size has changed
|
||||
if (_camera != null && _camera.orthographicSize != _lastOrthoSize)
|
||||
{
|
||||
if (debugMode)
|
||||
{
|
||||
Debug.Log($"{gameObject.name}: Camera ortho size changed from {_lastOrthoSize} to {_camera.orthographicSize}");
|
||||
}
|
||||
_lastOrthoSize = _camera.orthographicSize;
|
||||
shouldUpdate = true;
|
||||
}
|
||||
|
||||
// Update if screen size has changed
|
||||
if (adjustOnScreenResize &&
|
||||
(Screen.width != _lastScreenWidth || Screen.height != _lastScreenHeight))
|
||||
@@ -141,6 +269,18 @@ namespace AppleHillsCamera
|
||||
|
||||
private void FindCamera()
|
||||
{
|
||||
Camera prevCamera = _camera;
|
||||
|
||||
// First check if we have a camera adapter reference
|
||||
if (cameraAdapter != null)
|
||||
{
|
||||
_camera = cameraAdapter.GetControlledCamera();
|
||||
if (_camera != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for the main camera
|
||||
_camera = Camera.main;
|
||||
|
||||
@@ -154,6 +294,43 @@ namespace AppleHillsCamera
|
||||
{
|
||||
Debug.LogError("EdgeAnchor: No camera found in the scene.");
|
||||
}
|
||||
else if (_camera != prevCamera && debugMode)
|
||||
{
|
||||
Debug.Log($"{gameObject.name}: Camera reference updated to {_camera.name}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the combined bounds of all renderers on this object and its children
|
||||
/// </summary>
|
||||
private Bounds GetObjectBounds()
|
||||
{
|
||||
Bounds bounds = new Bounds(transform.position, Vector3.zero);
|
||||
|
||||
// Get all renderers in this object and its children
|
||||
Renderer[] renderers = GetComponentsInChildren<Renderer>();
|
||||
|
||||
if (renderers.Length > 0)
|
||||
{
|
||||
// Start with the first renderer's bounds
|
||||
bounds = renderers[0].bounds;
|
||||
|
||||
// Expand to include all other renderers
|
||||
for (int i = 1; i < renderers.Length; i++)
|
||||
{
|
||||
bounds.Encapsulate(renderers[i].bounds);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No renderers found, create a small placeholder bounds
|
||||
bounds = new Bounds(transform.position, new Vector3(0.1f, 0.1f, 0.1f));
|
||||
}
|
||||
|
||||
// Cache the bounds
|
||||
_objectBounds = bounds;
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -176,7 +353,7 @@ namespace AppleHillsCamera
|
||||
// Get the margin value to use
|
||||
float margin = GetMarginValue();
|
||||
|
||||
// Calculate the new position based on anchor edge
|
||||
// Calculate the new position based on anchor edge and object size
|
||||
Vector3 newPosition = CalculateAnchoredPosition(margin);
|
||||
|
||||
// If preserving other axes, keep their original values
|
||||
@@ -198,7 +375,21 @@ namespace AppleHillsCamera
|
||||
}
|
||||
|
||||
// Apply the new position
|
||||
if (debugMode && Vector3.Distance(transform.position, newPosition) > 0.01f)
|
||||
{
|
||||
Debug.Log($"{gameObject.name} position updated: {transform.position} -> {newPosition}, Camera OrthoSize: {_camera.orthographicSize}");
|
||||
}
|
||||
|
||||
transform.position = newPosition;
|
||||
|
||||
// Notify listeners that the position has been updated
|
||||
OnPositionUpdated?.Invoke();
|
||||
|
||||
// Store the current ortho size for change detection
|
||||
if (_camera != null)
|
||||
{
|
||||
_lastOrthoSize = _camera.orthographicSize;
|
||||
}
|
||||
}
|
||||
|
||||
private float GetMarginValue()
|
||||
@@ -225,36 +416,73 @@ namespace AppleHillsCamera
|
||||
|
||||
private Vector3 CalculateAnchoredPosition(float margin)
|
||||
{
|
||||
// Get the screen edges in world coordinates
|
||||
if (_camera == null)
|
||||
return transform.position;
|
||||
|
||||
// Always get the CURRENT camera properties to ensure we have latest values
|
||||
float cameraOrthoSize = _camera.orthographicSize;
|
||||
float screenAspect = (float)Screen.width / Screen.height;
|
||||
float screenHeight = cameraOrthoSize * 2f;
|
||||
float screenWidth = screenHeight * screenAspect;
|
||||
|
||||
Vector3 cameraPosition = _camera.transform.position;
|
||||
|
||||
Vector3 newPosition = transform.position;
|
||||
|
||||
// Calculate object size offset if needed
|
||||
float offsetX = 0f;
|
||||
float offsetY = 0f;
|
||||
|
||||
if (accountForObjectSize)
|
||||
{
|
||||
Bounds bounds = GetObjectBounds();
|
||||
Vector3 extents = bounds.extents; // Half the size
|
||||
Vector3 centerOffset = bounds.center - transform.position; // Offset from pivot to center
|
||||
|
||||
switch (anchorEdge)
|
||||
{
|
||||
case AnchorEdge.Top:
|
||||
// For top edge, offset is negative (moving down) by the top extent
|
||||
offsetY = -extents.y - centerOffset.y;
|
||||
break;
|
||||
case AnchorEdge.Bottom:
|
||||
// For bottom edge, offset is positive (moving up) by the bottom extent
|
||||
offsetY = extents.y - centerOffset.y;
|
||||
break;
|
||||
case AnchorEdge.Left:
|
||||
// For left edge, offset is positive (moving right) by the left extent
|
||||
offsetX = extents.x - centerOffset.x;
|
||||
break;
|
||||
case AnchorEdge.Right:
|
||||
// For right edge, offset is negative (moving left) by the right extent
|
||||
offsetX = -extents.x - centerOffset.x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (anchorEdge)
|
||||
{
|
||||
case AnchorEdge.Top:
|
||||
// Position from the top of the screen
|
||||
newPosition.y = cameraPosition.y + cameraOrthoSize - margin;
|
||||
// When margin is 0, object's top edge is exactly at the top screen edge
|
||||
newPosition.y = cameraPosition.y + cameraOrthoSize - margin + offsetY;
|
||||
break;
|
||||
|
||||
case AnchorEdge.Bottom:
|
||||
// Position from the bottom of the screen
|
||||
newPosition.y = cameraPosition.y - cameraOrthoSize + margin;
|
||||
// When margin is 0, object's bottom edge is exactly at the bottom screen edge
|
||||
newPosition.y = cameraPosition.y - cameraOrthoSize + margin + offsetY;
|
||||
break;
|
||||
|
||||
case AnchorEdge.Left:
|
||||
// Position from the left of the screen
|
||||
newPosition.x = cameraPosition.x - (screenWidth / 2f) + margin;
|
||||
// When margin is 0, object's left edge is exactly at the left screen edge
|
||||
newPosition.x = cameraPosition.x - (screenWidth / 2f) + margin + offsetX;
|
||||
break;
|
||||
|
||||
case AnchorEdge.Right:
|
||||
// Position from the right of the screen
|
||||
newPosition.x = cameraPosition.x + (screenWidth / 2f) - margin;
|
||||
// When margin is 0, object's right edge is exactly at the right screen edge
|
||||
newPosition.x = cameraPosition.x + (screenWidth / 2f) - margin + offsetX;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -262,16 +490,13 @@ namespace AppleHillsCamera
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the anchor point on the edge for visualization
|
||||
/// Calculates the exact point on the screen edge for visualization purposes
|
||||
/// </summary>
|
||||
private Vector3 GetAnchorPoint()
|
||||
private Vector3 CalculateScreenEdgePoint()
|
||||
{
|
||||
if (_camera == null)
|
||||
{
|
||||
FindCamera();
|
||||
if (_camera == null) return transform.position;
|
||||
}
|
||||
|
||||
return transform.position;
|
||||
|
||||
// Get the screen edges in world coordinates
|
||||
float cameraOrthoSize = _camera.orthographicSize;
|
||||
float screenAspect = (float)Screen.width / Screen.height;
|
||||
@@ -279,32 +504,46 @@ namespace AppleHillsCamera
|
||||
float screenWidth = screenHeight * screenAspect;
|
||||
|
||||
Vector3 cameraPosition = _camera.transform.position;
|
||||
Vector3 anchorPoint = transform.position;
|
||||
Vector3 objectPosition = transform.position;
|
||||
|
||||
// Calculate the point exactly on the screen edge that corresponds to the object's anchor
|
||||
switch (anchorEdge)
|
||||
{
|
||||
case AnchorEdge.Top:
|
||||
// Anchor at top edge with same X as the object
|
||||
anchorPoint.y = cameraPosition.y + cameraOrthoSize;
|
||||
break;
|
||||
// Point on top edge with same X coordinate as the object
|
||||
return new Vector3(
|
||||
objectPosition.x,
|
||||
cameraPosition.y + cameraOrthoSize,
|
||||
objectPosition.z
|
||||
);
|
||||
|
||||
case AnchorEdge.Bottom:
|
||||
// Anchor at bottom edge with same X as the object
|
||||
anchorPoint.y = cameraPosition.y - cameraOrthoSize;
|
||||
break;
|
||||
// Point on bottom edge with same X coordinate as the object
|
||||
return new Vector3(
|
||||
objectPosition.x,
|
||||
cameraPosition.y - cameraOrthoSize,
|
||||
objectPosition.z
|
||||
);
|
||||
|
||||
case AnchorEdge.Left:
|
||||
// Anchor at left edge with same Y as the object
|
||||
anchorPoint.x = cameraPosition.x - (screenWidth / 2f);
|
||||
break;
|
||||
// Point on left edge with same Y coordinate as the object
|
||||
return new Vector3(
|
||||
cameraPosition.x - (screenWidth / 2f),
|
||||
objectPosition.y,
|
||||
objectPosition.z
|
||||
);
|
||||
|
||||
case AnchorEdge.Right:
|
||||
// Anchor at right edge with same Y as the object
|
||||
anchorPoint.x = cameraPosition.x + (screenWidth / 2f);
|
||||
break;
|
||||
// Point on right edge with same Y coordinate as the object
|
||||
return new Vector3(
|
||||
cameraPosition.x + (screenWidth / 2f),
|
||||
objectPosition.y,
|
||||
objectPosition.z
|
||||
);
|
||||
|
||||
default:
|
||||
return objectPosition;
|
||||
}
|
||||
|
||||
return anchorPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using UnityEngine;
|
||||
using AppleHills.Core.Settings;
|
||||
using Input;
|
||||
using AppleHillsCamera;
|
||||
|
||||
namespace Minigames.DivingForPictures
|
||||
{
|
||||
@@ -10,6 +11,10 @@ namespace Minigames.DivingForPictures
|
||||
/// </summary>
|
||||
public class PlayerController : MonoBehaviour, ITouchInputConsumer
|
||||
{
|
||||
|
||||
[Tooltip("Reference to the edge anchor that this player should follow for Y position")]
|
||||
[SerializeField] private EdgeAnchor edgeAnchor;
|
||||
|
||||
// Settings reference
|
||||
private IDivingMinigameSettings _settings;
|
||||
|
||||
@@ -42,6 +47,38 @@ namespace Minigames.DivingForPictures
|
||||
_targetFingerX = transform.position.x;
|
||||
_isTouchActive = false;
|
||||
|
||||
// Try to find edge anchor if not assigned
|
||||
if (edgeAnchor == null)
|
||||
{
|
||||
// First try to find edge anchor on the same object or parent
|
||||
edgeAnchor = GetComponentInParent<EdgeAnchor>();
|
||||
|
||||
// If not found, find any edge anchor in the scene
|
||||
if (edgeAnchor == null)
|
||||
{
|
||||
edgeAnchor = FindObjectOfType<EdgeAnchor>();
|
||||
if (edgeAnchor == null)
|
||||
{
|
||||
Debug.LogWarning("[PlayerController] No EdgeAnchor found in scene. Origin Y position won't update with camera changes.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[PlayerController] Auto-connected to EdgeAnchor on {edgeAnchor.gameObject.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to edge anchor events if it exists
|
||||
if (edgeAnchor != null)
|
||||
{
|
||||
// Unsubscribe first to prevent duplicate subscriptions
|
||||
edgeAnchor.OnPositionUpdated -= UpdateOriginYFromAnchor;
|
||||
edgeAnchor.OnPositionUpdated += UpdateOriginYFromAnchor;
|
||||
|
||||
// Update origin Y based on current anchor position
|
||||
UpdateOriginYFromAnchor();
|
||||
}
|
||||
|
||||
DivingGameManager.Instance.OnGameInitialized += Initialize;
|
||||
|
||||
// If game is already initialized, initialize immediately
|
||||
@@ -70,6 +107,12 @@ namespace Minigames.DivingForPictures
|
||||
private void OnDestroy()
|
||||
{
|
||||
DivingGameManager.Instance.OnGameInitialized -= Initialize;
|
||||
|
||||
// Unsubscribe from edge anchor events
|
||||
if (edgeAnchor != null)
|
||||
{
|
||||
edgeAnchor.OnPositionUpdated -= UpdateOriginYFromAnchor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,5 +228,31 @@ namespace Minigames.DivingForPictures
|
||||
}
|
||||
transform.position = new Vector3(newX, newY, transform.position.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the origin Y position based on camera adjustments
|
||||
/// </summary>
|
||||
public void UpdateOriginY(float newOriginY)
|
||||
{
|
||||
_originY = newOriginY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the origin Y position based on the current position of the player
|
||||
/// This method is intended to be called by the camera adapter when the camera is adjusted.
|
||||
/// </summary>
|
||||
private void UpdateOriginYFromCurrentPosition()
|
||||
{
|
||||
_originY = transform.position.y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the origin Y position based on the current position of the edge anchor
|
||||
/// This method is intended to be called by the edge anchor when its position is updated.
|
||||
/// </summary>
|
||||
private void UpdateOriginYFromAnchor()
|
||||
{
|
||||
_originY = edgeAnchor.transform.position.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,43 @@ public class RockFollower : MonoBehaviour
|
||||
/// </summary>
|
||||
public bool useWobbleOffset = true;
|
||||
/// <summary>
|
||||
/// The base Y position for the rock.
|
||||
/// The vertical distance between the rock and the bottle.
|
||||
/// </summary>
|
||||
public float baseY = -6f;
|
||||
[SerializeField] private float verticalDistance = 6f;
|
||||
|
||||
private float velocityX; // For SmoothDamp
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Called in editor when properties are changed.
|
||||
/// Updates the object's position when verticalDistance is modified.
|
||||
/// </summary>
|
||||
private void OnValidate()
|
||||
{
|
||||
// Only update position if playing or in prefab mode
|
||||
if (Application.isPlaying || UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this))
|
||||
return;
|
||||
|
||||
if (bottleTransform != null)
|
||||
{
|
||||
// Calculate the new Y position based on bottle's position and the updated verticalDistance
|
||||
float newY = bottleTransform.position.y - verticalDistance;
|
||||
|
||||
// Apply the wobble offset if enabled
|
||||
if (useWobbleOffset && bottleWobble != null)
|
||||
{
|
||||
newY += bottleWobble.VerticalOffset;
|
||||
}
|
||||
|
||||
// Update only the Y position, keeping X and Z unchanged
|
||||
transform.position = new Vector3(transform.position.x, newY, transform.position.z);
|
||||
|
||||
// Mark the scene as dirty to ensure changes are saved
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (bottleTransform == null) return;
|
||||
@@ -33,8 +64,8 @@ public class RockFollower : MonoBehaviour
|
||||
// Smoothly follow bottle's X with stiffer motion
|
||||
float newX = Mathf.SmoothDamp(currentX, targetX, ref velocityX, 1f / followStiffness);
|
||||
|
||||
// Calculate Y position
|
||||
float newY = baseY;
|
||||
// Calculate Y position based on bottle's position and vertical distance
|
||||
float newY = bottleTransform.position.y - verticalDistance;
|
||||
if (useWobbleOffset && bottleWobble != null)
|
||||
{
|
||||
newY += bottleWobble.VerticalOffset;
|
||||
|
||||
Reference in New Issue
Block a user