最新文章
Cocos2d-x游戏开发实例详解7:对象释放时机
03-25 13:59
Cocos2d-x游戏开发实例详解6:自动释放池
03-25 13:55
Cocos2d-x游戏开发实例详解5:神奇的自动释放
03-25 13:49
Cocos2d-x游戏开发实例详解4:游戏主循环
03-25 13:44
Cocos2d-x游戏开发实例详解3:无限滚动地图
03-25 13:37
Cocos2d-x游戏开发实例详解2:开始菜单续
03-25 13:32
unity3d中lod核心脚本
2015年01月14日 11:54
0 点赞
0 评论
更新于 2025-11-21 14:22
在Unity3D中,LOD(Level of Detail)核心脚本的主要功能是根据物体与相机的距离来判断哪些物体需要隐藏,哪些物体需要显示,以此来优化场景性能,提高渲染效率。以下是详细的脚本内容及解释:
// *********************************************************************
// Speed LOD manager, set for 5 LOD
// (c) Nikko /Unity3dx.com
// All Rights reserved
// http://unity3dx.com
// *********************************************************************
// How to use: this script needs to be attached to the LOD prefab.
//@script ExecuteInEditMode
// 定义LOD级别枚举
private enum _Nikko_LOD_LEVEL { LOD0, LOD1, LOD2, LOD3, LOD4, LOD5 }
// LOD编号
public var nlod: int;
// 不同LOD级别的网格对象
public var lodMesh0: GameObject;
public var lodMesh1: GameObject;
public var lodMesh2: GameObject;
public var lodMesh3: GameObject;
public var lodMesh4: GameObject;
// 相机对象
public var mycam: Camera;
// 延迟计数器
public var delaycounter: int;
// 隐藏距离
public var distancehide: float;
// 不同LOD级别的切换距离
public var distanceLOD1: float;
public var distanceLOD2: float;
public var distanceLOD3: float;
public var distanceLOD4: float;
// 当前LOD级别
private var currentLOD: _Nikko_LOD_LEVEL = _Nikko_LOD_LEVEL.LOD4;
// 计数器
private var counter: int;
// 获取LOD编号
function getLODNbr() {
return nlod;
}
// 设置LOD编号
function setLODNbr(v: int) {
nlod = v;
}
// 获取组件名称
function getComponentName() {
return "Nikko_LODManager5";
}
// 设置LOD级别
function setLOD(l: int) {
switch (l) {
case _Nikko_LOD_LEVEL.LOD0:
lodMesh0.SetActiveRecursively(true);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
case _Nikko_LOD_LEVEL.LOD1:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(true);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
case _Nikko_LOD_LEVEL.LOD2:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(true);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
case _Nikko_LOD_LEVEL.LOD3:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(true);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
case _Nikko_LOD_LEVEL.LOD4:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(true);
break;
case _Nikko_LOD_LEVEL.LOD5:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
default:
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
if (nlod > 3) lodMesh3.SetActiveRecursively(false);
if (nlod > 4) lodMesh4.SetActiveRecursively(false);
break;
}
}
// 设置不同LOD级别的切换距离
function setDistanceLOD(lod: int, dist: float) {
switch (lod) {
case _Nikko_LOD_LEVEL.LOD0:
distanceLOD0 = dist;
break;
case _Nikko_LOD_LEVEL.LOD1:
distanceLOD1 = dist;
break;
case _Nikko_LOD_LEVEL.LOD2:
distanceLOD2 = dist;
break;
case _Nikko_LOD_LEVEL.LOD3:
distanceLOD3 = dist;
break;
case _Nikko_LOD_LEVEL.LOD4:
distanceLOD4 = dist;
break;
default:
Debug.LogError("SetDistanceLOD: Wrong LOD value");
return;
}
}
// 设置计数器
function SetCounter(c: int) {
counter = c;
}
// 脚本开始时执行
function Start() {
// 随机初始化计数器,使每个LOD在不同帧进行检查
counter = Random.Range(1, delaycounter);
// 计算物体与相机的距离
var distanceFromObject: float = Vector3.Distance(transform.position, mycam.transform.position);
// 如果物体距离相机过远,隐藏物体
if (distanceFromObject > distancehide) {
switch (nlod) {
case 3:
currentLOD = _Nikko_LOD_LEVEL.LOD3;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
break;
case 4:
currentLOD = _Nikko_LOD_LEVEL.LOD4;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
break;
case 5:
currentLOD = _Nikko_LOD_LEVEL.LOD5;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
lodMesh4.SetActiveRecursively(false);
break;
}
}
}
// 每帧更新后执行
function LateUpdate() {
// 计数器减1
counter = counter - 1;
// 当计数器小于0时,进行LOD检查和切换
if (counter < 0) {
counter = delaycounter;
// 计算物体与相机的距离
var distanceFromObject: float = Vector3.Distance(transform.position, mycam.transform.position);
switch (nlod) {
// LOD 3处理
case 3:
// 设置LOD0
if (distanceFromObject < distanceLOD1 && currentLOD != _Nikko_LOD_LEVEL.LOD0) {
currentLOD = _Nikko_LOD_LEVEL.LOD0;
lodMesh0.SetActiveRecursively(true);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
return;
}
// 设置LOD1
else if (distanceFromObject >= distanceLOD1 && distanceFromObject < distanceLOD2 && currentLOD != _Nikko_LOD_LEVEL.LOD1) {
currentLOD = _Nikko_LOD_LEVEL.LOD1;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(true);
lodMesh2.SetActiveRecursively(false);
return;
}
// 设置LOD2
else if (distanceFromObject >= distanceLOD2 && distanceFromObject < distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD2) {
currentLOD = _Nikko_LOD_LEVEL.LOD2;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(true);
return;
}
// 物体过远,隐藏
else if (distanceFromObject > distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD5) {
currentLOD = _Nikko_LOD_LEVEL.LOD3;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
return;
}
break;
// LOD 4处理
case 4:
// 设置LOD0
if (distanceFromObject < distanceLOD1 && currentLOD != _Nikko_LOD_LEVEL.LOD0) {
currentLOD = _Nikko_LOD_LEVEL.LOD0;
lodMesh0.SetActiveRecursively(true);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
return;
}
// 设置LOD1
else if (distanceFromObject >= distanceLOD1 && distanceFromObject < distanceLOD2 && currentLOD != _Nikko_LOD_LEVEL.LOD1) {
currentLOD = _Nikko_LOD_LEVEL.LOD1;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(true);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
return;
}
// 设置LOD2
else if (distanceFromObject >= distanceLOD2 && distanceFromObject < distanceLOD3 && currentLOD != _Nikko_LOD_LEVEL.LOD2) {
currentLOD = _Nikko_LOD_LEVEL.LOD2;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(true);
lodMesh3.SetActiveRecursively(false);
return;
}
// 设置LOD3
else if (distanceFromObject >= distanceLOD3 && distanceFromObject < distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD3) {
currentLOD = _Nikko_LOD_LEVEL.LOD3;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(true);
return;
}
// 物体过远,隐藏
else if (distanceFromObject > distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD5) {
currentLOD = _Nikko_LOD_LEVEL.LOD4;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
return;
}
break;
// LOD 5处理
case 5:
// 设置LOD0
if (distanceFromObject < distanceLOD1 && currentLOD != _Nikko_LOD_LEVEL.LOD0) {
currentLOD = _Nikko_LOD_LEVEL.LOD0;
lodMesh0.SetActiveRecursively(true);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
lodMesh4.SetActiveRecursively(false);
return;
}
// 设置LOD1
else if (distanceFromObject >= distanceLOD1 && distanceFromObject < distanceLOD2 && currentLOD != _Nikko_LOD_LEVEL.LOD1) {
currentLOD = _Nikko_LOD_LEVEL.LOD1;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(true);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
lodMesh4.SetActiveRecursively(false);
return;
}
// 设置LOD2
else if (distanceFromObject >= distanceLOD2 && distanceFromObject < distanceLOD3 && currentLOD != _Nikko_LOD_LEVEL.LOD2) {
currentLOD = _Nikko_LOD_LEVEL.LOD2;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(true);
lodMesh3.SetActiveRecursively(false);
lodMesh4.SetActiveRecursively(false);
return;
}
// 设置LOD3
else if (distanceFromObject >= distanceLOD3 && distanceFromObject < distanceLOD4 && currentLOD != _Nikko_LOD_LEVEL.LOD3) {
currentLOD = _Nikko_LOD_LEVEL.LOD3;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(true);
lodMesh4.SetActiveRecursively(false);
return;
}
// 设置LOD4
else if (distanceFromObject >= distanceLOD4 && distanceFromObject < distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD4) {
currentLOD = _Nikko_LOD_LEVEL.LOD4;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(true);
lodMesh4.SetActiveRecursively(false);
return;
}
// 物体过远,隐藏
else if (distanceFromObject > distancehide && currentLOD != _Nikko_LOD_LEVEL.LOD5) {
currentLOD = _Nikko_LOD_LEVEL.LOD5;
lodMesh0.SetActiveRecursively(false);
lodMesh1.SetActiveRecursively(false);
lodMesh2.SetActiveRecursively(false);
lodMesh3.SetActiveRecursively(false);
lodMesh4.SetActiveRecursively(false);
return;
}
break;
}
}
}
脚本使用说明
- 此脚本需要附加到LOD预制体上。
- 通过设置不同的
distanceLOD值,可以调整不同LOD级别的切换距离。 delaycounter参数用于控制LOD检查的频率,避免每帧都进行检查,以提高性能。
注意事项
- 脚本中存在一个小错误,
distanceLOD0未定义,需要根据实际情况进行修正。 - 该脚本使用了Unity的JavaScript语法,在新版Unity中,建议使用C#进行开发。