简体   繁体   English

在Unity中的运行时更新着色器

[英]Update Shader on Runtime in Unity

I have an object which has a diffuse shader and on runtime I want the shader to switch to Diffuse Always Visible but this should trigger only if the unit is behind a specific object within the layer named obstacles. 我有一个具有漫射着色器的对象,并且在运行时我希望该着色器切换为“始终可见的漫射”,但这仅在单元位于名为障碍的图层中的特定对象后面时才应触发。

First I tried to switch the object shader with the following code and the shader is changed in the inspector but not in the game during play. 首先,我尝试使用以下代码切换对象着色器,​​并且在播放过程中在检查器中更改了着色器,但在游戏中未进行更改。 I tried placing and calling the shader from the resources and also created seprate materials but its not working. 我尝试从资源中放置和调用着色器,还创建了单独的材质,但是它不起作用。

Here is the code I am using in C# 这是我在C#中使用的代码

Unit.renderer.material.shader = Shader.Find("Diffuse - Always visible");

As for the rest I was thinking of using a raycast but not sure how to handle this. 至于其余的,我正在考虑使用光线投射,但不确定如何处理。

Thanks in advance 提前致谢

I only need the other concept now where the shader changes if a unit is behind an object! 现在,我只需要另一个概念,即如果某个单位在对象后面,则着色器会发生变化!

For the trigger, how to handle it will depend a lot on how your camera moves. 对于触发器,如何处理触发器将在很大程度上取决于相机的移动方式。

To check in a 3D game , raycasts should work. 要检入3D游戏 ,应进行射线广播。 Because whether or not something is "behind" something else depends on the camera's perspective, I would personally try something like this to start: 因为是否有其他东西取决于相机的角度,所以我个人将尝试以下操作:

  1. Use Camera.WorldToScreenPoint to figure out where your object is on the screen. 使用Camera.WorldToScreenPoint找出对象在屏幕上的位置。
  2. Use Camera.ScreenPointToRay to convert this into a ray you'll send through the physics engine. 使用Camera.ScreenPointToRay将其转换为将通过物理引擎发送的射线。
  3. Use Physics.Raycast and check what gets hit. 使用Physics.Raycast并检查遇到了什么。 If it doesn't hit the object in question, something is in front of it. 如果它没有撞到有问题的物体,则它前面有东西。

Depending on your goals, you might want to check different points. 根据您的目标,您可能需要检查不同的点。 If you're just checking if something is more than halfway covered by an object, doing a single raycast at its center is probably sufficient. 如果您只是检查某物体是否覆盖了物体的一半以上,则在其中心进行一次射线投射可能就足够了。 If you want to see if it's at all occluded, you could try something like finding four approximate corners of the object and raycasting against them. 如果要查看它是否完全被遮挡,可以尝试执行以下操作,例如找到对象的四个近似角并对其进行光线投射。

If it's a 2D game or the camera is always at a fixed angle (for example, in a side scroller), the problem is potentially a lot simpler. 如果是2D游戏,或者相机始终处于固定角度(例如,在侧面滚动条中),则问题可能会简单得多。 Add colliders to the objects, and use OnTriggerEnter or OnTriggerEnter2D (along with the corresponding Exit functions). 将碰撞器添加到对象,然后使用OnTriggerEnterOnTriggerEnter2D (以及相应的Exit函数)。 That only works if the tiniest bit of overlap should trigger the effect, and it only works if depth doesn't really matter (eg in a 2D game) so your colliders will actually intersect. 这仅在最微小的重叠触发效果时才有效,并且仅在深度真的不重要时才有效(例如在2D游戏中),因此对撞机实际上会相交。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM