Detect obstacle and block players movement with raycast - c#

I'm new in Unity3D and I have a problem with collision detection. I want to return true if i hit the obstacle by raycast and block movement in this direction. It works good when im in front of the obstacle face to face. When i'm changing direction and i'm in front of the obstacle (but with another face direction) then it returns false and i can still move in all directions (it should block "up" movement like you see on first image).
Any tips would be greatly appreciated!
Returns true when obstacle is in front of us and we can't move "up"
Returns false when obstacle is in on our left or right
Player is blocked after wrong move
Here is sample of my code:
void Update()
{
Ray myRay = new Ray(transform.position, Vector3.right);
Debug.DrawRay(transform.position, Vector3.right, Color.red);
if (Physics.Raycast(myRay, out hit, 1.5f))
{
if (hit.collider.gameObject.tag == "TerrainObject")
{
Debug.DrawRay(transform.position, Vector3.right, Color.blue);
upHit = true;
}
}
else
upHit = false;
...
}

As discussed in the comments, you need to increase the starting height of the raycast.
Use Ray myRay = new Ray(transform.position+new Vector3(0f,0.15f,0f), Vector3.right); to raycast from above the ground a little bit.

Related

Debug.DrawRay() pointing to wrong direction in Unity2D

I am trying to learn how to Raycast in Unity2D.
Here is my code:
Ray ray;
void Update()
{
ray = new Ray(transform.position, Input.mousePosition);
Debug.DrawRay(transform.position,Input.mousePosition);
}
This results in strange behavior.
transform.position is the Vector3 of the player object.
I want to shoot a ray from the Player Object through the Mouse Position.
However, this does not seem to work.
The line is drawn, but behaves weirdly. It does not point toward it at all. It's hard to accurately describe its behavior as anything except erratic.
What am I doing wrong?
I think there may be something wrong with putting in Input.mousePosition and directions in general. I would be very thankful for any help you can give.
Note: I am using Unity 2D.
When you use Input.mousePosition you get a Vector2 which represents the position of the mouse relative to the camera. This means the X and Y you get are actually the X and Y of the position of the mouse on the screen.
These coordinates are not world coordinates.
For example if you were to draw a ray from transform.position of a player standing at 0,0,0 to the mouse position of 500, 250 you would get a gigantic and seemingly randomly pointing ray.
To convert from where the mouse is on the screen(Screen Coordinates) to what it's pointing to in-game(World Coordinates) you can use Camera.ScreenToWorldPoint.
For example
Ray ray;
void Update()
{
// get the mouse screen pos
Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y);
// convert it
Vector3 worldMousePosition = Camera.Main.ScreenToWorldPoint(mousePosition);
ray = new Ray(transform.position, );
Debug.DrawRay(transform.position, worldMousePosition);
}

Raycast is only working when I move at a moderate speed?

I used to raycast to destroy things in my game and it didn't work unless I moved quite fast I attached this script to my main camera in unity, Can anyone tell me what I have done wrong as I want it to happen regardless of movement whether you're still or not.
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector2 mousePos = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
RaycastHit2D hit = Physics2D.Raycast(mousePos, Vector2.zero, 100f);
if (hit.collider.tag == "Ground")
{
Debug.Log("You clicked a block and tried to break it!");
Destroy(hit.collider.gameObject);
}
}
}
Physics2D.Raycast should be used in FixedUpdate because in there is when the physics are calculate. Physics are not frame dependant.
From the docs:
RaycastHit2D Raycast(Vector3 origin, Vector3 direction, float distance)
You've given the raycast a zero direction.
Generally, you should use ScreenPointToRay and pass the ray origin and direction to Raycast instead

Object Follow finger Only when it swipe on the Screen

I have a sphere in that is moving foward and I need it to follow my finger smoothly when it swipes on the screen but only in the x axis.
I trying to make the exact movent like Rolling Sky, Color Road
The ball Should follow my finger when it swipes in the x axis and move smoothly.
Just like in the games I mention before.
I try OnMouseDrag and a lot of ways but it dont work correctly beacuse it dont dont follow the finger or it dont move while finger is swiping.
From what I understand, it seems you want to get the position of the user's finger and move the ball accordingly?
You could achieve this with Touch.position
Example:
private void Update()
{
Touch touch = Input.GetTouch(0); // Get the touch data for the first finger
Vector2 position = touch.position; // Get the position in screen-space
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(position); // Convert the position to world space
Vector3 ballPosition = ball.transform.position;
ball.transform.position = new Vector3(worldPosition.x, ballPosition.y, ballPosition.z); // Move the ball
}
I think you should handle the input separately from the sphere.
Put this on a script to detect the swiping on the screen.
bool inputBegan = false;
Vector2 beganPosition;
void Update()
{
if (!inputBegan && Input.GetMouseButtonDown (0))
{
inputBegan = true;
beganPosition = Input.mousePosition;
}
else if (inputBegan && Input.GetMouseButtonUp (0))
{
//If you want a threshold you need to change this comparison
if (beganPosition.x > Input.mousePosition)
{
MoveBallLeft ();
}
else
{
MoveBallRight ();
}
inputBegan = false;
}
}
The movement of the balls you can achieve it adding or substracting Vector2.right * movingDistance to the sphere Transform if you want it to teleport or making the sphere move slowly using a targetPosition and currentPosition and each Update cycle add a little bit of transform distance.
I solved it doing this and setting the variable NavigationMultiplier to 10000

RayCast Not Working in GearVR

I have and raycast, and a rayCastHit. Whenever the user click on the fire button. It will move the FPS charater to the location where the rayCastHit is. lightRetical is a gameObject variable which is a spotlight that shows where the rayCastHit is.
The Funny thing is, it works when I click play in unity. But whenever I build to my android phone it doesn't work. I am unable to move the fps character.
The FPS character I used, is from the standard asset "character" and the codes I add them to the Update() method.
RaycastHit seen;
Ray raydirection = new Ray(transform.position, cam.transform.forward);
int sightlength = 5;
if (Physics.Raycast(raydirection, out seen, sightlength))
{
if (seen.collider.tag == "Floor" && Input.GetButtonDown("Fire1")) //in the editor, tag anything you want to interact with and use it here
{
Vector3 relativePoint;
lightRetical.SetActive(true);
relativePoint = seen.point;
relativePoint.y = 2.0f;
bodychar.transform.position = relativePoint;
}
else
{
lightRetical.SetActive(true);
Vector3 relativePoint;
relativePoint = seen.point;
relativePoint.y = 2.64f;
lightRetical.transform.position = relativePoint;
}
}
else
{
lightRetical.SetActive(false);
}
I suggest casting the ray from the camera position forward. If the player rotates his head the raycast will follow. I'm currently developing an app for VR and this seems like the best solution. You can use collision layers to filter the raycast. I would also print the hit.transform to the console, to check what the raycast is hitting. Hope this helps.

Collision on X axis means 0 movement in Y axis

I'm developing a platformer in Unity using the 2D engine. I have my player character which has a BoxCollider2D and a RigidBody, and a number of 'walls' which have BoxColliders.
Now, I copied the script for moving the player from another project and made some changes. The part which has to do with movement is as follows:
public void FixedUpdate()
{
physVel = Vector2.zero;
// move left
if(Input.GetKey(KeyCode.LeftArrow))
{
physVel.x = -runVel;
}
// move right
if(Input.GetKey(KeyCode.RightArrow))
{
physVel.x = runVel;
}
// jump
if(Input.GetKey(KeyCode.UpArrow))
{
if(jumps < maxJumps)
{
jumps += 1;
if(jumps == 1)
{
_rigidbody.velocity = new Vector2(physVel.x, jumpVel);
}
}
}
//Apply gravity
_rigidbody.AddForce(-Vector3.up * fallVel);
// actually move the player
_rigidbody.velocity = new Vector2(physVel.x, _rigidbody.velocity.y);
}
Now this works perfectly fine.
The problem arises if the player jumps into a wall. If I keep the direction button mashed 'towards' the wall after having jumped, he is suspended in mid-air. As in the collision appears to be reducing movement on both axis to zero. If I release the direction, he falls normally. Collisions on the other axis works fine. I can hit my head or walk without issue.
Am I missing something obvious?
EDIT: try adding a material with 0 friction to both player and walls and see what happens, if it stops it is a friction error.

Categories

Resources