[Player][Interactions] Pulver moves to item and goes back. Item disappears, but in wrong order
This commit is contained in:
8
Assets/Data/Settings.meta
Normal file
8
Assets/Data/Settings.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcd99d46037b3e44abe09d64d0fa2e47
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/Data/Settings/DefaultSettings.asset
Normal file
16
Assets/Data/Settings/DefaultSettings.asset
Normal file
@@ -0,0 +1,16 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e4ec438b455a4044957501c2c66a6f4b, type: 3}
|
||||
m_Name: DefaultSettings
|
||||
m_EditorClassIdentifier:
|
||||
playerStopDistance: 10
|
||||
followerPickupDelay: 0.2
|
||||
8
Assets/Data/Settings/DefaultSettings.asset.meta
Normal file
8
Assets/Data/Settings/DefaultSettings.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 924922151a72ae8439be5090a3feaef9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,7 +13,7 @@ GameObject:
|
||||
- component: {fileID: 3435632802124758411}
|
||||
m_Layer: 8
|
||||
m_Name: PulverCharacter
|
||||
m_TagString: Untagged
|
||||
m_TagString: Pulver
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
|
||||
@@ -13,7 +13,7 @@ GameObject:
|
||||
- component: {fileID: 3070149615425714466}
|
||||
- component: {fileID: 7616859841301711022}
|
||||
- component: {fileID: 592045584872845087}
|
||||
m_Layer: 6
|
||||
m_Layer: 0
|
||||
m_Name: BasePickup
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
|
||||
@@ -13,7 +13,7 @@ GameObject:
|
||||
- component: {fileID: 841695541655102207}
|
||||
- component: {fileID: 4981092805118965486}
|
||||
- component: {fileID: 1397300447834037203}
|
||||
m_Layer: 6
|
||||
m_Layer: 0
|
||||
m_Name: BaseLevelSwitch
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
|
||||
@@ -488,6 +488,81 @@ PrefabInstance:
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3}
|
||||
--- !u!1 &416453392 stripped
|
||||
GameObject:
|
||||
m_CorrespondingSourceObject: {fileID: 1102400833121127473, guid: 8ac0210dbf9d7754e9526d6d5c214f49, type: 3}
|
||||
m_PrefabInstance: {fileID: 1950557796102186365}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!114 &416453396
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 416453392}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f6eb1402c17e84a9282a7f0f62eb584f, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 5
|
||||
radius: 2
|
||||
height: 2
|
||||
canMove: 1
|
||||
maxSpeed: 15
|
||||
gravity: {x: NaN, y: NaN, z: NaN}
|
||||
groundMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
centerOffsetCompatibility: NaN
|
||||
repathRateCompatibility: NaN
|
||||
canSearchCompability: 0
|
||||
orientation: 1
|
||||
enableRotation: 0
|
||||
autoRepath:
|
||||
mode: 2
|
||||
interval: 0.5
|
||||
sensitivity: 10
|
||||
maximumInterval: 2
|
||||
visualizeSensitivity: 0
|
||||
targetCompatibility: {fileID: 0}
|
||||
maxAcceleration: -2.5
|
||||
rotationSpeed: 360
|
||||
slowdownDistance: 3
|
||||
pickNextWaypointDist: 2
|
||||
endReachedDistance: 0.5
|
||||
alwaysDrawGizmos: 0
|
||||
slowWhenNotFacingTarget: 1
|
||||
whenCloseToDestination: 0
|
||||
constrainInsideGraph: 0
|
||||
--- !u!114 &416453397
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 416453392}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 373b52eb9bf8c40f785bb6947a1aee66, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
version: 1
|
||||
drawGizmos: 1
|
||||
detailedGizmos: 0
|
||||
startEndModifier:
|
||||
addPoints: 0
|
||||
exactStartPoint: 3
|
||||
exactEndPoint: 3
|
||||
useRaycasting: 0
|
||||
mask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
useGraphRaycasting: 0
|
||||
traversableTags: -1
|
||||
tagPenalties: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
graphMask:
|
||||
value: -1
|
||||
--- !u!1001 &448642088
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -633,6 +708,7 @@ Transform:
|
||||
- {fileID: 954512636}
|
||||
- {fileID: 535638824}
|
||||
- {fileID: 189988800}
|
||||
- {fileID: 2027860879}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!4 &754397347 stripped
|
||||
@@ -22942,6 +23018,51 @@ Tilemap:
|
||||
e31: 0
|
||||
e32: 0
|
||||
e33: 1
|
||||
--- !u!1 &2027860878
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2027860879}
|
||||
- component: {fileID: 2027860880}
|
||||
m_Layer: 0
|
||||
m_Name: GameManager
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &2027860879
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2027860878}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 638340961}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2027860880
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2027860878}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: b9333cd9ca0e44769ef1913d10231047, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
gameSettings: {fileID: 11400000, guid: 924922151a72ae8439be5090a3feaef9, type: 2}
|
||||
--- !u!4 &2102167558 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 2844046668579196942, guid: b5fc01af35233eb4cbeede05e50a7c34, type: 3}
|
||||
@@ -23002,7 +23123,13 @@ PrefabInstance:
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
m_AddedComponents: []
|
||||
m_AddedComponents:
|
||||
- targetCorrespondingSourceObject: {fileID: 1102400833121127473, guid: 8ac0210dbf9d7754e9526d6d5c214f49, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 416453397}
|
||||
- targetCorrespondingSourceObject: {fileID: 1102400833121127473, guid: 8ac0210dbf9d7754e9526d6d5c214f49, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 416453396}
|
||||
m_SourcePrefab: {fileID: 100100000, guid: 8ac0210dbf9d7754e9526d6d5c214f49, type: 3}
|
||||
--- !u!1001 &8865498003578620591
|
||||
PrefabInstance:
|
||||
|
||||
@@ -27,6 +27,9 @@ public class FollowerController : MonoBehaviour
|
||||
public float thresholdNear = 0.5f;
|
||||
public float stopThreshold = 0.1f; // Stop moving when within this distance
|
||||
private float playerMaxSpeed = 5f;
|
||||
private const float followerSpeedMultiplier = 1.2f;
|
||||
private float followerMaxSpeed = 6f; // Default, will be set from player
|
||||
private float defaultFollowerMaxSpeed = 6f; // Default fallback value
|
||||
|
||||
private Animator animator;
|
||||
private Transform artTransform;
|
||||
@@ -72,6 +75,8 @@ public class FollowerController : MonoBehaviour
|
||||
if (playerAIPath != null)
|
||||
{
|
||||
playerMaxSpeed = playerAIPath.maxSpeed;
|
||||
defaultFollowerMaxSpeed = playerMaxSpeed;
|
||||
followerMaxSpeed = playerMaxSpeed * followerSpeedMultiplier;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -95,27 +100,29 @@ public class FollowerController : MonoBehaviour
|
||||
if (playerTransform == null)
|
||||
return; // Still missing, skip update
|
||||
}
|
||||
// Determine direction: use player's velocity if available, else lastMoveDir
|
||||
Vector3 playerPos = playerTransform.position;
|
||||
Vector3 moveDir = Vector3.zero;
|
||||
if (playerAIPath != null && playerAIPath.velocity.magnitude > 0.01f)
|
||||
if (isManualFollowing)
|
||||
{
|
||||
moveDir = playerAIPath.velocity.normalized;
|
||||
lastMoveDir = moveDir; // Update last valid direction
|
||||
}
|
||||
else
|
||||
{
|
||||
moveDir = lastMoveDir; // Use last direction if stationary
|
||||
}
|
||||
// Calculate target point behind player
|
||||
targetPoint = playerPos - moveDir * followDistance;
|
||||
targetPoint.z = 0; // For 2D
|
||||
// Determine direction: use player's velocity if available, else lastMoveDir
|
||||
Vector3 playerPos = playerTransform.position;
|
||||
Vector3 moveDir = Vector3.zero;
|
||||
if (playerAIPath != null && playerAIPath.velocity.magnitude > 0.01f)
|
||||
{
|
||||
moveDir = playerAIPath.velocity.normalized;
|
||||
lastMoveDir = moveDir; // Update last valid direction
|
||||
}
|
||||
else
|
||||
{
|
||||
moveDir = lastMoveDir; // Use last direction if stationary
|
||||
}
|
||||
// Calculate target point behind player
|
||||
targetPoint = playerPos - moveDir * followDistance;
|
||||
targetPoint.z = 0; // For 2D
|
||||
|
||||
// Always use manual following unless GoToPoint is called
|
||||
isManualFollowing = true;
|
||||
if (aiPath != null)
|
||||
{
|
||||
aiPath.enabled = false;
|
||||
// Only disable aiPath if in manual mode
|
||||
if (aiPath != null)
|
||||
{
|
||||
aiPath.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,14 +146,17 @@ public class FollowerController : MonoBehaviour
|
||||
// Manual movement logic with acceleration/deceleration and stop threshold
|
||||
if (isManualFollowing)
|
||||
{
|
||||
float dist = Vector3.Distance(transform.position, targetPoint);
|
||||
// 2D distance calculation (ignore z)
|
||||
Vector2 current2D = new Vector2(transform.position.x, transform.position.y);
|
||||
Vector2 target2D = new Vector2(targetPoint.x, targetPoint.y);
|
||||
float dist = Vector2.Distance(current2D, target2D);
|
||||
if (dist > stopThreshold)
|
||||
{
|
||||
float desiredSpeed = playerMaxSpeed;
|
||||
float desiredSpeed = followerMaxSpeed;
|
||||
if (dist > thresholdFar)
|
||||
{
|
||||
// Accelerate to player's max speed
|
||||
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, playerMaxSpeed);
|
||||
// Accelerate to follower's max speed
|
||||
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, followerMaxSpeed);
|
||||
}
|
||||
else if (dist <= thresholdNear && dist > stopThreshold)
|
||||
{
|
||||
@@ -155,8 +165,8 @@ public class FollowerController : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
// Maintain player's max speed
|
||||
desiredSpeed = playerMaxSpeed;
|
||||
// Maintain follower's max speed
|
||||
desiredSpeed = followerMaxSpeed;
|
||||
}
|
||||
currentSpeed = desiredSpeed;
|
||||
Vector3 dir = (targetPoint - transform.position).normalized;
|
||||
@@ -176,12 +186,12 @@ public class FollowerController : MonoBehaviour
|
||||
if (isManualFollowing)
|
||||
{
|
||||
// Use currentSpeed for manual following
|
||||
normalizedSpeed = currentSpeed / playerMaxSpeed;
|
||||
normalizedSpeed = currentSpeed / followerMaxSpeed;
|
||||
}
|
||||
else if (aiPath != null)
|
||||
{
|
||||
// Use aiPath velocity for pathfinding mode
|
||||
normalizedSpeed = aiPath.velocity.magnitude / playerMaxSpeed;
|
||||
normalizedSpeed = aiPath.velocity.magnitude / followerMaxSpeed;
|
||||
}
|
||||
animator.SetFloat("Speed", Mathf.Clamp01(normalizedSpeed));
|
||||
}
|
||||
@@ -194,10 +204,64 @@ public class FollowerController : MonoBehaviour
|
||||
if (aiPath != null)
|
||||
{
|
||||
aiPath.enabled = true;
|
||||
aiPath.maxSpeed = followerMaxSpeed;
|
||||
aiPath.destination = new Vector3(worldPosition.x, worldPosition.y, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void FollowerPickupHandler();
|
||||
public event FollowerPickupHandler OnPickupArrived;
|
||||
public event FollowerPickupHandler OnPickupReturned;
|
||||
private Coroutine pickupCoroutine;
|
||||
|
||||
// Command follower to go to a specific point and return to player
|
||||
public void GoToPointAndReturn(Vector2 itemPosition, Transform playerTransform)
|
||||
{
|
||||
if (pickupCoroutine != null)
|
||||
StopCoroutine(pickupCoroutine);
|
||||
if (aiPath != null)
|
||||
aiPath.maxSpeed = followerMaxSpeed;
|
||||
pickupCoroutine = StartCoroutine(PickupSequence(itemPosition, playerTransform));
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator PickupSequence(Vector2 itemPosition, Transform playerTransform)
|
||||
{
|
||||
isManualFollowing = false;
|
||||
if (aiPath != null)
|
||||
{
|
||||
aiPath.enabled = true;
|
||||
aiPath.maxSpeed = followerMaxSpeed;
|
||||
aiPath.destination = new Vector3(itemPosition.x, itemPosition.y, 0);
|
||||
}
|
||||
// Wait until follower reaches item (2D distance)
|
||||
while (Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(itemPosition.x, itemPosition.y)) > stopThreshold)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
OnPickupArrived?.Invoke();
|
||||
// Wait briefly, then return to player
|
||||
yield return new WaitForSeconds(0.2f);
|
||||
if (aiPath != null && playerTransform != null)
|
||||
{
|
||||
aiPath.maxSpeed = followerMaxSpeed;
|
||||
aiPath.destination = playerTransform.position;
|
||||
}
|
||||
// Wait until follower returns to player (2D distance)
|
||||
while (playerTransform != null && Vector2.Distance(new Vector2(transform.position.x, transform.position.y), new Vector2(playerTransform.position.x, playerTransform.position.y)) > stopThreshold)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
OnPickupReturned?.Invoke();
|
||||
// Reset follower speed to normal after pickup
|
||||
followerMaxSpeed = defaultFollowerMaxSpeed;
|
||||
if (aiPath != null)
|
||||
aiPath.maxSpeed = followerMaxSpeed;
|
||||
isManualFollowing = true;
|
||||
if (aiPath != null)
|
||||
aiPath.enabled = false;
|
||||
pickupCoroutine = null;
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
if (debugDrawTarget && Application.isPlaying)
|
||||
|
||||
36
Assets/Scripts/GameManager.cs
Normal file
36
Assets/Scripts/GameManager.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class GameManager : MonoBehaviour
|
||||
{
|
||||
private static GameManager _instance;
|
||||
public static GameManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = FindAnyObjectByType<GameManager>();
|
||||
if (_instance == null)
|
||||
{
|
||||
var go = new GameObject("GameManager");
|
||||
_instance = go.AddComponent<GameManager>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Game Settings")]
|
||||
public GameSettings gameSettings;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
public float PlayerStopDistance => gameSettings != null ? gameSettings.playerStopDistance : 1.0f;
|
||||
public float FollowerPickupDelay => gameSettings != null ? gameSettings.followerPickupDelay : 0.2f;
|
||||
// Add more accessors as needed
|
||||
}
|
||||
3
Assets/Scripts/GameManager.cs.meta
Normal file
3
Assets/Scripts/GameManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9333cd9ca0e44769ef1913d10231047
|
||||
timeCreated: 1756933142
|
||||
11
Assets/Scripts/GameSettings.cs
Normal file
11
Assets/Scripts/GameSettings.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName = "GameSettings", menuName = "AppleHills/GameSettings", order = 1)]
|
||||
public class GameSettings : ScriptableObject
|
||||
{
|
||||
[Header("Interactions")]
|
||||
public float playerStopDistance = 6.0f;
|
||||
public float followerPickupDelay = 0.2f;
|
||||
// Add other settings here as needed
|
||||
}
|
||||
|
||||
3
Assets/Scripts/GameSettings.cs.meta
Normal file
3
Assets/Scripts/GameSettings.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4ec438b455a4044957501c2c66a6f4b
|
||||
timeCreated: 1756933137
|
||||
@@ -7,8 +7,12 @@ public class LevelSwitch : MonoBehaviour
|
||||
public SpriteRenderer iconRenderer;
|
||||
private Interactable interactable;
|
||||
|
||||
private bool _isActive = true;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_isActive = true;
|
||||
|
||||
if (iconRenderer == null)
|
||||
iconRenderer = GetComponent<SpriteRenderer>();
|
||||
|
||||
@@ -51,11 +55,12 @@ public class LevelSwitch : MonoBehaviour
|
||||
private async void OnInteracted()
|
||||
{
|
||||
Debug.Log($"LevelSwitch.OnInteracted: Switching to level {switchData?.targetLevelSceneName}");
|
||||
if (switchData != null && !string.IsNullOrEmpty(switchData.targetLevelSceneName))
|
||||
if (switchData != null && !string.IsNullOrEmpty(switchData.targetLevelSceneName) && _isActive)
|
||||
{
|
||||
// Optionally: show loading UI here
|
||||
var progress = new Progress<float>(p => Debug.Log($"Loading progress: {p * 100:F0}%"));
|
||||
await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress);
|
||||
_isActive = false;
|
||||
// Optionally: hide loading UI here
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ public class Pickup : MonoBehaviour
|
||||
public SpriteRenderer iconRenderer;
|
||||
private Interactable interactable;
|
||||
|
||||
private bool pickupInProgress = false;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (iconRenderer == null)
|
||||
@@ -33,6 +35,23 @@ public class Pickup : MonoBehaviour
|
||||
iconRenderer = GetComponent<SpriteRenderer>();
|
||||
ApplyItemData();
|
||||
}
|
||||
|
||||
void OnDrawGizmos()
|
||||
{
|
||||
// Get stop distance from GameManager or default
|
||||
float playerStopDistance = GameManager.Instance != null ? GameManager.Instance.PlayerStopDistance : 1.0f;
|
||||
// Draw stop distance circle around pickup
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(transform.position, playerStopDistance);
|
||||
// Draw stop point (where player is told to move)
|
||||
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||
if (playerObj != null)
|
||||
{
|
||||
Vector3 stopPoint = transform.position + (playerObj.transform.position - transform.position).normalized * playerStopDistance;
|
||||
Gizmos.color = Color.cyan;
|
||||
Gizmos.DrawSphere(stopPoint, 0.15f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public void ApplyItemData()
|
||||
@@ -48,8 +67,56 @@ public class Pickup : MonoBehaviour
|
||||
|
||||
private void OnInteracted()
|
||||
{
|
||||
Debug.Log($"[Pickup] OnInteracted: Picked up {itemData?.itemName}");
|
||||
// TODO: Add item to inventory manager here
|
||||
Destroy(gameObject);
|
||||
if (pickupInProgress) return;
|
||||
pickupInProgress = true;
|
||||
// Find player and follower controllers
|
||||
var playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||
var followerObj = GameObject.FindGameObjectWithTag("Pulver");
|
||||
if (playerObj == null || followerObj == null)
|
||||
{
|
||||
Debug.LogWarning("Pickup: Player or Follower not found.");
|
||||
pickupInProgress = false;
|
||||
return;
|
||||
}
|
||||
var playerController = playerObj.GetComponent<PlayerTouchController>();
|
||||
var followerController = followerObj.GetComponent<FollowerController>();
|
||||
if (playerController == null || followerController == null)
|
||||
{
|
||||
Debug.LogWarning("Pickup: PlayerTouchController or FollowerController missing.");
|
||||
pickupInProgress = false;
|
||||
return;
|
||||
}
|
||||
// Get settings from GameManager
|
||||
float playerStopDistance = GameManager.Instance != null ? GameManager.Instance.PlayerStopDistance : 1.0f;
|
||||
float followerPickupDelay = GameManager.Instance != null ? GameManager.Instance.FollowerPickupDelay : 0.2f;
|
||||
// Subscribe to player arrival event
|
||||
void OnPlayerArrived()
|
||||
{
|
||||
playerController.OnArrivedAtTarget -= OnPlayerArrived;
|
||||
// After player arrives, dispatch follower after delay
|
||||
StartCoroutine(DispatchFollower());
|
||||
}
|
||||
System.Collections.IEnumerator DispatchFollower()
|
||||
{
|
||||
yield return new WaitForSeconds(followerPickupDelay);
|
||||
// Subscribe to follower events
|
||||
followerController.OnPickupArrived += OnFollowerArrived;
|
||||
followerController.OnPickupReturned += OnFollowerReturned;
|
||||
followerController.GoToPointAndReturn(transform.position, playerObj.transform);
|
||||
}
|
||||
void OnFollowerArrived()
|
||||
{
|
||||
followerController.OnPickupArrived -= OnFollowerArrived;
|
||||
// Optionally: play pickup animation, etc.
|
||||
}
|
||||
void OnFollowerReturned()
|
||||
{
|
||||
followerController.OnPickupReturned -= OnFollowerReturned;
|
||||
pickupInProgress = false;
|
||||
Destroy(gameObject);
|
||||
}
|
||||
playerController.OnArrivedAtTarget += OnPlayerArrived;
|
||||
Vector3 stopPoint = transform.position + (playerObj.transform.position - transform.position).normalized * playerStopDistance;
|
||||
playerController.MoveToAndNotify(stopPoint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,11 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
||||
private Animator animator;
|
||||
private Transform artTransform;
|
||||
|
||||
public delegate void ArrivedAtTargetHandler();
|
||||
public event ArrivedAtTargetHandler OnArrivedAtTarget;
|
||||
private Coroutine moveToCoroutine;
|
||||
private bool interruptMoveTo = false;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
rb3d = GetComponent<Rigidbody>();
|
||||
@@ -56,6 +61,8 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
||||
|
||||
public void OnTouchPress(Vector2 worldPosition)
|
||||
{
|
||||
// If moving to pickup, interrupt
|
||||
InterruptMoveTo();
|
||||
Debug.Log($"PlayerTouchController.OnTouchPress received worldPosition: {worldPosition}");
|
||||
SetTargetPosition(worldPosition);
|
||||
}
|
||||
@@ -93,4 +100,48 @@ public class PlayerTouchController : MonoBehaviour, ITouchInputConsumer
|
||||
}
|
||||
|
||||
// Remove FixedUpdate and MoveTowardsTarget, as AIPath handles movement
|
||||
|
||||
// Move to a target position, notify when arrived
|
||||
public void MoveToAndNotify(Vector3 target)
|
||||
{
|
||||
if (moveToCoroutine != null)
|
||||
{
|
||||
StopCoroutine(moveToCoroutine);
|
||||
}
|
||||
interruptMoveTo = false;
|
||||
moveToCoroutine = StartCoroutine(MoveToTargetCoroutine(target));
|
||||
}
|
||||
|
||||
public void InterruptMoveTo()
|
||||
{
|
||||
interruptMoveTo = true;
|
||||
}
|
||||
|
||||
private System.Collections.IEnumerator MoveToTargetCoroutine(Vector3 target)
|
||||
{
|
||||
hasTarget = true;
|
||||
targetPosition = target;
|
||||
if (aiPath != null)
|
||||
{
|
||||
aiPath.destination = target;
|
||||
}
|
||||
while (!interruptMoveTo)
|
||||
{
|
||||
// 2D distance calculation (ignore z)
|
||||
Vector2 current2D = new Vector2(transform.position.x, transform.position.y);
|
||||
Vector2 target2D = new Vector2(target.x, target.y);
|
||||
float dist = Vector2.Distance(current2D, target2D);
|
||||
if (dist <= stopDistance + 0.2f)
|
||||
{
|
||||
break;
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
hasTarget = false;
|
||||
moveToCoroutine = null;
|
||||
if (!interruptMoveTo)
|
||||
{
|
||||
OnArrivedAtTarget?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,24 @@ using UnityEngine.SceneManagement;
|
||||
|
||||
public class SceneManagerService : MonoBehaviour
|
||||
{
|
||||
public static SceneManagerService Instance { get; private set; }
|
||||
private static SceneManagerService _instance;
|
||||
public static SceneManagerService Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = FindAnyObjectByType<SceneManagerService>();
|
||||
if (_instance == null)
|
||||
{
|
||||
var go = new GameObject("SceneManagerService");
|
||||
_instance = go.AddComponent<SceneManagerService>();
|
||||
DontDestroyOnLoad(go);
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
// Events for scene lifecycle
|
||||
public event Action<string> SceneLoadStarted;
|
||||
@@ -21,12 +38,7 @@ public class SceneManagerService : MonoBehaviour
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
_instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,4 +53,4 @@ Physics2DSettings:
|
||||
m_ReuseCollisionCallbacks: 1
|
||||
m_AutoSyncTransforms: 0
|
||||
m_GizmoOptions: 10
|
||||
m_LayerCollisionMatrix: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff7fffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
m_LayerCollisionMatrix: fffffffffffffffffffffffffffffffffffffffffffffffffffefffffffcffff3fffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
|
||||
@@ -5,6 +5,7 @@ TagManager:
|
||||
serializedVersion: 3
|
||||
tags:
|
||||
- CharacterArt
|
||||
- Pulver
|
||||
layers:
|
||||
- Default
|
||||
- TransparentFX
|
||||
|
||||
Reference in New Issue
Block a user