102 lines
3.2 KiB
C#
102 lines
3.2 KiB
C#
using System.Collections;
|
||
using UnityEngine;
|
||
|
||
public class CameraFollow2D : MonoBehaviour
|
||
{
|
||
[Header("Follow")]
|
||
public float damping = 1.5f;
|
||
public Vector2 offset = new(2f, 1f);
|
||
public bool faceLeft;
|
||
|
||
[Header("Behaviour")]
|
||
public bool snapOnFound = true; // мгновенно «прилипнуть», когда нашли игрока
|
||
|
||
private Transform player;
|
||
private float lastX;
|
||
private Coroutine bindRoutine;
|
||
|
||
void OnEnable()
|
||
{
|
||
offset = new Vector2(Mathf.Abs(offset.x), offset.y);
|
||
// запускаем цикл привязки — он подождёт появления игрока в билде
|
||
bindRoutine = StartCoroutine(BindLoop());
|
||
}
|
||
|
||
void OnDisable()
|
||
{
|
||
if (bindRoutine != null) { StopCoroutine(bindRoutine); bindRoutine = null; }
|
||
}
|
||
|
||
// Главный цикл: если игрока нет/его уничтожили — пытаемся найти снова
|
||
private IEnumerator BindLoop()
|
||
{
|
||
while (true)
|
||
{
|
||
if (!player)
|
||
{
|
||
var t = ResolvePlayer();
|
||
if (t)
|
||
{
|
||
player = t;
|
||
lastX = player.position.x;
|
||
if (snapOnFound) SnapToPlayer(faceLeft);
|
||
}
|
||
}
|
||
yield return null; // подождём кадр
|
||
}
|
||
}
|
||
|
||
// Пытаемся получить трансформ игрока сначала из GameManager, потом по тегу
|
||
private Transform ResolvePlayer()
|
||
{
|
||
// 1) Через GameManager, если он есть и уже создал игрока
|
||
if (GameManager.Instance && GameManager.Instance.playerObj)
|
||
return GameManager.Instance.playerObj.transform;
|
||
|
||
// 2) Фолбэк по тегу (если префаб помечен "Player")
|
||
var go = GameObject.FindWithTag("Player");
|
||
return go ? go.transform : null;
|
||
}
|
||
|
||
// Совместимость с твоим прежним API — теперь безопасно
|
||
public void FindPlayer(bool playerFaceLeft)
|
||
{
|
||
faceLeft = playerFaceLeft;
|
||
player = ResolvePlayer();
|
||
if (!player)
|
||
{
|
||
Debug.Log("CameraFollow2D: player not found yet, will wait.");
|
||
return; // BindLoop сам подцепит позже
|
||
}
|
||
lastX = player.position.x;
|
||
SnapToPlayer(faceLeft);
|
||
}
|
||
|
||
private void SnapToPlayer(bool playerFaceLeft)
|
||
{
|
||
if (!player) return;
|
||
Vector3 p = player.position;
|
||
p.x += (playerFaceLeft ? -offset.x : offset.x);
|
||
p.y += offset.y;
|
||
p.z = transform.position.z;
|
||
transform.position = p;
|
||
}
|
||
|
||
void FixedUpdate()
|
||
{
|
||
if (!player) return; // ждём появления
|
||
|
||
float currentX = player.position.x;
|
||
if (currentX > lastX + 0.01f) faceLeft = false;
|
||
else if (currentX < lastX - 0.01f) faceLeft = true;
|
||
lastX = currentX;
|
||
|
||
Vector3 target = player.position;
|
||
target.x += faceLeft ? -offset.x : +offset.x;
|
||
target.y += offset.y;
|
||
target.z = transform.position.z;
|
||
|
||
transform.position = Vector3.Lerp(transform.position, target, damping * Time.deltaTime);
|
||
}
|
||
}
|