- Home /
True Cone of Sight? Commandos
Hi everyone!
I would like to know if anyone ever tried to simulate FOV (from Commandos game, picture below) in Unity to work with different height variations. I discovered that this is really hard task to accomplish. I tried Projectors, raycasting and all other methods found on internet but it was always not what i was looking for.
Projectors can be a good solution, but:
1. I need shader which allow me to render cone texture only on top faces of other objects (Picture below represents bad projector)
2. Projector should not draw texture through walls, buildings etc. I know i can use layers to block rendering the cone on the second wall, but depends to enemy position it's important to render cone on all objects.
Can anyone give me an idea or solution how can i achieve this type of FOV rendering?
Thanks!
Answer by JacobDzwinel · Dec 08, 2016 at 10:36 PM
To everyone wondering how I finally achieved nice effect of true cone of sight, I found this https://github.com/joscanper/unity_coneofsightfx
I hope this will help you :)
If you are looking for rendering projector texture on top of the objects you should definetly check rageingnonsense post below. He led me to write a good shader that actually works. You can check final results in the picture i posted in comment.
Thanks!
Hi @JacobDzwinel,
Did you manage to make it work as expected? I'm facing the same problem...
Thanks!
Hi Nicolas, Unfortunately I did not manage to make it work... I was looking recently at your posts on unity forum and i wanted to ask you the same question ;) You were really close to achieve final effect :)
Did you manage to make it work?
Hi Jacob,
Yes I actually managed to find a solution. Feel free to ping me if you want to discuss about it.
Cheers,
It would be benefitial for the community, if you just discussed your solution here, ins$$anonymous$$sd of in private.
@Nicolas-Liatti Hello,Can you share it?? I have same problem.
Answer by rageingnonsense · Apr 15, 2015 at 06:56 PM
What is the code for the shader you are using for the projector? This is actually not very hard to accomplish in shader code. If you could post the code of the shader, I could help you more exactly, but...
What you want to do is add a check to see how "vertical" a surface is, and not alter the color if it is too vertical. Here is some psuedo shader code to demonstrate this:
// assuming Y is up
half3 up = half3(0,1,0);
if(dot(normal, up) == 1) {
// this is a flat floor surface, adjust color
}
That is just a general idea. Odds are it will never be exactly 1 (or might be 0, I forget what the value of a dot product of two matching directions is), so you will need to test for a range.
General idea though is to run a test on the dot product of the normal of the vertex against the world up normal.
EDIT:
I see. ok, first we need to get the normal data:
make a new struct:
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
}
modify the existing struct:
struct v2f {
float4 uvShadow : TEXCOORD0;
float4 uvFalloff : TEXCOORD1;
float4 pos : SV_POSITION;
float3 norm : NORMAL;
};
Now to modify our vertex function:
v2f vert (appdata i)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, i.vertex);
o.uvShadow = mul (_Projector, i.vertex);
o.uvFalloff = mul (_ProjectorClip, i.vertex);
o.normal = i.normal;
return o;
}
Now our fragment function should have a normal to work with. Now try doing this:
fixed4 frag (v2f i) : SV_Target
{
fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
texS.a = 1.0-texS.a;
fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
fixed4 res;
// assume Y is up
if(dot(i.normal, float3(0,1,0)) >= 0.9) {
res = lerp(fixed4(1,1,1,0), texS, texF.a);
} else {
res = texS;
}
return res;
}
For the if statement, you may need to play with that 0.9 value. It is going to be a value between -1 and 1; but I forget what the value will be when the normal and the up vector are the same (or close to it).
This is by no means a complete solution (or maybe it is? I did not test it), but it should help to point you in the right direction. The main points to take are this:
You need to get normal information to your frag function
you need to compare the dot product of the normal to the world up vector to figure out how vertical a face is.
I am also unsure what texS and texF contain at this point of the shader. I'm assuming texS is the shaded texture BEFORE the projection is applied, but I could be wrong.
This link should help a bit as well, as it explains inputs to vertex/fragment shaders:
Thanks @rageingnonsense!
I'm using $$anonymous$$ultiply shader for Projectors found in Unity Standard Assets.
$$anonymous$$y knowledge in writing shaders is very limited. Can you help me figure out how to achieve effects i described?
The image you posted shows that perhaps what they are doing is creating a cone mesh, then finding the points where it intersects with terrain poly faces that look upwards and create a new mesh to place on top of them.
Similar to what a decal system would do.
I exa$$anonymous$$ed your script and play with it for a while. Here is my result
It looks really good, but i still can't figure out how to deal with my second problem? Do you think it's possible to modify this shader to work with collision on specific objects on map (Like in the picture below)
..or it is different problem i need to deal with?
I found this video https://www.youtube.com/watch?v=FdwdkVB36dQ
His solution looks interesting.
I was thinking also about @screenname_taken sugestion. He's idea of creating a new mesh could solve collision problems. JEEZ, i would love to know how developers from PyroStudios achieved this type of FOV effect.
I'm glad the first part worked! I was afraid I was being too vague, but nice!
As far as your second problem, I am not too sure unfortunately. That is where my knowledge ends.
You could try to make an occlusion texture that you send to the material whenever the character position changes, and then reference this to see if you should render the code here (if pixel is black, don't render, otherwise render), but I am not sure if that is the best solution; might be slow.
Your answer
Follow this Question
Related Questions
Blackout 3D Cone of vision/Line of sight 0 Answers
RayCast2D not returning values as expected 0 Answers
AI raycasting problem 0 Answers
Vision cone with obstacles? 2 Answers
AI detection script problem 0 Answers