Field of view visualisation (E02)

  Рет қаралды 161,412

Sebastian Lague

Sebastian Lague

Күн бұрын

Пікірлер: 265
@Pixelith
@Pixelith 6 жыл бұрын
I can't believe something like this isn't behind a paywall. Fantastic work!
@SebastianLague
@SebastianLague 9 жыл бұрын
Episode two - creating the FOV visualisation. Let me know if there's anything more you'd like to see from this series. Hope you enjoy :) You can support my videos on patreon over here: bit.ly/sebPatreon
@leloctai
@leloctai 9 жыл бұрын
That would be very cool if you add a stencil buffer shader, you can make everything unseen by the character invisible.
@SebastianLague
@SebastianLague 9 жыл бұрын
+Lê Tài Good idea, I'll experiment with that.
@Mikekan13
@Mikekan13 9 жыл бұрын
+Sebastian Lague omg if you can make it so everything is black when the character can't see it It would be amazing!!!!!!!!
@SebastianLague
@SebastianLague 9 жыл бұрын
+Michael Kantack I've got it working, will upload an episode on it later :)
@Mikekan13
@Mikekan13 9 жыл бұрын
+Sebastian Lague Then you sir are my hero.
@Mixtrate
@Mixtrate 9 жыл бұрын
I love these small supplement type tutorials. They go over some great math and good programming for a rapid prototype of a system. Awesome to follow along then tinker and learn from the entire process.
@BlackoutGamingChannel
@BlackoutGamingChannel 2 жыл бұрын
I started learning unity 6 years ago. You were the person who taught me how to code. I still find myself coming back time and time again just to watch your videos either because I remembered you doing a specific thing or just because I really enjoy watching them. I just want you to know how much I've appreciated your content over the years.
@asliniarayanadam
@asliniarayanadam 2 жыл бұрын
After 7 years this video can be still helpful as its very first day. You are great Sebastian! Thanks a lot!
@connorheyz9230
@connorheyz9230 3 жыл бұрын
Sebastian, just know how many future game designers you are helping to foster with these fantastic tutorials. What a blessing you are
@NFMynster
@NFMynster 9 жыл бұрын
Great tutorials man, I can't believe how much work you put into each tutorial. Really great job man, I'm really hoping the best for you!
@SebastianLague
@SebastianLague 9 жыл бұрын
+NFMynster Thank you!
@prod.jakekarno1765
@prod.jakekarno1765 2 жыл бұрын
FULL 2D script Converting these scripts to 2D for Unity 2021 was an absolute nightmare. Other people have already shared scripts but none of them seemed to work for me entirely. So here are both the scripts, converted to 2D, with a rotation variable added so that you can choose which direction it faces in if you need that and a bool targetAquired to use for enemy actions. Hope it helps. FIELD OF VIEW SCRIPT ( I renamed mine to FOV) public class FOV : MonoBehaviour { public float viewRadius; [Range(0,360)] public float viewAngle; [Range(0,360)] public float fovRotation; public LayerMask targetMask; public LayerMask obstacleMask; ///[HideInInspector] public List visibleTargets = new List(); public float meshResolution; public int edgeResolveIterations; public float edgeDstThreshold; public MeshFilter viewMeshFilter; private Mesh viewMesh; public bool targetAquired = false; void Start() { viewMesh = new Mesh (); viewMesh.name = "View Mesh"; viewMeshFilter.mesh = viewMesh; StartCoroutine ("FindTargetsWithDelay", .2f); } IEnumerator FindTargetsWithDelay(float delay) { while (true) { yield return new WaitForSeconds (delay); FindVisibleTargets (); } } void LateUpdate() { DrawFieldOfView(); } void FindVisibleTargets() { visibleTargets.Clear (); targetAquired = false; Collider2D[] targetsInViewRadius = Physics2D.OverlapCircleAll (new Vector2(transform.position.x, transform.position.y), viewRadius, targetMask); for (int i = 0; i < targetsInViewRadius.Length; i++) { Transform target = targetsInViewRadius [i].transform; Vector2 dirToTarget = (target.position - transform.position).normalized; if (Vector2.Angle(new Vector2(Mathf.Sin(fovRotation * Mathf.Deg2Rad), Mathf.Cos(fovRotation * Mathf.Deg2Rad)), dirToTarget) < viewAngle / 2) { float dstToTarget = Vector3.Distance (transform.position, target.position); if (!Physics2D.Raycast (transform.position, dirToTarget, dstToTarget, obstacleMask)) { visibleTargets.Add (target); targetAquired = true; } } } } void DrawFieldOfView() { int rayCount = Mathf.RoundToInt(viewAngle * meshResolution); float stepAngleSize = viewAngle / rayCount; List viewPoints = new List(); ViewCastInfo oldViewCast = new ViewCastInfo (); for (int i = 0; i < rayCount; i++) { float angle = fovRotation - viewAngle / 2 + stepAngleSize * i; ViewCastInfo newViewCast = ViewCast(angle); if (i > 0) { bool edgeDstThresholdExceeded = Mathf.Abs(oldViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDstThresholdExceeded)) { EdgeInfo edge = FindEdge(oldViewCast, newViewCast); if (edge.pointA != Vector3.zero) { viewPoints.Add(edge.pointA); } if (edge.pointB != Vector3.zero) { viewPoints.Add(edge.pointB); } } } viewPoints.Add(newViewCast.point); oldViewCast = newViewCast; } int vertexCount = viewPoints.Count + 1; Vector3[] vertices = new Vector3[vertexCount]; int[] triangles = new int[(vertexCount -2) * 3]; vertices[0] = Vector3.zero; for (int i = 0; i < vertexCount - 1; i++) { vertices[i + 1] = transform.InverseTransformPoint(viewPoints [i]); if (i < vertexCount - 2) { triangles[i * 3] = 0; triangles[i * 3 + 1] = i + 1; triangles[i * 3 + 2] = i + 2; } } viewMesh.Clear (); viewMesh.vertices = vertices; viewMesh.triangles = triangles; viewMesh.RecalculateNormals (); } EdgeInfo FindEdge(ViewCastInfo minViewCast, ViewCastInfo maxViewCast) { float minAngle = minViewCast.angle; float maxAngle = maxViewCast.angle; Vector3 minPoint = Vector3.zero; Vector3 maxPoint = Vector3.zero; for (int i = 0; i < edgeResolveIterations; i++) { float angle = (minAngle + maxAngle) / 2; ViewCastInfo newViewCast = ViewCast (angle); bool edgeDstThresholdExceeded = Mathf.Abs(minViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (newViewCast.hit == minViewCast.hit && !edgeDstThresholdExceeded) { minAngle = angle; minPoint = newViewCast.point; } else { maxAngle = angle; maxPoint = newViewCast.point; } } return new EdgeInfo(minPoint, maxPoint); } ViewCastInfo ViewCast(float globalAngle) { Vector3 dir = DirFromAngle(globalAngle, true); RaycastHit2D hit; hit = Physics2D.Raycast(transform.position,dir, viewRadius, obstacleMask); if (hit.collider!=null) { return new ViewCastInfo(true, hit.point, hit.distance, globalAngle); } else { return new ViewCastInfo(false, transform.position + dir * viewRadius, viewRadius, globalAngle); } } public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal) { if (!angleIsGlobal) { angleInDegrees += fovRotation; } return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), Mathf.Cos(angleInDegrees * Mathf.Deg2Rad), 0); } public struct ViewCastInfo { public bool hit; public Vector3 point; public float dst; public float angle; public ViewCastInfo(bool _hit, Vector3 _point, float _dst, float _angle) { hit = _hit; point = _point; dst = _dst; angle = _angle; } } public struct EdgeInfo { public Vector3 pointA; public Vector3 pointB; public EdgeInfo(Vector3 _pointA, Vector3 _pointB) { pointA = _pointA; pointB = _pointB; } } } EDITOR SCRIPT [CustomEditor (typeof (FOV))] public class FOVEditor : Editor { void OnSceneGUI(){ FOV fow = (FOV)target; Handles.color = Color.white; Handles.DrawWireArc(fow.transform.position, Vector3.forward, Vector3.right, 360, fow.viewRadius); Vector3 viewAngleA = fow.DirFromAngle(-fow.viewAngle / 2, false); Vector3 viewAngleB = fow.DirFromAngle(fow.viewAngle / 2, false); Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleA * fow.viewRadius); Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleB * fow.viewRadius); Handles.color = Color.red; foreach (Transform visibleTarget in fow.visibleTargets) { Handles.DrawLine (fow.transform.position, visibleTarget.position); } } }
@Ir0nma1den
@Ir0nma1den Жыл бұрын
Mate, you're a hero. I was struggling with the same thing!
@prod.jakekarno1765
@prod.jakekarno1765 Жыл бұрын
@@Ir0nma1den Glad I could help, converting it's quite tricky when you're starting out
@LucasJCockburn
@LucasJCockburn Жыл бұрын
Thank You! this is epic
@prod.jakekarno1765
@prod.jakekarno1765 Жыл бұрын
@@LucasJCockburn Np, glad I could help
@BusCaseList
@BusCaseList 9 ай бұрын
The world in the hands of heroes like you!
@susi2622
@susi2622 3 жыл бұрын
even in 6 years after, the quality of the video is utmost. due to the lack of my intellectual comprehension, I can't fully absorb the content. but absolutely helpful video!
@adameisfeld8709
@adameisfeld8709 4 жыл бұрын
I enjoy the style and detail of these videos. You explain the problem and goal first allowing us to think about how we might solve the problem before seeing your solution. I’m a mobile engineer (iOS apps, primarily Swift), I’ve not used Unity yet but I’m glad to see how nicely it plays with custom code, seems very intuitive.
@CodeBlues-TimeisGold
@CodeBlues-TimeisGold 7 жыл бұрын
이런건 돈 내고 학원가야 가르쳐 줄까 말까 할 정도로 퀄리티 상급의 강의네요. 대단하단 말밖에 안 나오네요. 애청자 됐어요 ^^ 알아들을지는 모르지만 .. 최곱니다!!!
@florentmougenotaliasdafthu6227
@florentmougenotaliasdafthu6227 9 жыл бұрын
God a huge thanks from France for this series ! :D I have learn so much from it and I apply a lot of your tips when I'm making games so please don't stop it this soon :) A good learning can be the AI part if your are motivated :p
@quantumcookie64
@quantumcookie64 4 жыл бұрын
17:17 I didn't imagine binary search would come in handy in something like this. Wow
@pureatheistic
@pureatheistic 2 ай бұрын
At around 11:40 when writing the for loop, you dont have to artificially adsust the index count by adding one inside the loop. You can just set i=1 as the start of the for loop. Kinda the whol point of defining the iterating variable in the first place. I know you probably know this by now, but other people might find this bit of info helpful as it's a tutorial aimed at beginners.
@telamontgamedev7652
@telamontgamedev7652 7 жыл бұрын
I have to say, your videos are absolutely excellent, clear voice, perfect pace, never wasting time trying to figure things out, clearly very well prepared. Your skills are also quite remarkable. Have you made any games commercially available? I'd be curious to see what have you come up with.
@AlanAlan-bv9yg
@AlanAlan-bv9yg 3 жыл бұрын
Sebestian is the best of the best Unity teacher in the world !
@scootergem
@scootergem 2 жыл бұрын
at first i was lost, but now i'm beginning to get it. very good stuff. i want more - please... ..sir
@cutsceneentertainment6706
@cutsceneentertainment6706 3 жыл бұрын
FOR US NOOBS - visibleTargets.Count will give you an integer for how many targets are in the field of view. You can use this integer for actually having something happen when when a target is detected. For ex. If visibleTargets.Count >= 1, set off the alarm.
@brendon50049
@brendon50049 4 жыл бұрын
Thank you, this was fantastic. This was also my first time generating a mesh at runtime and you made it incredibly simple.
@Runalotski
@Runalotski 9 жыл бұрын
This was a nice tutorial, I enjoy the one off short tuts on a specific feature or mechanic to play with in-between my own projects, keep up the good work!
@beratcan9437
@beratcan9437 5 жыл бұрын
Awesome tutorial, thank you so much. I implemented this radial raycasting method to my project, it's worked correctly.
@tomtatlichsu2878
@tomtatlichsu2878 7 жыл бұрын
I love this guys so much! he made the best of the best tutorials.
@boncret
@boncret 3 жыл бұрын
Thank you so much, this series was exactly what i were looking for!
@TheBalalaikaVision
@TheBalalaikaVision 8 жыл бұрын
Sebastian Wow, amazing tutorial, everything is explained, I will be using this in my game, excellent work of my friend
@Gonzalo_105
@Gonzalo_105 4 жыл бұрын
thanks, your one of the best unity youtubers out there.
@lDeath489
@lDeath489 9 жыл бұрын
You call that miniseries , evil T_T. This will take me a week to fully understand it lol. Your torture is very lovely and welcomed xP. Thank you so much for doing something very useful. I have a note for you though if you don't mind feedback ...
@SebastianLague
@SebastianLague 9 жыл бұрын
+S Al Always happy to receive feedback!
@lDeath489
@lDeath489 9 жыл бұрын
+Sebastian Lague If you are aiming to teach inexperienced people too then i think you can do it in a better way. If not then no need to read the rest. For example: The moment you want to put a new feature to the script put the main goal without deep details first so that they know why they are doing this then write the code : if (!angleIsGlobal) { angleInDegrees += transform.eulerAngles.y; } [Read the code in an easy way] // if the angle Is not Global then we will convert it to a global angle ( by adding the angle to the transform own rotation ). [Explain why you created it] // This function will set the variable angleIsGlobal to a global angle so that we can make it false when we apply boolean to the editor and that will give us an angle that stays relative to character rotation. You can do this in the video which will make it longer with more work or just write it in a note while you are creating the video and upload it with the files. This will make it very simple to anyone.
@SebastianLague
@SebastianLague 9 жыл бұрын
+S Al Thanks, I will work at this.
@arturoalcibia3989
@arturoalcibia3989 9 жыл бұрын
+Sebastian Lague Great tutorials!! but if you could be able to do this for your scripts would be awesome!! I'm a beginner in this and it's really hard to understand most of these concepts even if I look up for them, but great work!
@ShadyCastKittyKai
@ShadyCastKittyKai 8 жыл бұрын
I would really love if you made a tutorial on how to do a 3d version of this, so it's like a 3d spotlight rather than a flat cone
@Justinjaro
@Justinjaro 4 жыл бұрын
Make a cone 3d object and make it a child of the camera? Nothing really confusing on that one
@HandsOnKnowledge
@HandsOnKnowledge 4 жыл бұрын
This was amazing Sebastian, great work and I did learn a lot from it
@MaltProgrammer
@MaltProgrammer 4 жыл бұрын
Thanks a lot! This is amazing tutorial. I will update my stealth game now!
@gabrielrej834
@gabrielrej834 9 жыл бұрын
There is one technique for more realistic visibility detection, for both 3d and 2d. Namely pick a random point within characters volume (like a vertex of the model), use that as a point you cast a ray to, pick another random point and another one and another etc. If a certain percentage of those rays return true, character is visible. If only a f.e. a hand is visible, there would be no way you'd get detected.
@TheOriginalMomos
@TheOriginalMomos 6 жыл бұрын
Hello, hello! Dunno if you'll see this, but could you give an example on how I'd do that in 2D and maybe 3D? 'cause right now I'm concluding that while the representation of the FOV and all is pretty darn great, the fact that it checks only the very center of the sprite before concluding that it sees it is kinda iffy at best.
@paularbas2444
@paularbas2444 9 жыл бұрын
Amazing. Was waiting for the 2nd part and it didn't disappoint :) thank you for all the hard work. Was also wondering if you ever considered doing a series on character cameras for different game modes? For example a strategy game, which allows you to select units with a drag box. A camera that has the very rough basics of what you see in 3rd person games. Be it mmos, adventure games, over the shoulder and so on. Another series that would be interesting is a mini series on basic programming concepts and optimizations, like object pooling, mesh and material merging and separating between objects of same type, saving/loading system. Maybe more topics on procedural generation, especially when it comes to generating terrain. Heightmap and nonheightmap based generation? Or maybe just play around and explain different noise methods, like perlin noise, voronoi and so on? Well whatever the case, hope to see more interesting topics from you in the near future :)
@ashleytwo
@ashleytwo 8 жыл бұрын
Fantastic series that really has helped, both the scripting side and the general maths/geometry pointers were great. Having problems trying to convert this to 2D. I can get it working to display the Debuged lines (around 3 minutes) but by the time we get to the mesh (15 minutes) it's not working. I can attach a mesh, but rather than clipping around obstacles it's simply not drawing on top of them. If I have a small obstacle the FOV still shows, but it just looks like the FOV is a layer underneath rather than working around it. If that makes sense. If anyone has any suggestions I'd be much obliged!
@MrNathanShow
@MrNathanShow 6 жыл бұрын
I was able to follow along well, just most of the transformations are Vector2 based now. Also, 2D collisions do not work with 3D collisions, 2D is done with Box2D and 3D is done with PhysX (so they are completely different systems). Physics2D is going to be needed to correctly convert this to 2D.
@TheOriginalMomos
@TheOriginalMomos 6 жыл бұрын
Hello, hello! Got a question for you: By "most of the transformations are Vector2 based now", do you mean stuff like transformation.position? Right now what I'm struggling with is to get the required infos out for the Physics2D.Raycast.
@thatcreepyguyinthecorner3364
@thatcreepyguyinthecorner3364 5 жыл бұрын
To make it work in 2d just replace RaycastHit2D hit; if (Physics2D.Raycast(transform.position, dir, hit, viewRadius, SightBlocker)) { return new ViewCastInfo(true, hit.point, hit.distance, globalAngle); } else { return new ViewCastInfo(false, transform.position + dir * viewRadius, viewRadius, globalAngle); } With RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(dir.x, dir.y), viewRadius, SightBlocker); if (hit != null && hit.collider != null) { return new ViewCastInfo(true, hit.point, hit.distance, globalAngle); } else { return new ViewCastInfo(false, transform.position + dir * viewRadius, viewRadius, globalAngle); } Hope That Helps!
@ToastandBananas
@ToastandBananas 4 жыл бұрын
@@thatcreepyguyinthecorner3364 My saviour!
@ForgottenMovieGems
@ForgottenMovieGems 5 жыл бұрын
This is incredibly helpful for a university project that I'm working on! You may have just saved my butt :P
@cedricodigital
@cedricodigital 9 жыл бұрын
Incredible material, as usual ;-) Bravo!
@nickngafook
@nickngafook 9 жыл бұрын
Amazing tutorial series! Thanks for the hard work
@123dgriffin
@123dgriffin 2 ай бұрын
This is amazing work. Curious if you have any content to handle this same type of thing but with uneven terrain
@keithtai7945
@keithtai7945 5 жыл бұрын
Great tutorial! May I know how you turn those blue capsule to red when it get detected?
@casvanmarcel
@casvanmarcel 9 жыл бұрын
Fantastic work Sebastian
@gotbaka3
@gotbaka3 Жыл бұрын
Amazing, you are a life saver
@stefan429
@stefan429 4 жыл бұрын
i really appreciate all the explanations, i sort of understand all this! :D
@Elledan3101
@Elledan3101 6 жыл бұрын
Great material. thank you so much! :)
@Secretlycat31
@Secretlycat31 3 жыл бұрын
This helped so much. Thank you very much
@mAeX135
@mAeX135 3 жыл бұрын
I LOVE YOU FOR THIS TUTORIAL!
@永泽秦
@永泽秦 Жыл бұрын
very nice work man
@ronnieth3bear
@ronnieth3bear 8 жыл бұрын
This is a fantastic tutorial. Thank you so much!
@bytestream64
@bytestream64 9 жыл бұрын
Gread mini series. One question though: How does this react to rather small obstacles? Wouldn't it simply ignore them if they are small enough to completely fit between two rays?
@flat6_music
@flat6_music 8 жыл бұрын
Although your comment is ten menths old, look at this: ncase.me/sight-and-light/ Basically you cast a ray to the edges of the Object and then cast two additional rays, wich are rotatet by a tiny amount so that they hit the wall or whatever behind the edge. You can find this explained a little bit better when you look at the link I just gave you :)
@Psyhogenesis
@Psyhogenesis 6 жыл бұрын
Thank you very much, sir, for your tutorial.
@johncruel4564
@johncruel4564 8 жыл бұрын
thank you for making this very good tutorial.
@timadams1662
@timadams1662 3 жыл бұрын
I was messing around after completing the tutorial and polishing/optimizing more and I found a piece of functionality that I wanted in and figured it out. When the ViewAnglew is set to 360 there was always a small gap in the back of the view. Now this could be because I calculated things wrong or just by design, but I wanted to support the 360 view. Here's the code for it: ============================================ int vertexCount = viewPoints.Count + 1; Vector3[] vertices = new Vector3[vertexCount]; int triangleCount = (vertexCount - 2) * 3; if (viewAngle == 360) { triangleCount += 3; } int[] triangles = new int[triangleCount]; vertices[0] = Vector3.zero; for (int i = 0; i < vertexCount-1; i++) { vertices[i + 1] = transform.InverseTransformPoint(viewPoints[i]); if (i < vertexCount - 2) { triangles[i * 3] = 0; triangles[i * 3 + 1] = i + 1; triangles[i * 3 + 2] = i + 2; } } if (viewAngle == 360) { triangles[(vertexCount - 1) * 3 - 3] = 0; triangles[(vertexCount - 1) * 3 - 2] = vertexCount - 1; triangles[(vertexCount - 1) * 3 - 1] = 1; } ============================================ Starting where you calculate the VertextCount and all the way till before you RecalculateNormals this adds 3 to the triangleCount if the viewAngle is 360. Because we need to add 3 more points for a triangle into it. After the for loop we have to use different functionality for the indices of the last triangle. Instead of increasing by 1 and 2 at an index we start from the end and count backwards. Using the center point for the first slot (as always), the vertexCount-1 (the Length) for the second, and 1 for the last as we're reconnecting to the first index always. I hope this helps anyone who was figuring this out to get trucking and find the answer/just copy paste :P
@elronman
@elronman 4 жыл бұрын
Accidentally had my viewvisualization mesh scaled to 2 for some reason. Spent like an hour trying to figure out what was doubling it in the script.
@eggsscramblerzz4711
@eggsscramblerzz4711 6 жыл бұрын
this coding is so satisfying to watch (y)
@cschott
@cschott 9 жыл бұрын
Great work! The effekt looks damn nice :D And happy new year! ( nearly there ;) )
@SebastianLague
@SebastianLague 9 жыл бұрын
+Mr3D Thanks, happy new year :D
@Catequil
@Catequil 4 жыл бұрын
I wonder whether the edge detection could be solved by drawing a line from the impact point alongside the normal of the impacted object, until it exists the object. This could reduce the ammount of rays, but idk whether the calculation would be much lighter in the grand scheme of things, as it would be difficult with spheres etc.
@sadekmaghzili2748
@sadekmaghzili2748 8 жыл бұрын
How I can make a condition when the player see the target please ?
@romeogaming6424
@romeogaming6424 3 жыл бұрын
EXCELENT, thank you very much!
@PS3centere
@PS3centere 9 жыл бұрын
love the new diagrams
@doshirts-7701
@doshirts-7701 8 жыл бұрын
HOW TO DO IF IN VISIBLE SECTOR, for example to change the color of the object ?
@MrBalinSuperTV
@MrBalinSuperTV 4 жыл бұрын
Bug fix: public Vector3 DirectionFromAngle(float angleInDegrees, bool angleIsGlobal) { if (angleIsGlobal) angleInDegrees += transform.localRotation.eulerAngles.y; return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), 0, Mathf.Cos(angleInDegrees * Mathf.Deg2Rad)); } Where need to get LOCAL rotation euler angle for Y.
@cyco3oy
@cyco3oy 8 жыл бұрын
Keeping performance in mind, can i run this attached to 20 or more enemies?
@daveroydun11
@daveroydun11 8 жыл бұрын
Impressive presentation. and it works! Still trying to figure out how you can type and speak so effortlessly without losing your train of thought or having to backtrack your explanation!
@SebastianLague
@SebastianLague 8 жыл бұрын
+Dave Dunbar Movie magic!
@86lufe
@86lufe 3 жыл бұрын
damn, man... you are too good.
@omniges
@omniges 2 жыл бұрын
is createEmptyChild() a method of disfunctionalHousehold() ?
@Aaaalfaroeo
@Aaaalfaroeo 4 жыл бұрын
How can I convert if (Physics.Raycast(transform.position, dir, out hit, Radius, obstacleMask)) to Physics2D?
@Slymp0
@Slymp0 4 жыл бұрын
There is a Physics2D.Raycast() equivalent
@igortelepenko2572
@igortelepenko2572 3 жыл бұрын
this is how I've done this: ViewCastInfo ViewCast(float globAngle) { Vector3 dir = DirFromAngle(globAngle, true); RaycastHit2D hit = Physics2D.Raycast(transform.position,dir, viewRadius, obstacleMask); if (hit!=null && hit.collider!=null) { return new ViewCastInfo(true, hit.point, hit.distance, globAngle); } else { return new ViewCastInfo(false, transform.position + dir * viewRadius, viewRadius, globAngle); } }
@perendi5583
@perendi5583 8 жыл бұрын
Great tutorial, thanks alot!
@lachee3055
@lachee3055 7 жыл бұрын
some could argue that the edge problem is really just..... a edge case *ba dum tish*...... I will walk myself out.
@glorkeShprork
@glorkeShprork 3 жыл бұрын
I've watched to 15:24 and my view cone goes through obstacles, where did I go wrong?
@wilcorelow
@wilcorelow 2 жыл бұрын
Maybe your obstacles are not quite on the ground and the view cone is passing under them.
@glorkeShprork
@glorkeShprork 2 жыл бұрын
@@wilcorelow Thanks Man!
@akmaludddin9281
@akmaludddin9281 Жыл бұрын
i Hope i found this sooner :( 2023 now and finally i found this video
@rodolforubens
@rodolforubens 9 жыл бұрын
This is amazing, thank you!
@jthespacec
@jthespacec 9 жыл бұрын
Awesome, dude. Thanks
@anonyanony7469
@anonyanony7469 6 жыл бұрын
Love your vids.
@Blacksoul444
@Blacksoul444 5 жыл бұрын
Nice Tutorial man, thanks! Wouldn't it be more performant and smoother to save the vertices of the obstacles and construct a triangulated mesh incorporating the exact vertices? That way you wouldn't have to guess where to find the edge of an obstacle in view and would not have to deal with the jitter. Of course, it would require a little preliminary work, like adding 2D-Colliders to the obstacles and taking their vertices.
@Blacksoul444
@Blacksoul444 5 жыл бұрын
@Luc Bloom You're right.
@lightswitch2622
@lightswitch2622 2 жыл бұрын
what if there is many objec
@jakubkadlec4285
@jakubkadlec4285 4 жыл бұрын
Very nice tutorial, that's right .. but I'm little bit struggling in how to work with visible targets. I have this field of view script on enemy and whenever the player is in fov of enemy, the enemy should look at player.. But he don't want to look at him. I tried everything..write it in FieldOfViewEditor script where red line is created, i tried to call it from another script but nothing work .. would it be possible to explain how it's done ..? i would be really grateful
@drakis50
@drakis50 7 жыл бұрын
This is awesome! Thanks to you I can finally continue with a project that me and couple friends are doing, we really needed this field of view. Any tip of how to convert this to a spherical Field of View?
@andresmicalizzi5420
@andresmicalizzi5420 4 жыл бұрын
Awesome tutorial. Haven't tried it yet, but how does it perform? Considering it's creating meshes each frame. Isnt it a resource hog?
@Hukhaa
@Hukhaa 6 жыл бұрын
How to translate this script to a 2D view? i cant create the mesh on YX axis.
@Milfofin
@Milfofin 4 жыл бұрын
This worked for me: In the DirFromAngle function, check the line starting with return new Vector3, and see to it that (Mathf.Sin[...], 0, Mathf.Cos[...]) are changed to (Mathf.Sin[...], Mathf.Cos[...], 0), i.e. that the X and Y is populated.
@indoxperia
@indoxperia 8 жыл бұрын
Hope the best for you to make a lot of tutorial.
@MattTaylorMotion
@MattTaylorMotion Жыл бұрын
Hey Sebastian, This is incredible. Thank you so much for getting this out. There is a case that your mesh refinement step doesn't solve for, which is when two subsequent rays hit two different obsticles at different depths. I attemped to use the distance between the end points of the rays, instead of rays 'hit' boolean, and that works, but this solution tends to cause problems on very steep collisions. I've been struggling for a day to come up with a solution but no luck. I know this is a super old video, but I wonder if you have any insight for this particular case. Thanks again.
@ornithorink
@ornithorink Жыл бұрын
Hello I'm in the exact same situation for my project, have you found a solution?
@nickstavrou2693
@nickstavrou2693 8 жыл бұрын
Excellent tut man genius! Is there a way to UV planar map that mesh filter so i can apply a round texture to it and give a falloff effect using additive material?
@paranormalgamesstudios
@paranormalgamesstudios 8 жыл бұрын
Awesome work! How could i make the shader have a falloff? How could i make the furthest vert alpha transparent?? thanks
@gamedevmonkey6763
@gamedevmonkey6763 4 жыл бұрын
Can I use this without the mesh aspect and can height be added to this? i.e. a thickness in height or perhaps up and down angles? For detecting things at knee level and things at head level? Without the mesh aspect can I strip out the mesh construction stuff?
@ulgmail
@ulgmail 7 жыл бұрын
Hi, I really love your tutorials - great job! If you have a free minute, maybe you could at least have a quick look on a question I have regarding a movement area/circe. I want to draw a circle on a terrain like the circle you are drawing in the video above, but as a terrain might not be flat I'm struggling a bit with how to achieve this. I already implemented 2 approaches, but I'm not happy with both of them and wanted to ask you if you have an opinion or maybe a hint what I could/should do. My first attempt was to create custom meshes in a circle around my character and with raycasting I placed the vertices right above the terrain, even on non flat places - it works, but in my opinion it doesn't look good. My second attempt was to use a projector to project a circle around my character which has the size equivalent to the character's actionpoints - this works too, but then I have the problem that I cannot modify the circle if there is some obstacle in the way.... did you ever implement such a thing? As mentioned, if you have some free minute, any hint or help would be greatly appreciated!!
@mateuszbiaas1559
@mateuszbiaas1559 6 жыл бұрын
How I can add texture for cone field ? Like Shadow tactic,commandos etc.
@Shringyshrong
@Shringyshrong 4 жыл бұрын
Hey! Can someone help? For some reason using the "Fade" option in the shader for the View Visualisation Material just does not work and makes it disapear. On both the "Opaque" and "Cutout" options of this shader it works, although I can not make it transparent at all. Would anyone happen to know why this is happening?
@AletseDev
@AletseDev 2 жыл бұрын
How change where is the field of view? i need the cone on the head of my character but it is on ground, how im put a offset to put on reight place?
@RyanJhider
@RyanJhider 3 жыл бұрын
Some body know how to Make it compatible with multiplayer using Mirror ?
@leopripos
@leopripos 8 жыл бұрын
Hello +Sebastian Lague I have a problem to add mesh collider to the field of view. could you please explain about it? thanks before
@PaycoTsunami
@PaycoTsunami 5 жыл бұрын
add a meshfilter as well as the meshrenderer to the "View Visualization" I know its 2 years later but helps anyone who needs it
@--------------------------..
@--------------------------.. 9 жыл бұрын
The last bug when two consecutive viewcasts hit is still not fixed. As I understand it, viewcast.dst is just the distance to the hitpoints. Two different obstacles can of course be set up to be the same distance to you, and you would not refine your viewcasts.
@JulienCroain
@JulienCroain 9 жыл бұрын
+/ / I think you have right. We could test the collider return by the RayCastHit to know if they are different. What do you think +Sebastian Lague
@slurpleslixie
@slurpleslixie 4 жыл бұрын
Did Unity at the time not allow Vertices/Triangles of a mesh to be created with a List? Or was there some other reason to manually construct Arrays for them?
@Somiaz
@Somiaz 3 жыл бұрын
For some reason FindEdge is coming up with an error that 'not all code paths return a value'. Also, the i++ in the FindEdge for loop has an error of 'unreachable code detected'. Anyone know what could be wrong? Also, because this is happening, I can't enter playmode in Unity.
@kermitfroggers4879
@kermitfroggers4879 2 жыл бұрын
I have 2 problems with guards being able to see my player: 1) I found out by accident if the player is close enough to the enemy, he won't be seen by the enemy when standing in their field of view. I have to walk almost near the edge of the FOV's radius for the enemy to see me. 2) The second problem is enemies can only see my player if the FOV's angle high enough (at least 80 degrees). Any lower and my player won't be seen by the enemy even when I stand inside the enemy's FOV viewcone. How do I fix these 2 problems?
@MrBalinSuperTV
@MrBalinSuperTV 4 жыл бұрын
Mesh won't show if smaller than 3 degrees. Is there a way we can fix?
@abnejne4737
@abnejne4737 7 жыл бұрын
Great video, but if one would like to make this kind of field of view in "3d" meaning in a way so that the visualisation could also handle hight differences. How could that be done? I have been thinking about this for a while, but the solutions i come up with would use so many raycasts, that I think that there has to be a better and smarter way.
@mchristensen5683
@mchristensen5683 7 жыл бұрын
I know that this is an old video, but i'm having trouble using the ViewCastInfo strut. My method declared inside the struct is not working and writing: "Method must have a return type" even though i've written it exactly as in the video?
@paul_lifemademe
@paul_lifemademe 6 жыл бұрын
hello, If I want to bool to return true on the fov script, whenever a target is spotted, please how would I do this. thanks...
@shurikend
@shurikend 8 жыл бұрын
If we add a 2nd player in local mode with the same script, is there some interferences issue between the 2 field of view ?
@oreonengine9444
@oreonengine9444 8 жыл бұрын
great job man!
@NFMynster
@NFMynster 9 жыл бұрын
Hello again man, how (and where) would I detect what's in the view cone? Such as enemies as you have done.
@mukining0150
@mukining0150 2 жыл бұрын
My modernized and complete version of both scripts for 2D games if anybody is interested or having some trouble. Note: In my script, I didn't use view Radius as I wanted mine to exceed everywhere. So if you want to copy this script you will have to Add the edge radius float back in, change the Mathf.Infinity back to the edge radius variable and change the max range back to [0, 360]. This also won't work for 3D games as the changes I have made work only in 2D. The changes aren't too drastic so if you want to use 3D and are really struggling I suppose you could just look in the Field of View Script for all the components I have changed, mainly just some formatting and the added 'Physics2D' here and there. Enjoy! :) Field of View Script - Script 1 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; [ExecuteInEditMode] public class FieldOfView : MonoBehaviour { [Range(0, 361)] public float viewAngle; public LayerMask targetMask; public LayerMask obstacleMask; public List visibleTargets = new List(); public float meshResolution; public int edgeResolveIterations; public float edgeDstThreshold; public MeshFilter viewMeshFilter; Mesh viewMesh; private void Start() { viewMesh = new Mesh(); viewMesh.name = "View Mesh"; viewMeshFilter.mesh = viewMesh; StartCoroutine("FindTargetsWithDelay", .2f); } IEnumerator FindTargetsWithDelay(float delay) { while (true) { yield return new WaitForSeconds(delay); FindVisibleTargets(); } } private void LateUpdate() { DrawFieldOfView(); } void FindVisibleTargets() { visibleTargets.Clear(); Collider2D[] targetsInViewradius = Physics2D.OverlapCircleAll(transform.position, Mathf.Infinity, targetMask); for (int i = 0; i < targetsInViewradius.Length; i++) { Transform target = targetsInViewradius[i].transform; Vector3 dirToTarget = (target.position - transform.position).normalized; if (Vector3.Angle(transform.forward, dirToTarget) < viewAngle / 2) { float disToTarget = Vector3.Distance(transform.position, target.position); if (!Physics2D.Raycast(transform.position, dirToTarget, disToTarget, obstacleMask)) { visibleTargets.Add(target); } } } } void DrawFieldOfView() { int stepCount = Mathf.RoundToInt(viewAngle * meshResolution); float stepAngleSize = viewAngle / stepCount; List viewPoints = new List(); ViewCastInfo oldViewCast = new ViewCastInfo(); for (int i = 0; i < stepCount; i++) { float angle = transform.eulerAngles.y - viewAngle / 2 + stepAngleSize * i; //Debug.DrawLine(transform.position, transform.position + DirFromAngle(angle, true) * 7, Color.red); ViewCastInfo newViewCast = ViewCast(angle); if (i > 0) { bool edgeDstThresholdExceeded = Mathf.Abs(oldViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (oldViewCast.hit != newViewCast.hit || (oldViewCast.hit && newViewCast.hit && edgeDstThresholdExceeded)) { EdgeInfo edge = FindEdge(oldViewCast, newViewCast); if (edge.pointA != Vector3.zero) { viewPoints.Add(edge.pointA); } if (edge.pointB != Vector3.zero) { viewPoints.Add(edge.pointB); } } } viewPoints.Add(newViewCast.point); oldViewCast = newViewCast; } int vertexCount = viewPoints.Count + 1; Vector3[] vertices = new Vector3[vertexCount]; int[] triangles = new int[(vertexCount - 2) * 3]; vertices[0] = Vector3.zero; for (int i = 0; i < vertexCount - 1; i++) { vertices[i + 1] = transform.InverseTransformPoint(viewPoints[i]); if (i < vertexCount - 2) { triangles[i * 3] = 0; triangles[i * 3 + 1] = i + 1; triangles[i * 3 + 2] = i + 2; } } viewMesh.Clear(); viewMesh.vertices = vertices; viewMesh.triangles = triangles; viewMesh.RecalculateNormals(); } EdgeInfo FindEdge(ViewCastInfo minViewCast, ViewCastInfo maxViewCast) { float minAngle = minViewCast.angle; float maxAngle = maxViewCast.angle; Vector3 minPoint = Vector3.zero; Vector3 maxPoint = Vector3.zero; for (int i = 0; i < edgeResolveIterations; i++) { float angle = (minAngle + maxAngle) / 2; ViewCastInfo newViewCast = ViewCast(angle); bool edgeDstThresholdExceeded = Mathf.Abs(minViewCast.dst - newViewCast.dst) > edgeDstThreshold; if (newViewCast.hit == minViewCast.hit && !edgeDstThresholdExceeded) { minAngle = angle; minPoint = newViewCast.point; } else { maxAngle = angle; maxPoint = newViewCast.point; } } return new EdgeInfo(minPoint, maxPoint); } ViewCastInfo ViewCast(float globalAngle) { Vector3 dir = DirFromAngle(globalAngle, true); RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(dir.x, dir.y), Mathf.Infinity, obstacleMask); if (/*hit != null &&*/ hit.collider != null) { return new ViewCastInfo(true, hit.point, hit.distance, globalAngle); } else { return new ViewCastInfo(false, transform.position + dir * Mathf.Infinity, Mathf.Infinity, globalAngle); } } public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal) { if (!angleIsGlobal) { angleInDegrees += transform.eulerAngles.y; } return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), Mathf.Cos(angleInDegrees * Mathf.Deg2Rad), 0); } public struct ViewCastInfo { public bool hit; public Vector3 point; public float dst; public float angle; public ViewCastInfo(bool _hit, Vector3 _point, float _dst, float _angle) { hit = _hit; point = _point; dst = _dst; angle = _angle; } } public struct EdgeInfo { public Vector3 pointA; public Vector3 pointB; public EdgeInfo(Vector3 _pointA, Vector3 _pointB) { pointA = _pointA; pointB = _pointB; } } } FieldOfViewEditor Script - Script 2 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; [CustomEditor(typeof(FieldOfView))] public class FieldOfViewEditor : Editor { void OnSceneGUI() { FieldOfView fow = (FieldOfView)target; Handles.color = Color.white; Handles.DrawWireArc(fow.transform.position, Vector3.forward, Vector3.right, 360, Mathf.Infinity); Vector3 viewAngleA = fow.DirFromAngle(-fow.viewAngle / 2, false); Vector3 viewAngleB = fow.DirFromAngle(fow.viewAngle / 2, false); Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleA * Mathf.Infinity); Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleB * Mathf.Infinity); Handles.color = Color.red; foreach(Transform visibleTarget in fow.visibleTargets) { Handles.DrawLine(fow.transform.position, visibleTarget.position); } } }
@colonthree
@colonthree 4 жыл бұрын
What about using the hit.normal and/or object ID (int) to also help with checking along with the Exceedingly Edge Distance Thresholde? ;w;
@perendi5583
@perendi5583 8 жыл бұрын
Most of time i just work with the 2D tools of unity, because im not confident with 3d modelling. It is not possible to use this method for 2D sprites / 2DCollider, because they have no mesh renderer right?
Introduction to Game Development (E03: Unity overview)
4:59
Sebastian Lague
Рет қаралды 159 М.
I Spent a Week Making an AI's Video Game Idea
17:51
Sebastian Lague
Рет қаралды 3,2 МЛН
Mom Hack for Cooking Solo with a Little One! 🍳👶
00:15
5-Minute Crafts HOUSE
Рет қаралды 20 МЛН
Quando A Diferença De Altura É Muito Grande 😲😂
00:12
Mari Maria
Рет қаралды 35 МЛН
Coding Adventure: Ant and Slime Simulations
17:54
Sebastian Lague
Рет қаралды 1,9 МЛН
Moebius-style 3D Rendering | Useless Game Dev
8:12
Useless Game Dev
Рет қаралды 854 М.
Answering Your Questions
29:12
Sebastian Lague
Рет қаралды 323 М.
Better Coding in Unity With Just a Few Lines of Code
15:27
Firemind
Рет қаралды 317 М.
How to Add a Field of View for Your Enemies [Unity Tutorial]
23:45
Comp-3 Interactive
Рет қаралды 91 М.
Coding Adventure: Portals
16:06
Sebastian Lague
Рет қаралды 1,3 МЛН
Unity line of sight checking using sensors [AI #08]
19:24
TheKiwiCoder
Рет қаралды 56 М.
Field of view visualisation (E01)
22:32
Sebastian Lague
Рет қаралды 443 М.
Hacking a weird TV censoring device
20:59
Ben Eater
Рет қаралды 3,3 МЛН
The Art of Game Optimization
10:18
Worlds In Motion
Рет қаралды 276 М.
Mom Hack for Cooking Solo with a Little One! 🍳👶
00:15
5-Minute Crafts HOUSE
Рет қаралды 20 МЛН