using UnityEngine; using System; using System.Collections; using Pathfinding; public class AnneLiseBehaviour : MonoBehaviour { [SerializeField] public float moveSpeed; private Animator animator; private AIPath aiPath; private bool hasArrived = false; private LureSpot currentLureSpot; private SpriteRenderer spriteRenderer; // Cached reference private bool allowFacingByVelocity = true; // New flag private Coroutine walkingCoroutine; private bool annaLiseIsReady = false; // Flag to know if Anna Lise is ready to take the picture private void Awake() { animator = GetComponentInChildren(); aiPath = GetComponent(); spriteRenderer = GetComponentInChildren(); // Cache the reference if (aiPath != null) { aiPath.maxSpeed = moveSpeed; aiPath.OnTargetReachedEvent += HandleArriveAtSpot; } } private void OnDestroy() { if (aiPath != null) { aiPath.OnTargetReachedEvent -= HandleArriveAtSpot; } } public void TeleportJustOutOfView(Camera cam, float offset = 2f) { if (aiPath == null || cam == null || currentLureSpot == null || currentLureSpot.annaLiseSpot == null) return; // Calculate direction from the target spot to Anna Lise's current position Vector3 from = currentLureSpot.annaLiseSpot.transform.position; Vector3 to = transform.position; Vector3 direction = (to - from).normalized; // Project the target spot to screen space Vector3 targetScreen = cam.WorldToScreenPoint(from); // Find the screen edge in the direction Vector2 dir2D = new Vector2(direction.x, direction.y); if (dir2D == Vector2.zero) dir2D = Vector2.right; // fallback dir2D.Normalize(); // Calculate intersection with screen bounds float tX = dir2D.x > 0 ? (Screen.width - targetScreen.x) / dir2D.x : (0 - targetScreen.x) / dir2D.x; float tY = dir2D.y > 0 ? (Screen.height - targetScreen.y) / dir2D.y : (0 - targetScreen.y) / dir2D.y; float t = Mathf.Min(Mathf.Abs(tX), Mathf.Abs(tY)); Vector2 edgeScreen = new Vector2(targetScreen.x, targetScreen.y) + dir2D * t; edgeScreen += dir2D * offset; // Move outside the screen by offset // Convert back to world position Vector3 teleportWorld = cam.ScreenToWorldPoint(new Vector3(edgeScreen.x, edgeScreen.y, cam.WorldToScreenPoint(from).z)); teleportWorld.z = transform.position.z; // Keep original Z aiPath.Teleport(teleportWorld, true); } public void GotoSpot(GameObject lurespot) { currentLureSpot = lurespot.GetComponent(); // Teleport Anna Lise just out of view before moving TeleportJustOutOfView(Camera.main, 2f); if (aiPath == null) return; aiPath.destination = currentLureSpot.annaLiseSpot.transform.position; aiPath.canMove = true; aiPath.SearchPath(); hasArrived = false; allowFacingByVelocity = true; if (walkingCoroutine != null) { StopCoroutine(walkingCoroutine); } walkingCoroutine = StartCoroutine(UpdateSpeedWhenWalking()); } private IEnumerator UpdateSpeedWhenWalking() { while (!hasArrived && aiPath != null && animator != null) { float currentSpeed = aiPath.velocity.magnitude; animator.SetFloat("speed", currentSpeed); // Only allow facing by velocity if not arrived if (allowFacingByVelocity && currentSpeed > 0.01f && spriteRenderer != null) { Vector3 velocity = aiPath.velocity; if (velocity.x != 0) { Vector3 scale = spriteRenderer.transform.localScale; scale.x = Mathf.Abs(scale.x) * (velocity.x > 0 ? 1 : -1); spriteRenderer.transform.localScale = scale; } } yield return null; } } private void HandleArriveAtSpot() { if (hasArrived) return; hasArrived = true; allowFacingByVelocity = false; // Disable facing by velocity after arrival aiPath.canMove = false; if (walkingCoroutine != null) { StopCoroutine(walkingCoroutine); walkingCoroutine = null; } // Face the "luredBird" of the current lurespot, if available if (currentLureSpot != null) { if (currentLureSpot.luredBird != null) { FaceTarget(currentLureSpot.luredBird); annaLiseIsReady = true; // Now Anna Lise is ready to take the picture } } if (animator != null && currentLureSpot.name != "LureSpotB")// Horrible way to not take the photo if its Wolter { animator.SetTrigger("TakePhoto"); annaLiseIsReady = false; // Reset the flag after taking the photo } animator.SetFloat("speed", 0); } public void FaceTarget(GameObject target) { if (target == null || spriteRenderer == null) return; // Compare X positions to determine facing direction float direction = target.transform.position.x - transform.position.x; if (Mathf.Abs(direction) > 0.01f) // Avoid flipping if almost aligned { Vector3 scale = spriteRenderer.transform.localScale; scale.x = Mathf.Abs(scale.x) * (direction > 0 ? 1 : -1); spriteRenderer.transform.localScale = scale; } } public void TrafalgarTouchedAnnaLise() { if (annaLiseIsReady == true && currentLureSpot.name == "LureSpotB") // Only allow if Anna Lise is ready and it's the correct lure spot { // Trigger the photo taken animation if (animator != null) { currentLureSpot.GetComponentInChildren().BirdReveal(); animator.SetTrigger("TakePhoto"); } annaLiseIsReady = false; // Reset the flag after taking the photo } Debug.Log("Trafalgar touched Anna Lise"); } }