123 lines
3.0 KiB
C#
123 lines
3.0 KiB
C#
using UnityEngine;
|
|
using DG.Tweening;
|
|
|
|
/// <summary>
|
|
/// 物体飞到玩家面前 + 可选始终面向玩家 + 飞回原位
|
|
/// </summary>
|
|
public class FlyFollowToPlayer : MonoBehaviour
|
|
{
|
|
[Header("玩家摄像机")]
|
|
public Transform playerCamera;
|
|
|
|
[Header("停留距离")]
|
|
public float distance = 0.8f;
|
|
|
|
[Header("高度偏移")]
|
|
public float heightOffset = -0.1f;
|
|
|
|
[Header("平滑跟随速度")]
|
|
public float followSmooth = 6f;
|
|
|
|
[Header("视线锁定阈值(角度)")]
|
|
public float viewLockAngle = 5f;
|
|
|
|
[Header("是否始终面向玩家")]
|
|
public bool alwaysFacePlayer = true;
|
|
|
|
private bool isFlying = false;
|
|
private bool isFollow = false;
|
|
|
|
private Vector3 targetPos;
|
|
|
|
/// <summary>原始位置与旋转(回展台)</summary>
|
|
private Vector3 originPos;
|
|
private Quaternion originRot;
|
|
|
|
void Start()
|
|
{
|
|
originPos = transform.position;
|
|
originRot = transform.rotation;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (!isFollow) return;
|
|
|
|
// 计算目标位置(始终在视线前方)
|
|
targetPos = playerCamera.position
|
|
+ playerCamera.forward * distance
|
|
+ Vector3.up * heightOffset;
|
|
|
|
// 判断是否在视线正前
|
|
Vector3 dir = (transform.position - playerCamera.position).normalized;
|
|
float angle = Vector3.Angle(playerCamera.forward, dir);
|
|
|
|
// 已在视线范围内则停止位置修正,但如果需要朝向玩家,则继续朝向
|
|
if (angle >= viewLockAngle)
|
|
{
|
|
// 平滑移动
|
|
transform.position = Vector3.Lerp(
|
|
transform.position,
|
|
targetPos,
|
|
Time.deltaTime * followSmooth
|
|
);
|
|
}
|
|
|
|
// 是否面向玩家
|
|
if (alwaysFacePlayer)
|
|
{
|
|
transform.LookAt(playerCamera);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 物体飞到玩家面前
|
|
/// </summary>
|
|
public void FlyToPlayer()
|
|
{
|
|
if (isFlying) return;
|
|
isFlying = true;
|
|
|
|
targetPos = playerCamera.position
|
|
+ playerCamera.forward * distance
|
|
+ Vector3.up * heightOffset;
|
|
|
|
transform.DOMove(targetPos, 1f)
|
|
.SetEase(Ease.OutBack)
|
|
.OnComplete(() =>
|
|
{
|
|
isFollow = true;
|
|
isFlying = false;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止跟随玩家(不再更新位置)
|
|
/// </summary>
|
|
public void StopFollow()
|
|
{
|
|
isFollow = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 物体飞回展台原位
|
|
/// </summary>
|
|
public void FlyBackToOrigin()
|
|
{
|
|
isFollow = false; // 停止跟随玩家
|
|
isFlying = true;
|
|
|
|
transform.DOKill(); // 停止其他动画,避免冲突
|
|
|
|
transform.DOMove(originPos, 1f)
|
|
.SetEase(Ease.InOutQuad);
|
|
|
|
transform.DORotateQuaternion(originRot, 1f)
|
|
.SetEase(Ease.InOutQuad)
|
|
.OnComplete(() =>
|
|
{
|
|
isFlying = false;
|
|
});
|
|
}
|
|
}
|