NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Scene/SceneObject.cs

228 lines
5.7 KiB
C#
Raw Normal View History

2023-12-07 16:41:41 +08:00
using System.Collections.Generic;
using UnityEngine;
public enum ESceneObjectType
{
None = 0,
Tree = 1, //树
2023-12-10 15:21:33 +08:00
Buildings = 2, //建筑物
2023-12-25 16:07:59 +08:00
Stuff = 3,//其他
2023-12-07 16:41:41 +08:00
}
/// <summary>
/// 场景中对象,可以方便地执行一些渲染上的效果,如半透,面片渲染等
/// </summary>
public class SceneObject : MonoBehaviour
{
#region Fields
[SerializeField]
private bool _transparent;
[SerializeField]
private bool _useSurface;
[SerializeField]
2023-12-08 20:02:39 +08:00
public SceneObjectRenderInfo renderInfo;
2023-12-10 15:21:33 +08:00
2023-12-08 20:02:39 +08:00
[SerializeField]
public ESceneObjectType sceneObjectType;
2023-12-07 16:41:41 +08:00
2023-12-12 20:03:44 +08:00
private bool Valid => renderInfo != null;
private SceneSurfaceData _surfaceData;
public SceneSurfaceData SurfaceData
{
get
{
2023-12-13 13:51:06 +08:00
if (_surfaceData == null || !_surfaceData.valid)
2023-12-12 20:03:44 +08:00
{
NLDSceneManager sceneManager;
if (Application.isPlaying)
{
2024-01-02 14:52:37 +08:00
sceneManager = NLDSceneManager.Instance;
2023-12-12 20:03:44 +08:00
}
else
{
sceneManager = FindObjectOfType<NLDSceneManager>();
}
if (sceneManager is not null)
2023-12-12 20:03:44 +08:00
{
sceneManager.Refresh();
_surfaceData = sceneManager.GetSurfaceData(renderInfo);
}
}
return _surfaceData;
}
}
public bool SupportSurface => SurfaceData != null && SurfaceData.IsGameObjectValid(gameObject);
2023-12-14 14:33:45 +08:00
private Vector3 _originMeshScale;
private Vector3 _originMeshPosition;
private Quaternion _originMeshRotation;
2023-12-10 15:21:33 +08:00
2023-12-07 16:41:41 +08:00
#endregion
#region API
public bool Transparent
{
get => _transparent;
set
{
2023-12-12 20:03:44 +08:00
if (_transparent != value && Valid)
2023-12-07 16:41:41 +08:00
{
_transparent = value;
2023-12-10 15:21:33 +08:00
RefreshTransparent();
2023-12-07 16:41:41 +08:00
}
}
}
public bool UseSurface
{
get => _useSurface;
set
{
if (_useSurface != value)
{
2023-12-12 20:03:44 +08:00
if (value && !SupportSurface)
{
return;
}
2023-12-07 16:41:41 +08:00
_useSurface = value;
2023-12-12 20:03:44 +08:00
RefreshSurface();
2023-12-07 16:41:41 +08:00
}
}
}
2023-12-10 15:21:33 +08:00
#endregion
#region MainLife
2023-12-12 20:03:44 +08:00
private void Start()
2023-12-07 16:41:41 +08:00
{
}
#endregion
2023-12-10 15:21:33 +08:00
2023-12-14 14:33:45 +08:00
private void SaveSurfaceTransformValues(Transform meshTrans)
{
_originMeshScale = meshTrans.localScale;
_originMeshPosition = meshTrans.position;
_originMeshRotation = meshTrans.rotation;
}
private void RevertSurfaceTransformValues(Transform surfaceTrans)
{
surfaceTrans.localScale = _originMeshScale;
surfaceTrans.position = _originMeshPosition;
surfaceTrans.rotation = _originMeshRotation;
}
2023-12-10 15:21:33 +08:00
private void RefreshAllMaterials(List<Material> mats)
{
if (mats == null || mats.Count == 0)
return;
var meshrenderers = GetComponentsInChildren<MeshRenderer>();
int matIndex = 0;
List<Material> matsToSet = new();
foreach (var meshrenderer in meshrenderers)
{
matsToSet.Clear();
2023-12-12 20:03:44 +08:00
var msf = meshrenderer.GetComponent<MeshFilter>();
var mesh = msf.sharedMesh;
for (int i = 0; i < mesh.subMeshCount; i++)
2023-12-10 15:21:33 +08:00
{
2023-12-12 20:03:44 +08:00
Material matToSet = matIndex >= mats.Count ? null : mats[matIndex];
2023-12-10 15:21:33 +08:00
matsToSet.Add(matToSet);
matIndex++;
}
meshrenderer.SetSharedMaterials(matsToSet);
}
}
2023-12-12 20:03:44 +08:00
private void RefreshAllMeshes(List<Mesh> meshes)
{
if (meshes == null || meshes.Count == 0)
return;
var msfs = GetComponentsInChildren<MeshFilter>();
int meshIndex = 0;
foreach (var msf in msfs)
{
Mesh mesh = null;
if (meshIndex < meshes.Count)
mesh = meshes[meshIndex];
msf.sharedMesh = mesh;
meshIndex++;
}
}
2023-12-10 15:21:33 +08:00
private void RefreshTransparent()
{
if (!_useSurface)
{
RefreshAllMaterials(_transparent ? renderInfo.transparentMaterial : renderInfo.opaqueMaterial);
}
else
{
}
}
2023-12-12 20:03:44 +08:00
private void RefreshSurface()
{
if (_useSurface)
{
ChangeGameObjectToSurface();
}
else
{
ChangeGameObjectToReal();
}
}
private async void ChangeGameObjectToSurface()
{
var mat = await SurfaceData.GetMaterial();
if (mat is null)
2023-12-12 20:03:44 +08:00
{
_useSurface = false;
return;
2023-12-14 14:33:45 +08:00
}
2023-12-13 13:51:06 +08:00
2023-12-12 20:03:44 +08:00
var msr = gameObject.GetComponentInChildren<MeshRenderer>();
var msf = msr.GetComponent<MeshFilter>();
if (msr is null)
2023-12-14 14:33:45 +08:00
return;
var meshTrans = msr.transform;
SaveSurfaceTransformValues(meshTrans);
2023-12-12 20:03:44 +08:00
msf.sharedMesh = await SceneSurfaceData.GetSurfaceMesh();
RefreshAllMaterials(new List<Material>() { mat });
2023-12-14 14:33:45 +08:00
//必须是统一缩放
var rootScale = transform.localScale.x;
meshTrans.position += SurfaceData.cachedOffset * rootScale;
if (meshTrans == transform)
meshTrans.localScale = SurfaceData.cachedScale * rootScale;
else
meshTrans.localScale = SurfaceData.cachedScale;
meshTrans.eulerAngles = SurfaceData.cachedRotation;
2023-12-12 20:03:44 +08:00
}
private void ChangeGameObjectToReal()
{
2023-12-14 14:33:45 +08:00
var msr = gameObject.GetComponentInChildren<MeshRenderer>();
if (msr is null)
2023-12-14 14:33:45 +08:00
return;
var meshTrans = msr.transform;
2023-12-12 20:03:44 +08:00
RefreshAllMeshes(renderInfo.meshes);
RefreshTransparent();
2023-12-14 14:33:45 +08:00
RevertSurfaceTransformValues(meshTrans);
2023-12-12 20:03:44 +08:00
}
2023-12-07 16:41:41 +08:00
}