我在使用LOD Group时遇到了困难,因为我想知道我在屏幕上看到的当前活动LOD级别是哪个。我只能访问百分比信息,但无法得知具体级别。
GameObject.GetComponent<LODGroup>().GetLODs()[size].screenRelativeTransitionHeight;
有人知道如何解决这个问题吗?提前感谢。
我在使用LOD Group时遇到了困难,因为我想知道我在屏幕上看到的当前活动LOD级别是哪个。我只能访问百分比信息,但无法得知具体级别。
GameObject.GetComponent<LODGroup>().GetLODs()[size].screenRelativeTransitionHeight;
在搜索answers.unity3d.com的答案时,我找到了这个链接:http://answers.unity3d.com/questions/684467/find-the-lod-step-which-is-currently-used.html
该链接涉及如何找到当前使用的LOD步骤。 LODGroup lodGroup = obj.GetComponent<LODGroup>();
if (lodGroup != null)
{
Transform lodTransform = lodGroup.transform;
foreach (Transform child in lodTransform)
{
var renderer = child.GetComponent<Renderer> ();
if (renderer != null && renderer.isVisible)
{
Debug.Log("This LODlevel is used: " + child.name);
}
}
}
您可以通过查看当前可见(在屏幕上可见)的子游戏对象渲染器的名称来确定当前活动的LOD级别。
static public int GetCurrentLODIndex(LODGroup lodGroup)
{
LOD[] lods = lodGroup.GetLODs();
for (int i = 0; i < lods.Length; i++)
{
LOD lod = lods[i];
if (lod.renderers.Length > 0 && lod.renderers[0].isVisible)
return i;
}
return -1;
}
using UnityEngine;
public class LODUtils
{
/// <summary>
/// Returns the currently visible LOD level of a specific LODGroup, from a specific camera.
/// </summary>
public static int GetCurrentLODIndex(LODGroup lodGroup, Camera camera)
{
var lods = lodGroup.GetLODs();
var relativeHeight = GetRelativeHeight(lodGroup, camera);
int lodIndex = GetMaxLOD(lodGroup);
for (var i = 0; i < lods.Length; i++)
{
var lod = lods[i];
if (relativeHeight >= lod.screenRelativeTransitionHeight)
{
lodIndex = i;
break;
}
}
return lodIndex;
}
private static float GetRelativeHeight(LODGroup lodGroup, Camera camera)
{
var distance = (lodGroup.transform.TransformPoint(lodGroup.localReferencePoint) - camera.transform.position).magnitude;
return DistanceToRelativeHeight(camera, (distance / QualitySettings.lodBias), GetWorldSpaceSize(lodGroup));
}
private static float DistanceToRelativeHeight(Camera camera, float distance, float size)
{
if (camera.orthographic)
return size * 0.5F / camera.orthographicSize;
var halfAngle = Mathf.Tan(Mathf.Deg2Rad * camera.fieldOfView * 0.5F);
var relativeHeight = size * 0.5F / (distance * halfAngle);
return relativeHeight;
}
private static int GetMaxLOD(LODGroup lodGroup)
{
return lodGroup.lodCount - 1;
}
private static float GetWorldSpaceSize(LODGroup lodGroup)
{
return GetWorldSpaceScale(lodGroup.transform) * lodGroup.size;
}
private static float GetWorldSpaceScale(Transform t)
{
var scale = t.lossyScale;
float largestAxis = Mathf.Abs(scale.x);
largestAxis = Mathf.Max(largestAxis, Mathf.Abs(scale.y));
largestAxis = Mathf.Max(largestAxis, Mathf.Abs(scale.z));
return largestAxis;
}
}
private static int GetLODCurShowLevel(Camera cam, LODGroup lodGroup)
{
//var inv_SceneViewCamHeight = 1.0f / (cam.pixelHeight - 6.0f);
var inv_SceneViewCamHeight = 1.0f / (cam.pixelHeight);
var lods = lodGroup.GetLODs();
for (int lodIDX = 0; lodIDX < lods.Length; lodIDX++)
{
var lod = lods[lodIDX];
var renderers = lod.renderers;
for (int renderIDX = 0; renderIDX < renderers.Length; renderIDX++)
{
var renderer = renderers[renderIDX];
// method1:
//var heightInScreen = Mathf.Abs(cam.WorldToScreenPoint(renderer.bounds.max).y - cam.WorldToScreenPoint(renderer.bounds.min).y);
// method2:
var heightInScreen = GetHeightInScreen(cam, renderer);
var ratioInScren = heightInScreen * inv_SceneViewCamHeight;
if (ratioInScren > lod.screenRelativeTransitionHeight)
{
return lodIDX;
}
}
}
return -1;
}
private static float GetHeightInScreen(Camera cam, Renderer renderer)
{
var min = renderer.bounds.min;
var max = renderer.bounds.max;
// F = Front
var FTL = new Vector3(min.x, max.y, min.z);
var FTR = new Vector3(max.x, max.y, min.z);
var FBR = new Vector3(max.x, min.y, min.z);
var FBL = new Vector3(min.x, min.y, min.z);
// Back
var BTL = new Vector3(min.x, max.y, max.z);
var BTR = new Vector3(max.x, max.y, max.z);
var BBR = new Vector3(max.x, min.y, max.z);
var BBL = new Vector3(min.x, min.y, max.z);
// to screen space pos
FTL = cam.WorldToScreenPoint(FTL);
FTR = cam.WorldToScreenPoint(FTR);
FBR = cam.WorldToScreenPoint(FBR);
FBL = cam.WorldToScreenPoint(FBL);
BTL = cam.WorldToScreenPoint(BTL);
BTR = cam.WorldToScreenPoint(BTR);
BBR = cam.WorldToScreenPoint(BBR);
BBL = cam.WorldToScreenPoint(BBL);
var maxY = FTL.y;
maxY = Mathf.Max(FTR.y, maxY);
maxY = Mathf.Max(FBR.y, maxY);
maxY = Mathf.Max(FBL.y, maxY);
maxY = Mathf.Max(BTL.y, maxY);
maxY = Mathf.Max(BTR.y, maxY);
maxY = Mathf.Max(BBR.y, maxY);
maxY = Mathf.Max(BBL.y, maxY);
var minY = FTL.y;
minY = Mathf.Min(FTR.y, minY);
minY = Mathf.Min(FBR.y, minY);
minY = Mathf.Min(FBL.y, minY);
minY = Mathf.Min(BTL.y, minY);
minY = Mathf.Min(BTR.y, minY);
minY = Mathf.Min(BBR.y, minY);
minY = Mathf.Min(BBL.y, minY);
return maxY - minY;
}
public class TestingStoreLODGroupCurLODLevel : MonoBehaviour
{
public bool[] lodVisibleArr;
public int GetCurLOD()
{
if (lodVisibleArr != null)
{
var len = lodVisibleArr.Length;
for (int i = 0; i < len; i++)
{
if (lodVisibleArr[i])
{
return i;
}
}
}
return -1;
}
}
public class TestingCheckVisibleChanged : MonoBehaviour
{
public int belongLOD;
public TestingStoreLODGroupCurLODLevel storeLOD;
private void OnBecameInvisible()
{
if (storeLOD)
{
storeLOD.lodVisibleArr[belongLOD] = false;
}
}
private void OnBecameVisible()
{
if (storeLOD)
{
storeLOD.lodVisibleArr[belongLOD] = true;
}
}
}
private void SetupCheckLODInfo(GameObject go)
{
var lodGroup = go.GetComponent<LODGroup>();
if (lodGroup == null)
{
return;
}
var storeLODComp = go.GetComponent<TestingStoreLODGroupCurLODLevel>();
if (storeLODComp != null)
{
return;
}
storeLODComp = go.AddComponent<TestingStoreLODGroupCurLODLevel>();
var lods = lodGroup.GetLODs();
for (int lodIDX = 0; lodIDX < lods.Length; lodIDX++)
{
var lod = lods[lodIDX];
var renderers = lod.renderers;
for (int rendererIDX = 0; rendererIDX < renderers.Length; rendererIDX++)
{
var renderer = renderers[rendererIDX];
var checkVisibleComp = renderer.gameObject.GetComponent<TestingCheckVisibleChanged>();
if (checkVisibleComp == null)
{
checkVisibleComp = renderer.gameObject.AddComponent<TestingCheckVisibleChanged>();
}
checkVisibleComp.belongLOD = lodIDX;
checkVisibleComp.storeLOD = storeLODComp;
}
}
storeLODComp.lodVisibleArr = new bool[lods.Length];
}
private void UnSetupCheckLODInfo(GameObject go)
{
var lodGroup = go.GetComponent<LODGroup>();
if (lodGroup == null)
{
return;
}
var storeLODComp = go.GetComponent<TestingStoreLODGroupCurLODLevel>();
if (storeLODComp != null)
{
GameObject.Destroy(storeLODComp);
}
var lods = lodGroup.GetLODs();
for (int lodIDX = 0; lodIDX < lods.Length; lodIDX++)
{
var lod = lods[lodIDX];
var renderers = lod.renderers;
for (int rendererIDX = 0; rendererIDX < renderers.Length; rendererIDX++)
{
var renderer = renderers[rendererIDX];
var checkVisibleComp = renderer.gameObject.GetComponent<TestingCheckVisibleChanged>();
if (checkVisibleComp != null)
{
GameObject.Destroy(checkVisibleComp);
}
}
}
}