I have an array which is filled with all the objects with the tag Enemy. When one enemy comes close to an other enemy, it has to stay away from that enemy or go around it.
This is what I have now:
foreach(Transform enemy in enemies){
if(enemy == this.transform) continue;
enemyPos = enemy;
float enemyDistance = Vector3.Distance(enemy.transform.position, transform.position);
if(enemyDistance < 8){
transform.RotateAround (enemyPos.position, Vector3.up, 360 * Time.deltaTime);
}
}
If enemies come close enough to each other, they will circle around each other. Also tried to use 2 cube triggers for when an enemy object touches one of the cubes, the cubed enemy wil rotate away from it. Also tried different angles.
But no luck :(
I am still trying to find a solution. But if you have a better idea about this, your help is much appreceated :)
Thanks in advance!!!
You have several moving objects, and some of them may stand in the way of other objects. I would propose that you defer moving of all those objects that have a moving obstacle in front of them. When all free-moving objects are moved then try to move all other, by repeating the procedure, because in the process some objects might become free. You essentially loop through list of not-yet-moved objects until there is no change in the list.
If you don't find any new free-moving objects then deal with the rest as you like. I would suggest that you try find alternative route only for one of them, and then repeat the procedure above. It might be that when one object is unstuck then all others are unstuck as well. You may repeat this second procedure for the rest of stuck objects.
The following article could help you.
In short, your agent are "repulsing" each other when they are under the given distance. This is the "separation" concept in the flock. What is really interesting is that you can have a rotation that depends on the distance (ie another agent very near mean that you have to turn hard) and that you can interact with more than one agent.
in the same site, this can help you search the player. Combien the two method, and you have agents that try to catch the player while avoiding other agents.
regards
Guillaume
Related
I am currently facing a problem I cannot wrap my head around. In my 2D game which in the end should become some kind of virtual model railway, I can create a path, consisting of different railtypes. Each rail has it's own waypoints. Now the issue is as follows:
Straight rails don't need many waypoints, since they only need two to be defined; The start and the end point. Curves on the other hand need a lot more waypoints, so the objects movement on them is not all jaggy and unsmooth. The problem I am facing is, that the waypoints then are so unevenly distributed on the whole railway, it makes the speed which the object moves along the path very uneven.
I also already know the issue: The points are so cramped in the curve sections that the distribution looks like this:
See this picture for an example with red Gizmo.Spheres as waypoints
Now when I move an object along that said path, I do it like this:
wagon.transform.position = Vector2.MoveTowards(wagon.transform.position, wagon.GetNextPosition(), wagon.GetSpeed());
The third parameter of the method Vector2.MoveTowards() is the maxDistanceDelta, so it can only move that amount into the direction of wagon.GetNextPosition(), which is constantly updated.
The twist is, that the densly packed points result in a way shorter distance than the maxDistanceDelta. So in those parts of the railway, the object moves way slower then wagon.GetSpeed() per frame.
I already have a solution to this, which sadly I cannot use: I took every waypoint and distributed them evenly on the path. I don't want that; I want the path to stay as is, but the speed to the eye to be uniform.
Thanks in advance for your help!
PS: I already looked in similar threads, but none of those solutions seems to work for me :( Namely:
This thread
And this one
I would comment this but unfortunately I don't have enough reputation, so here it is:
The best idea I can think of is to create 2 waypoints for your curve (at the start and finish) and use a parabolic function to define the movement between them. So in other words, your train follows a parabola instead of moving towards waypoints directly.
I found a useful answer on a unity forum about parabolic trajectories which you may find useful for your project (It is the first answer beneath the question at the time of writing).
How are you generating those waypoints?
Could you use bezier curves instead?
If yes, there it's typical to run into exactly this issue and solutions have been found. Not solutions with absolute accuracy, but usually sufficient for games (aka visualizations that in the end only need to be as accurate as the pixels you see).
There is this outstanding video about the topic: https://www.youtube.com/watch?v=aVwxzDHniEw
To explain the context, I procedurally generate buildings on unity in C#. I create a mesh and fill in the vertices and triangles, then I calculate the normals of the different points. I have several hundreds of buildings that are generated, but some faces are not in the right direction, the normals point inwards instead of outwards.
The normals are good
The normals are bad
To calculate the normals I create a Plane with the different vertex that make up the triangle, and then I retrieve the normal of the Plane. I also tested the cross product that gives the same result.
Plane plane = new Plane(v1, v2, v3);
normals.Add(plane.normal);
How i generate Triangle ?
Ex: I make a for loop on the points at the base of the building.
vectors.Add(v1);
vectors.Add(v2);
vectors.Add(v3); //v3 = v1+height
vectors.Add(v4); //v4 = v2+height
// index values
int idx1, idx2, idx3, idx4;
idx4 = vectors.Count - 1;
idx3 = vectors.Count - 2;
idx2 = vectors.Count - 3;
idx1 = vectors.Count - 4;
// Triangle 1
indices.Add(idx1);
indices.Add(idx3);
indices.Add(idx2);
...
mesh.triangles = indices.ToArray();
So my question is: How to determine if the normal is in the right direction (inside or outside)? If I can determine that, I can then flip the normal and normally it will work.
I do not totally understand your question, but for simple shapes a simple algorithm is ..
just take the "center" of the object (the CG is fine) and make a vector from there to your vertex or triangle. That direction is "outside". If you're pointing over 90° away from that, you're pointing in to the guts of the object
the next more complicated approach ...
move along your normal say "one meter". call that point "test point". you should now be "outside" your building, correct?
now you just need to check if testPoint is inside or outside your 3D shape.
in short, to determine if you are inside or outside a 3D object, you just cast a ray and count how many times you intersect with the walls. if odd, you're inside, if even you're outside.
You can google hundreds of discussions on this on the www, example https://stackoverflow.com/a/63572837/294884
Note that there are many, many variations on this, and many problems too. In some cases you start from "just inside" your normal (ie go backwards a little); sometimes it's better to start from the middle of the object (if such a thing is knowable); sometimes there are issues about how the ray casting system works in edge cases (like "right on" the surface, which is what your vertex is)
the first solution seems to me to be the right one
It may be. Sometimes it is useless. It depends on the nature of your shapes.
I wanted to avoid having to do raycast ..
Can assure you - you will have to constantly raycast during any construction process! If you wish to "avoid" casting, set the idea aside. You will be casting until you are sick of it :)
I wanted to avoid having to do raycast to limit the generation time
The good news is this is totally incorrect. Casting is extremely trivial and a very minor burden compared to everything going on in a 3D scene. When you play any 3D scene, casts are being made 100s and 1000s of times each frame.
but if I have two buildings that are close to each other, the ray will find the wall but from the second building so I couldn't determine the normal is "inside" or "outside", right?
TBC in the simple system I described. You would certainly ONLY cast against that same building that you are working on! So that's the way to go.
But indeed, unrelated to what you're asking about. Say you're in a "city". You can indeed cast through "all walls" and the parity (ie: odd or even) will let you know if you are indoors or out. This has problems though, relating to edges, corners etc. But in some case it is relevant to that problem.
As mentioned on this answer https://stackoverflow.com/a/63593282/294884 ultimately you can investigate convex hulls and more. It's a big topic!
Note that often when you build dynamic buildings/shapes, you havce a data structure of each "wall" and indeed it knows which side is in and which side out. When you do that first, it's then easy to draw the triangles the correct way. It's a big topic!
I'm going to create an endless runner in Unity and I was wondering if I should move the player or the scenario during the runs.
The most obvious answer sounds like "the player" because you are moving fewer objects but... does the performance get affected if the size of the scenes is too large? I don't think so but my real worry is about the coordinate:
What happens if the player runs so far away that the coordinates can't fit in a float variable? I think that the transform component uses a Vector3 to store the coordinates and this Vector3 uses float variables (with a limit of +3.4E+38) for each of the coordinates.
Thank you for your answers in advance,
Guillem Poy
Even if I don't know what happens if the value of the coordenates exceeds the capacity of a float variable (I think that then the number simply will be wrong) doing some calculus...
Even if the player is moving 1000 units per second, to create that problem, the player should be playing during 9.4+E32 hours (2.5+E29 years). I think that nobody is going to play this much.
So, the best option I think that is to move the player.
I'm making a game in which I know would want to embed grenades. What would be the best way to find all game objects within a certain radius from the grenade before it explodes? I have already seen that one way is too have all enemies/opponents in an array and then loop through the array to see how many would be within a certain area but I was wondering if there would be a better way to approach this.
Edit:
Hello, please if you see this, vote this question up for some reason I was banned for a fine question which only got 1-. (most likely because it was my first question so my account was very susceptible to being banned) It originally said it was only a 1 day ban but apparently not as it has been two days already....
If all the objects you want to detect have colliders attached to them, you can use Physics.OverlapSphere(). Just supply it a position and a radius to retrieve all colliders within a spherical area:
Collider[] hitColliders = Physics.OverlapSphere(grenadePosition, explosionRadius);
Then you can loop through them and apply damage as needed. Hope this helps! Let me know if you have any questions.
I think the best way to approach this is, as you already said, to have the objects in an array.
I would set the tag "Enemy" for the enemies and then loop through all gameobjects which are tagged with "Enemy".
foreach(GameObject gameObj in GameObject.FindGameObjectsWithTag("Enemy") {
// check if the current gameObj is in a certain range of your grenade object
}
Imagine the following scenario: I have a level whose physical structure is built up from a collection of bounding rectangles, combined with prerendered bitmap backgrounds. My actors, including the player character, all have their own bounding rectangle. If an actor manages to get stuck inside a level block, partially or otherwise, it'll need to be shifted out again, so that it is flush against the block.
The untested technique I thought up during bio break is as follows:
If an actor's box is found to intersect a level box, determine where the centerpoints of each rect are. If the actor's center is higher than the level box's, move the actor so that the bottom of the actor's rect is flush with the top of the level's rect, and vice versa if it's lower. Then do a similar thing horizontally.
Opinions on that? Suggestions on better methods?
Actually, the bounding rects are XNA BoundingBoxes with their Z spanning from -1 to 1, but it's still 2D gameplay.
Have you read the N Tutorials? They're a wonderful introduction, complete with little demos, of Separating Axis Theorem based collision detection and simple projection response. (They're actually used in the N game to great effect.) The tutorials cover more than you need, but they're very general (extensible to many other shapes), and start to touch on issues with fast-moving objects and other response techniques.
Even if you do decide to go with something simpler than a SAT implementation, this may give you a lot of good ideas.
(When you're done with that and if you want your mind blown, try looking into some of the presentations from the Game Developers Conference physics tutorial day, including realtimecollisiondetection.net publications, the essentialmath.com tutorial slides, both of those books, and/or other stuff linked from those sites. I'd highly recommend the GDC session itself, too. While we still don't need or particularly want fancy GJK on swept hulls on the handheld game platforms we work with, some of the simpler concepts such as "configuration spaces" and Minkowski sums and differences have greatly influenced how I think about physics and collision detection and how we implement it.)
What the "real" physics engines do is find the minimum penetration vector. That is - the smallest vector that represents how far inside each other the two objects penetrate.
For an AABB (axis-aligned bounding box) this is really easy to calculate.
(Consider making your own 2D AABB structure, it will be smaller and therefore better for performance.)
Once you have your minimum penetration vector, you can perform collision response. And the easiest response is to simply separate the two objects by that vector (or separate the one object if the other is static).
Here is a good reference, by the makers of N on how to do this for convex polygons and circles. You should be able to simplify this down for AABBs.
A lot depends on the details. A complete solution could take into account velocities or other issues. But treating this simply...
You don't want to always resolve vertically first. Imagine an actor nudges horizontally into a block. If you resolve vertically first then the actor will pop up above that block, when a small horizontal movement would have sufficed.
Find what the vertical and horizontal movements would need to be to "get out of collision", and then apply the one with the smallest absolute value.
Then repeat a few times, in case the movement puts the actor into another block. But don't repeat forever, because the actor could be wedged somewhere that never resolves.
Maybe if your last movement still leaves you in collision, you could just average the last two movements and leave it there.
Another possible approach is, rather than waiting for a collision and then shifting out, check for possible collisions before you move objects and, if there is going to be a collision, move the player only up to the edge of the block.
I.e., contrast how Adventure does collisions with walls: http://www.youtube.com/watch?v=I6-zN_eaRd8
to how most NES games do collisions with walls.