Files
2026-05-26 16:15:54 +08:00

118 lines
4.0 KiB
C#

using DG.Tweening;
using UnityEngine;
using System.Collections.Generic;
using cfg;
using asap.core;
using PlayFab.GroupsModels;
public class CameraCtrl : MonoBehaviour
{
private Transform _focus;
private float _blockDepth, _skyLoopTriggerheight, _skyLoopOffsetDelta;
private MeshRenderer _sky;
private Material _skyMat;
private InfiniteBuildingConf _cfg;
private InfiniteBuildingData _data;
private List<int> _lvlThresh;
private List<float> _depth, _yOffset;
private TbConstructionHeightEvent _tableHeightEvent;
private readonly string MatOffsetKey = "_Offset";
//[SerializeField]private CinemachineVirtualCamera _cam;
/* public Vector3 LowerLimit
{
get
{
Vector3 pos = Camera.main.ViewportToWorldPoint(
new Vector3(0.5f, 0, _blockDepth - transform.position.z));
//Debug.Log(pos);
return pos;
}
}
*/
public float CamDepth
{
get { return GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _depth); }
}
public void Init(Transform focus, InfiniteBuildingConf cfg, MeshRenderer sky,
InfiniteBuildingData data)
{
_tableHeightEvent = GContext.container.Resolve<Tables>().TbConstructionHeightEvent;
_focus = focus;
_blockDepth = cfg.blockDepth;
_sky = sky;
_skyMat = sky.sharedMaterial;
_skyLoopTriggerheight = cfg.skyLoopTriggerHeight;
_skyLoopOffsetDelta = cfg.skyLoopOffsetDelta;
if (focus.position.y >= cfg.skyLoopTriggerHeight)
{
Vector3 pos = _sky.transform.position;
_sky.transform.position = new Vector3(pos.x, transform.position.y, pos.z);
}
_cfg = cfg;
_data = data;
_lvlThresh = new List<int>();
_depth = new List<float>();
_yOffset = new List<float>();
foreach (var c in _tableHeightEvent.DataList)
{
_lvlThresh.Add(c.Height);
_depth.Add(c.CameraDepth);
_yOffset.Add(c.CameraYOffest);
}
transform.position = new Vector3(0,
focus.position.y + GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _yOffset),
focus.position.z - CamDepth);
if (_focus.position.y >= _skyLoopTriggerheight)
_sky.transform.position =
new Vector3(0, transform.position.y, _sky.transform.position.z);
_skyMat.SetVector(MatOffsetKey, Vector4.zero);
}
public void FollowFocus(float duration = 0.5f)
{
transform.DOMove(new Vector3(0,
_focus.position.y + GetDataByIBLvl<float>(_data.Lvl, _lvlThresh, _yOffset),
transform.position.z), duration);
if (_focus.position.y < _skyLoopTriggerheight)
return;
_sky.transform.DOMove(new Vector3(0, transform.position.y, _sky.transform.position.z),
duration);
//Vector2 oldOffset = _skyMat.GetTextureOffset("_Texture2D");
//Debug.Log(oldOffset);
//_skyMat.DOOffset(oldOffset + Vector2.up * _skyLoopOffsetDelta, duration);
Vector2 offset = _skyMat.GetVector(MatOffsetKey);
float t = 0;
DOTween.To(() => t, (value) => t = value, _skyLoopOffsetDelta, duration)
.OnUpdate(() => _skyMat.SetVector(MatOffsetKey, offset + t * Vector2.up)).OnComplete(() =>
{
var v = _skyMat.GetVector(MatOffsetKey);
while (v.y > 0.5f) v.y -= 1f;
while (v.y < -0.5f) v.y += 1f;
_skyMat.SetVector(MatOffsetKey, v);
});
}
private T GetDataByIBLvl<T>(int lvl, List<int> lvlThresh, List<T> dataList)
{
if (lvlThresh.Count != dataList.Count)
{
Debug.LogError($"lvlTresh count {lvlThresh.Count} does not" +
$"match dataList count {dataList.Count}");
return default(T);
}
for (int i = 0; i < lvlThresh.Count - 1; i++)
{
if (lvl < lvlThresh[i + 1])
return dataList[i];
}
return dataList[^1];
}
}