问候!
我知道,从本质上讲,您知道您缺少哪些纸牌游戏或三合一游戏。 隐形系统!
当然,任何自尊的隐形系统都应该能够考虑到玩家周围环境的光照。 我惊讶地发现了这个话题,发现异常少量的信息。 因此,我赶紧分享成果。
今天,我们将不为玩家开发完整的隐形系统,我们仅考虑与照明的交互。
方法1:撞机
一种简单但不是很耗资源的方法。
我们向每个光源添加一个球形对撞机。 我们使其成为触发器。 我们将尺寸设置为大约等于光的半径。
其余的就像阴影一样清晰。 我们正在编写一个简单的脚本,在该脚本中,我们在OnTriggerEnter()中激活灯光计算功能(这样,当玩家不在附近时,光源就不会“空转”)。
照度计算本身将位于Update()中。 本质上,这是通常的Physics.Raycast()。 如果它击中了播放器,则该播放器处于亮区。 如果它没有掉落,则表示玩家在障碍物后面,因此在阴影中。
您还可以在此处添加播放器和光源之间距离的计算。 因此,为了确定照度,我们将使用一个简单的浮标,该浮标将根据距光源的距离而变化。 而且,您可以随时随地使用它。
例子
在点1,照明接近最大值。 在第2点,光照很小-在该点和该点之间有障碍物。 在点3,照度是平均的。 不仅如此! 您可以将触发对撞机添加到玩家必须隐藏的各个“阴影区域”。 遵循Manhunt的最佳传统。 同样,您可以使用对撞机标记亮区,例如模拟聚光灯。
优点:
- 易于定制点光源。
- 如果您不发送垃圾邮件,则在资源方面非常经济。
缺点:
- 对聚光灯和定向光进行了严格的调整。 如果第一种情况足以将对撞机放置在光场中(以增加玩家在入口处的能见度),那么第二种情况确实令人恐惧。 您需要在每个阴影处放置对撞机(以减少玩家在入口处的可见性),或使用Physics.Raycast()不断检查玩家与“太阳”之间的位置-它位于光线下方或阴影中。
- 大量的对撞机使场景变得混乱,使物理复杂化。
- 必须注意相交的光源。
- 需要通过脚本分别添加动态光(移动或改变强度)。
方法2:RenderTexture
我们在这里做什么? 实际上,我们从摄像机(而不是从主摄像机)获得“屏幕快照”。 然后,我们分析屏幕截图的颜色,以找出明亮的光线如何照射到主体上。
首先,我们需要一个从中“读取”光线的对象。 创建一个常规球体或平面,使其变小(比例尺为0.1),将其放置在靠近地面的位置,使其变白,然后移除对撞机:
添加一个摄像头(确保删除音频侦听器并检查MainCamera标签是否值得)。 将其绑定到我们的对象。 我们将其放高一点,然后将其放低。 我们在设置中不显示主屏幕。 正字法照您的口味。
最后,我们将其放置在适当的位置,以便仅查看对象。
最后,配置主摄像机和辅助摄像机的消隐遮罩,以使主摄像机不显示我们的“亮”对象,而辅助摄像机仅看到它们,而不会弄乱其他任何东西。
从这里开始乐趣。 我们将脚本附加到相机:
public Camera cam; // RenderTexture tex; Texture2D _tex; void Start () { // "". // , - . // Depth 0 - . tex = new RenderTexture (1, 1, 8); // RenderTexture "" , // , . _tex = new Texture2D (1, 1, TextureFormat.RGB24, false); } void Update () { // "" cam.targetTexture = tex; cam.Render (); // RenderTexture.active = tex; // Texture2D _tex.ReadPixels (new Rect (0, 0, 1, 1), 0, 0); _tex.Apply (); Color col = _tex.GetPixel (0, 0); float vis = (col.r + col.g + col.b) / 3; }
在输出中,我们得到一个浮动的vis,从本质上讲,它是入射在我们物体上的照明水平的数字表示。 如果源关闭-对象为白色-可见为1。如果源为暗-对象为黑色-可见为〜0。
我们不需要每一帧都执行上述操作,因此我们嵌入了一个小的第二个计时器:
float interval = 0; void Update () { interval += Time.deltaTime; if (interval < 1) return; interval = 0; // }
接下来,我们将整个系统绑定到玩家,以便它随他一起移动。 并且我们的vis变量会自动在播放器周围返回光!
该系统不仅可以与播放器一起使用。 您可以将其放置在任何位置,并根据需要创建一种光传感器。 通常,有更有效的方法来实现它们,但是拥有替代方法总是很好吗?
优点是显而易见的,让我们谈谈缺点。
缺点
- 每个“光检测器”(如果有多个)都需要一个单独的摄像头。
- Texture2D.ReadPixels()-很好,非常慢。 即使您每秒执行一次,而不是每隔一帧一次,即使您破坏了将纹理写入和读取到不同帧中的功能,仍然存在40-110ms的布局。
- 该系统未考虑一些罕见情况。 例如,手电筒照在角色上。 角色光线很好,但是光线分别照射到他和他的身后,而不是落下,我们的光检测器显示出低照度。 您可以解决问题,例如,通过将探测器不放在地板上,而是放置在角色胸部的水平上。 然后,您需要将两个摄像头放在相对的两侧以读取任一侧的光。 什么会使系统速度减半。