Detect an OffMeshLink without using an Agent - c#

I'm doing a AI using the NavMesh pathfinding solutions, and I don't to want to use a NavMeshAgent because of some limitations (like teleporting when a carved object comes close, etc.),
Thus I made a sort of fusion, moving a Rigidbody on the path of NavMesh.CalculatePath(), this is working quite good so far, but I have trouble detecting the OffMeshLinks on my path (because it's just an array of Vector3).
I can "trick" a bit using NavMesh.Raycast() like above, but it's not working all the time and sometimes detecting OffMeshLinks that aren't one
NavMeshHit hit;
//Raycast between two corners of a path, because OffMeshLink are most of the time over a hole
if (NavMesh.Raycast(_pathCorners[0], _pathCorners[1], out hit, NavMesh.AllAreas))
{
//If the hit position is really close to the corner, it's surely a offmeshlink generate from the NavMesh
//Or if the second corner is higher than the first one, it's surely a offmeshlink I generate myself
if ((hit.position - _pathCorners[0]).sqrMagnitude < 1
|| _pathCorners[0].y < _pathCorners[1].y)
{
ActivateJump(_pathCorners[0], _pathCorners[1]);
}
}
Thanks in advance :)

Related

How can i get the Direction where my Object is moving?

I have started to make Pacman and would like to know how can i write in my code the direction where the Ghost is going ? So if the transform.position.y is growing, its obvious Up Direction and so on....
This is for the Direction Change if they're hit the Wall.
Any suggestions?
It depends on how you've got your game set-up. One manual way you could go about it is by saving the position in a frame, and in the next frame you calculate the difference between the two positions (the previous frame and the actual frame), and divide that by the time that has passed (Time.deltaTime).
Another way you could go about it (and I would recommend if possible) is simply getting the Rigidbody component and checking the velocity attribute: https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
Keep in mind, since this is a beginner's question, that the fact that an object is moving in a certain direction may not come from a ribidbody. As I said, this depends on your exact set-up.

AI : fire on moving object

i try to to make an AI in C# (with unity) that can predict the estimated position of a moving object to hit it with a bullet
the moving object have a movement speed of 5f and the bullet have a speed of 7f
my problem is that the time my bullet travel to my estimated position my "enemy" already moved further and the bullet don't hit
do you know a formula or code that i can adapt to improve my targeting AI ? (already looking for that in google but don't find anything usefull)
thank
An answer to your question from unreal engine forums
Here is the top answer from there in case the link dies. I did not write this code I simply found it with a quick google of your problem which you stated you already tried.
Link answer:
Get the "velocity" of the target player. Multiply by the time the bullet will take to travel to the target. Then get the position of the target, add the velocity*time vector, and that's the position you should aim at. You can either hard-code the travel time (half a second, or whatever,) or you can in turn measure the distance between AI and player, and divide by bullet travel time, to come up with an approximate travel time. You can also apply a differential equation to calculate the exact time of impact and exact direction, but that requires a little more math and is slightly harder to write out, so I think the above will work best for you.
Simply:
Distance = Length(Target_Position - Firing_Position)
Time = Distance / Bullet_Speed
Predicted_Position = Target_Position + (Target_Velocity * Time)

How to make an object follow another object's path in Unity3D?

I've tried asking this question on the Unity answers site, but since I've yet to receive an answer I figured I'd ask this question here as well. I am trying to make a 3D version of the game "Snake", but I am running into serious problems trying to make the first snake segment follow the head of the snake. The GameObjects I am using are spheres with rigidbody components, with the player having control only over the "head" of the snake. Then, as the snake grows, more spheres are added that should follow the path that the main sphere makes.
I would like to know if there is either a more elegant solution to what I am trying to achieve, or at least a little help into what I may do to fix the current implementation. I am attaching the code of the segment that is supposed to follow the head. The naming for the objects are in Spanish, but it may not be that hard to figure out what is going on from a non-Spanish speaking person's perspective.
I have also properly commented the code, so that you can understand what I am doing at each sentence. The main idea that partially works right now is to send the snake segments information about where exactly the head made a turn so that when the segments get to a particular turning point, they can make a turn in the direction the head turned. The problem I have is that sometimes the segment travels past by the point where it should make a turn, and I don't understand if it is because of precision problems (I am making float comparisons to determine if a segment has reached a certain position where it turns) or if it's something else.
using UnityEngine;
using System.Collections.Generic;
using Clases;
public class ControladorSegmento : MonoBehaviour {
//This is a generic list of Objects that store both turning position and turning direction that the head has made
public List<PosicionCambioDireccion> listaPosicionesCambioDireccion;
//This would be the head in the case of only one segment that is following
public GameObject lider;
//Speed
public float rapidez;
//Direction
public Vector3 direccion;
//This is an index that is used to iterate over the list of turning points
private int indiceCambioDireccion;
// Use this for initialization
void Start () {
indiceCambioDireccion = 0;
listaPosicionesCambioDireccion = new List<PosicionCambioDireccion>();
//First find the Head of the snake so that we can access its position in order to determine segment spawning position
lider = GameObject.Find("Cabeza");
//Set the position of the new segment 2 units right behind the head
transform.position = lider.GetComponent<Transform>().position - lider.GetComponent<ControladorCabeza>().direccion * 2f;
//Get the current direction of the head so that the segment inmediately moves in its direction
direccion = lider.GetComponent<ControladorCabeza>().direccion;
}
void LateUpdate () {
//Check if there has been a change in direction that the segment has to follow
if ((listaPosicionesCambioDireccion.Count > 0) && (listaPosicionesCambioDireccion.Count > indiceCambioDireccion)) {
//Compare how close we are to the turning position. If we are sufficiently close, change segment direction
if (Mathf.Abs(transform.position.x - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.x) < 0.0999999 &&
Mathf.Abs(transform.position.z - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.z) < 0.0999999) {
//Change segment direction at the current position
direccion = listaPosicionesCambioDireccion[indiceCambioDireccion].direccion;
//Increment turning positions list index so that we get the next turning point in the list (if there is any)
indiceCambioDireccion++;
}
}
}
void FixedUpdate() {
//Change the velocity
GetComponent<Rigidbody>().velocity = direccion * rapidez;
}
}
I am still really new working with Unity and it seems I have still much to learn. And again, if you have a more elegant solution to what I am trying to achieve, please let me know. Right know I am aware that this implementation could cause a sort of memory leak in the sense that, as long as the head keeps changing direction, the list of turning points that is stored is going to keep growing and growing which obviously is something one should avoid.
You may record each segment's position in last frame in a list(include head), at the next frame, create a vector from the current position of the head segment to the last position recorded last frame. Then step the distance of the sum of both head & first segment's radius from the current position of the head, and place your first segment there. Repeat these steps for all other segments consist your snake. Hope this can help you.

C# Monogame & Farseer Physics: Collisions

I am a begginer. I am using Monogame and Farseer Physics Library in C#. (latest versions)
In my game, whenever my ball (circle) hits the corner of a rectangle, (or even another circle), it is supposed to only change direction on the Y-Axis.
However, it does not only change direction on the Y-Axis, (as intended), but it also moves a small amount to the right as well (or the left accordingly), depending on how you hit the corner (or another circle). It is as if some force is being put on the ball, making it move on X-Axis as well.
This movement is cool and all, and it makes a lot of sense, but in my game, it does not, therefore i want to get rid of it.
How is this possible ? I am guessing i have to change some default values.
This what my coding looks like:
BallBody.BodyType = BodyType.Dynamic;
BlockBody.BodyType = BodyType.Static;
Ball.LinearVelocity = new Vector(0,-1); // ball going up
BallBody.OnCollision += Ball_OnCollision;
public bool Ball_OnCollision(Fixture f1, Fixture f2, Contact contact)
{
// if the Ball (f1), collides with the Block (f2)
if (f2.Body == BlockBody)
// change the direction of the Ball on Y-Axis
Ball.LinearVelocity = new Vector(0,-1);
return true;
}
Also with high speeds, this occurs:
Even though the ball is never able to pass through the Block (tunneling), I want to know how could i possible fix that so that the ball never enters the Block area ?
Unfortunately, this is surprisingly difficult to do with Box2D. The best I could manage when I tried, was to record the velocity of the ball when the contact started, and then when the contact ends, manually set the velocity to what I wanted. That works fine when the ball only begins and end contact with one block at a time, but in some cases the ball can begin touching two blocks in the same time step. You would have to look at the arrangement of the blocks it touched, and calculate for yourself what angle you would expect it to bounce away at. Eventually I just gave up and did not bother to cover that case.

Moving A Body With A Texture

I am using Farseer Physics Engine to build a "Monster Dash" like game targeted for the PC using C# and XNA,
I am trying to move a body with it's texture, the texture is built from parts so they all should move together, basically it looks like this:
public void Update()
{
tilingFloorPosition.X += (floorMoveSpeed / MeterInPixels);
_tilingFloorBody.Position = tilingFloorPosition;
// Update the textures position
for (int i = 0; i < texturePositions.Length; i++)
{
texturePositions[i].X += floorMoveSpeed;
}
}
But whenever my player lands on top of the floor he just goes through it like there is nothing there, what am I doing wrong?
If the player is falling through the floor then I can only assume that either the floor's body isn't actually in position, or the two bodies are not colliding. Can you confirm that the floor is indeed positioned correctly? If you're able, turn on the Farseer Debug View. If so, then the collision must not be occurring.
Check:
That both the player and the floor are not sensors.
That they are not within the same CollisionCategory and at least one of them is included within the others CollidesWithCategory.
That you have not added one of the bodies to the others IgnoreBody list.
That the body types will collide. See: Farseeer Body Types.
Also, it may be worth noting that it is possible that manually setting the position could skip the collision. Try instead setting the LinearVelocity.

Categories