自动处理2.5D(伪3D)游戏中物体的遮挡关系

2 篇文章 0 订阅

使用了OrderInLayer而不是z坐标来对伪3D场景物体进行定时排序。

 

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

//自定义比较器,通过 Transform.position.y 给 List 排序
public class StageObjectComparer : IComparer<ZSortObject>
{
    public int Compare(ZSortObject a, ZSortObject b)
    {
        if (a.transform.position.y - b.transform.position.y > 0f)
        {
            return 1;
        }
        else if (a.transform.position.y - b.transform.position.y < 0f)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }
}

//主类 ZSortObject , 场景内所有挂载了该脚本的2D物体 都将按照y轴位置 自动调整遮挡关系,遮挡关系通过z轴位置来调整
public class ZSortObject : MonoBehaviour
{

    public static List<ZSortObject> StageObjectList = new List<ZSortObject>(); //存放所有需要排序的物体,注意是静态的
    //public float StageZGap = 0.01f; //两个相邻物体之间的z轴距离
    //public float StageZMin = 0f; //最靠前的物体的z轴位置
    public float SortRant = 0.03f; //每隔多久排序一次

    private static StageObjectComparer Soc = new StageObjectComparer(); //排序器的实例化
    private float SortTime = 0f; //距离下次排序的时间

    void OnEnable()
    {
        //每次恢复意识都把自己写进 List
        if (!StageObjectList.Contains(this))
        {
            StageObjectList.Add(this);
        }
    }

    void OnDisabled()
    {
        //每次失去意识都把自己踢出 List
        StageObjectList.Remove(this);
    }

    void Update()
    {

        //如果需要执行排序(列表里有物体 且当前实例是列表的第一个物体)
        if (StageObjectList.Count > 0 && StageObjectList[0] == this)
        {
            //如果到了该排序的时间
            if (SortTime < 0f)
            {
                SortObjects();
                SortTime += SortRant; //不要写成 SortTime = SortRant,会扔掉小于0的部分
            }
            else
            {
                SortTime -= Time.deltaTime;
            }
        }
    }

    //每次执行这个函数,都会将场景中所有的物体排序一次
    void SortObjects()
    {

        //用List类的自定义排序方法
        ZSortObject.StageObjectList.Sort(Soc);

        int _count = ZSortObject.StageObjectList.Count;

        for (int i = 0; i < _count; i++)
        {
            ZSortObject.StageObjectList[i].GetComponent<SpriteRenderer>().sortingOrder = _count - i;
        }
    }
}
 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Unity实现多物体遮挡的方法有多种。一种常见的方法是使用射线检测来判断物体是否被其他物体遮挡。通过摄像机向人物发射射线,检测第一个碰到的物体是否为人物。如果不是人物,那么就判断为障碍,将其透明度设为0.2,并将其添加入一个GameObject数组。当射线检测到第一个物体是人物时,将这个GameObject数组的所有物体透明度恢复为1,并清空这个数组。这样可以实现多物体遮挡效果。\[1\] 另一种方法是使用材质的透明度来实现多物体遮挡。通过改变物体的材质透明度,可以使被遮挡物体变得半透明。在Unity,可以直接修改物体的材质透明度,而不需要额外新建材质。这种方法不会导致其他共用此材质的物体也变透明的问题。\[2\] 此外,还可以通过设置物体的Layer和渲染顺序来实现多物体遮挡。可以为角色设置一个单独的Layer,并单独渲染该层级的对象。在材质设置,选择Depth深度勾选,WriteDepth不选,选择Greater,意思是当渲染距离大于某物体且重叠渲染时,才进行渲染。通过添加第二个CharacterInFrond,可以实现多物体遮挡效果。\[3\] 以上是几种在Unity实现多物体遮挡的方法,可以根据具体需求选择适合的方法来实现多物体遮挡效果。 #### 引用[.reference_title] - *1* *2* [Unity实现遮挡人物的障碍物体设为透明,并在不遮挡时恢复的个人解决方法](https://blog.csdn.net/qianhang120/article/details/128145939)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Unity——物体遮挡角色轮廓显示(URPShaderGraph)](https://blog.csdn.net/qq_45946883/article/details/118070864)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值