_xiaofang/xiaofang/Assets/Res/gsj/scripts/Godvisual.cs
2024-12-26 03:46:07 +08:00

149 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading.Tasks;
public class Godvisual : MonoBehaviour
{
public Transform mainBuilding; // 主建筑的中心点
public Transform birdEyeView; // 鸟瞰视角的 Transform
public Transform[] characterViews; // 每个角色的默认视角 Transform 数组
public bool ishost; // 是否为主持人
public float voiceLength = 10f; // 语音长度,单位秒
public float rotationRadius = 100f; // 环绕半径
public float rotationHeight = 5f; // 环绕高度
public float rotationSpeed = 36f; // 环绕速度(角速度,度/秒)
private float elapsedTime = 0f; // 已经经过的时间
private bool isSwitching = false; // 是否正在切换视角
private bool isRotating = false; // 是否正在旋转
private bool isAtGodView = true; // 是否处于上帝视角
void OnEnable()
{
// 订阅事件
Starthost.OnBoolValueChanged += HandleRotationControl;
}
void OnDisable()
{
// 取消订阅事件
Starthost.OnBoolValueChanged -= HandleRotationControl;
}
// Start is called before the first frame update
void Start()
{
// 最开始切换到上帝视角
SetToGodView();
elapsedTime = 0f;
isSwitching = false;
// 确保摄像机初始位置在环绕轨道上
//Vector3 startPosition = mainBuilding.position + new Vector3(rotationRadius, rotationHeight, 0);
//transform.position = startPosition;
//transform.LookAt(mainBuilding); // 摄像机始终朝向主建筑
}
// 切换到上帝视角
void SetToGodView()
{
transform.position = birdEyeView.position;
transform.rotation = birdEyeView.rotation;
isAtGodView = true;
isRotating = false; // 停止旋转逻辑
//transform.GetComponent<Camera>().orthographic = true;//正交
}
// Update is called once per frame
void Update()
{
if (!isRotating) return;
// 时间计数
elapsedTime += Time.deltaTime;
// 如果还未到最后两秒,环绕主建筑
if (elapsedTime < voiceLength - 2f && !isSwitching)
{
RotateAroundBuilding();
isAtGodView = false;
}
// 在最后两秒切换到目标视角
else if (!isSwitching)
{
isSwitching = true;
SwitchToFinalViewAsync();
}
if (isAtGodView)
{
//transform.GetComponent<Camera>().orthographic = true;
}
else
{
//transform.GetComponent<Camera>().orthographic = false;
}
}
// 环绕主建筑
void RotateAroundBuilding()
{
float angle = rotationSpeed * Time.deltaTime; // 每帧旋转的角度
Vector3 offset = transform.position - mainBuilding.position; // 当前摄像机到建筑中心的偏移
offset = Quaternion.Euler(0, angle, 0) * offset; // 绕建筑中心点旋转
transform.position = mainBuilding.position + offset; // 更新摄像机位置
transform.position = new Vector3(transform.position.x, mainBuilding.position.y + rotationHeight, transform.position.z); // 确保高度固定
transform.LookAt(mainBuilding); // 始终朝向主建筑
}
// 切换到最终视角(使用 async/await
async void SwitchToFinalViewAsync()
{
// 切换到鸟瞰图或角色视角
Transform targetView = ishost ? birdEyeView : GetCurrentCharacterView();
// 平滑切换摄像机位置和旋转
float switchDuration = 2f; // 切换持续时间
Vector3 startPosition = transform.position;
Quaternion startRotation = transform.rotation;
Vector3 endPosition = targetView.position;
Quaternion endRotation = targetView.rotation;
// 平滑过渡
for (float t = 0; t < switchDuration; t += Time.deltaTime)
{
float progress = t / switchDuration;
transform.position = Vector3.Lerp(startPosition, endPosition, progress);
transform.rotation = Quaternion.Lerp(startRotation, endRotation, progress);
await Task.Yield(); // 等待一帧
}
isAtGodView = true;
// 确保最终位置和旋转准确
transform.position = endPosition;
transform.rotation = endRotation;
}
// 获取当前角色的默认视角(假设角色索引为 0
Transform GetCurrentCharacterView()
{
int characterIndex = 0; // 根据逻辑动态获取角色索引
if (characterIndex >= 0 && characterIndex < characterViews.Length)
{
return characterViews[characterIndex];
}
else
{
Debug.LogWarning("角色视角未配置,使用默认鸟瞰视角");
return birdEyeView;
}
}
// 处理旋转控制事件
void HandleRotationControl(bool shouldRotate)
{
isRotating = shouldRotate;
if (!shouldRotate)
{
// 重置时间和切换状态
elapsedTime = 0f;
isSwitching = false;
}
}
}