您当前的位置: 首页 >  Jave.Lin unity

Unity - 人物对象的 LOD 管理

Jave.Lin 发布时间:2021-12-23 21:09:24 ,浏览量:3

文章目录
  • Unity 没有内置的人物角色 LOD 管理
  • 可以自己写脚本按距离来控制
  • 扩展、及其问题
  • 另一种更好的方式
  • References

Unity 没有内置的人物角色 LOD 管理

参考了 Unity 论坛上的某个帖子:Level of Detail management (LOD)

虽然 Unity 没有内置的角色 LOD 管理 在这里插入图片描述

但是我们可以自己根据距离来切换网格 在这里插入图片描述

可以自己写脚本按距离来控制

直接参考:https://pastebin.com/clone/K1S4Zjh0

using UnityEngine;
using System;
using System.Collections.Generic;

//[ExecuteInEditMode]
public class CharacterLOD : MonoBehaviour
{
    public Mesh LOD0;
    public Mesh LOD1;
    public Mesh LOD2;
    public Mesh LOD3;

    public List LOD_0_Materials;
    public List LOD_1_Materials;
    public List LOD_2_Materials;
    public List LOD_3_Materials;

    public float lod0Dist = 10f;
    public float lod1Dist = 20f;
    public float lod2Dist = 30f;
    public float lod3Dist = 50f;
    public float lodTimer = 0.3f;

    public Camera camera1;
    private bool foundCamera;
    public int currLOD;
    private float currTimer;
    

    public void Start()
    {
        GetCamera();
        currLOD = 0;
    }

    void Update()
    {
        if (foundCamera == false)
            GetCamera();

        //Update LODs Timer
        currTimer -= Time.deltaTime;
        if (currTimer = 3)
        {
            if (LOD_3_Materials.Count > 0)
                return 3;
            if (LOD_2_Materials.Count > 0)
                return 2;
            if (LOD_1_Materials.Count > 0)
                return 1;
            if (LOD_0_Materials.Count > 0)
                return 0;
        }
        if (desired == 2)
        {
            if (LOD_2_Materials.Count > 0)
                return 2;
            if (LOD_1_Materials.Count > 0)
                return 1;
            if (LOD_0_Materials.Count > 0)
                return 0;
        }
        if (desired == 1)
        {
            if (LOD_1_Materials.Count > 0)
                return 1;
            if (LOD_0_Materials.Count > 0)
                return 0;
        }
        if (desired == 0)
        {
            if (LOD_0_Materials.Count > 0)
                return 0;
        }
        return 0;
    }

    public void SetLowestLODMesh(int desired)
    {
        SkinnedMeshRenderer mf1 = GetComponent();
        if (desired >= 3)
        {
            if (LOD3 != null)
                mf1.sharedMesh = LOD3;
            if (LOD2 != null)
                mf1.sharedMesh = LOD2;
            if (LOD1 != null)
                mf1.sharedMesh = LOD1;
            if (LOD0 != null)
                mf1.sharedMesh = LOD0;
        }
        if (desired == 2)
        {
            if (LOD2 != null)
                mf1.sharedMesh = LOD2;
            if (LOD1 != null)
                mf1.sharedMesh = LOD1;
            if (LOD0 != null)
                mf1.sharedMesh = LOD0;
        }
        if (desired == 1)
        {
            if (LOD1 != null)
                mf1.sharedMesh = LOD1;
            if (LOD0 != null)
                mf1.sharedMesh = LOD0;
        }
        if (desired == 0)
            if (LOD0 != null)
                mf1.sharedMesh = LOD0;
    }

    public void GetCamera()
    {
        try
        {
            camera1 = Camera.main;
            foundCamera = true;
        }
        catch (Exception e)
        {
            Debug.Log("[CharacterLOD] Couldn't find Main Camera: " + e.Message);
        }
    }
}
扩展、及其问题

上面按距离的方式来处理的话会有一些问题

比如说再 FPS 游戏中就不太好用

因为游戏会有倍镜

而倍镜一般时调整 FOV 来处理的

再使用 LODGroup 中处理的时按屏幕高度比例来处理的话,这种制作时没有问题的

但时 LODGROUP 的方式不设置对 SkinnedMeshRenderer 做处理

因为 SkinnedMeshRenderer 内部有动画信息的状态

所以只能写脚本切换 Mesh 即可,动画骨骼信息不要动他就可以了

然后配上 自己按 FOV 的数值来换算一下,让 FOV 不同大小下也可以比较正常的显示 SknnedMeshRnederer 的 LOD

还有另一个问题,以上这些方式都不能切换骨骼结构

因为如果一个模型骨骼结构很复杂,也时消耗比较大的

但是理论上,我们可以再写一个:再切换 LOD时,可以将前一个LOD的 Animator 状态和 AnimationClip.playTime 同步一下到当前的 LOD 即可,但是不保证会不会抖动,得看 API 得封装够不够好

另一种更好的方式
  • 首先得有 带骨骼蒙皮的 模型,和 或对应的 LOD1, LOD2
    • 可以使用工具生成,比如:使用 UMS (Unity Mesh Simplifier) 工具,github : Whinarn/UnityMeshSimplifier
  • 直接给父级添加 LODGroup ,设置好每一级的 LOD renderers 就OK了
  • 可以无缝LOD切换
References
  • Creating LOD Group for character
  • Level of Detail management (LOD)
  • Unity自动生成LOD,人形角色LOD的使用解决动画播放问题 - 这种方式不太好,人物LOD切换时还有动作抖动,但是里面的 LOD 模型生成插件可以使用
关注
打赏
1688896170
查看更多评论

Jave.Lin

暂无认证

  • 3浏览

    0关注

    546博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0598s