116 lines
3.9 KiB
C#
116 lines
3.9 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace RR.Game2D.Core
|
|
{
|
|
public class CameraFollow2D : MonoBehaviour
|
|
{
|
|
[Header("Follow")]
|
|
[SerializeField, Min(0)] private float damping = 1.5f;
|
|
[SerializeField] private Vector2 offset = new(2f, 1f);
|
|
[SerializeField] private bool faceLeft;
|
|
|
|
[Header("Behaviour")]
|
|
[SerializeField] private 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; }
|
|
}
|
|
|
|
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;
|
|
faceLeft = Mathf.Abs(player.localEulerAngles.y) >= 180 ? true : false;
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Цикл привязки камеры к игроку. Ищет игрока на сцене.
|
|
/// </summary>
|
|
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; // подождём кадр
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Метод для поиска объекта игрока.
|
|
/// Сначала ищет экземпляр объекта игрока в GameManager,
|
|
/// затем, ели не нашел, то ищет по тегу на сцене
|
|
/// </summary>
|
|
/// <returns>Transform playerPosition - позиция игрокка</returns>
|
|
private Transform ResolvePlayer()
|
|
{
|
|
if (GameManager.Instance && GameManager.Instance.PlayerObj)
|
|
return GameManager.Instance.PlayerObj.transform;
|
|
|
|
var go = GameObject.FindWithTag("Player");
|
|
return go ? go.transform : null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Метод для поиска игрока и привязки к нему камеры.
|
|
/// </summary>
|
|
/// <param name="playerFaceLeft">Повернут ли игрок налево</param>
|
|
public void FindPlayer(bool playerFaceLeft)
|
|
{
|
|
faceLeft = playerFaceLeft;
|
|
player = ResolvePlayer();
|
|
if (!player)
|
|
{
|
|
Debug.Log("CameraFollow2D: player not found yet, will wait.");
|
|
return;
|
|
}
|
|
lastX = player.position.x;
|
|
SnapToPlayer(faceLeft);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Метод для привязки камеры к игроку.
|
|
/// </summary>
|
|
/// <param name="playerFaceLeft">Повернут ли игрок налево</param>
|
|
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;
|
|
}
|
|
}
|
|
} |