Problems with Physics2D.Raycast - c#

In a basic tutorial to make a 2D platformer I was given this bit of code:
if (Physics2D.Raycast(ray, out hit, Mathf.Infinity, collisionMask))
But Unity says you need Vector2s instead of Ray and out hit. Is there a way I could substitute Vectors for the same value and produce the same effect?
Here's the ray code if you want it:
ray = new Ray2D(new Vector2(x,y), new Vector2(x,dir));
The code is compiling now but it won't actually work (it's supposed to emulate gravity so the character will fall till they hit ground) but it just falls through the ground.
PlayerPhysics.cs
PlayerController.cs
In Unity the character has a Box Collider 2D which is correctly setup and the scripts are both attached and the platform has a Box Collider 2D correctly setup.

Your ray has an origin and direction components (both of which are vectors) so try this:
var hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity, collisionMask));

Related

Boxcast not working with Capsule Collider 2D in Unity

I'm trying to make a 2D platform game where my character makes a ground check before jumping using Physics2D.BoxCast & some of the platforms have Capsule Collider 2D & others have Box Collider 2D.
Everything works fine with the Box Collider but when it comes to Capsule Collider, Boxcast is not responding & my character can spam jump on those platforms. Here's my code for ground check,
public bool isGrounded()
{
RaycastHit2D raycastHit = Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector3.down, castDist, ground);
return raycastHit.collider != null;
}
How can I resolve this issue? Any way to detect both BoxCollider & CapsuleCollider?
I got it, the castDist variable was causing the issue. It was set to 5 so the detection at bottom was far more than enough, reducing it to 0.1 solved the issue.

I'm trying to figure out what is the best way to prevent from the player to move through walls and other objects?

I can think of what objects I will use in the game and add them a box collider or mesh collider and start setting them up. Or I could use maybe raycast and detect the distance from the objects I want to avoid walking through ? Is that logic to use distance calculation with raycast ?
void FixedUpdate()
{
Vector3 direction = new Vector3(transform.position - lastPosition);
Ray ray = new Ray(lastPosition, direction);
RaycastHit hit;
if (Physics.Raycast(ray, hit, direction.magnitude))
{
// Do something if hit
}
this.lastPosition = transform.position;
}
Not sure if this is the right script to put on the player. Maybe need to use layer ? But the logic is that if the player is for example 0.3f distance form the object that the player will stop moving forward.
Using unity you don't really want to be doing any of this stuff from the code behind, instead you'd have a RigidBody or RigidBody2D component on your "player", and then a box Collider or mesh collider (or the 2d versions of those) on your collision objects.
This will handle all collisions and stop the player when they hit that object.
Another word of advice is, when handling collisions in the backend you don't want to use FixedUpdate as if an object is travelling fast enough it will pass through the collider between updates

How to drop a box to the mouse position?

I am trying to learn unity, and made my first own game and stucked at the beginning. The first idea was to drop a box (cube) to the mouse position. There are many videos and posts about getting the mouse position, and i tried to use them. My problem is, the mouse position i got is the camera's position, instead of the plane.
As you can see, it is kinda works, but it isn't fall to the plane.
https://prnt.sc/lmrmcl
My code:
void Update()
{
Wall();
}
void Wall()
{
if (Input.GetMouseButtonDown(0))
{
if (Input.GetMouseButtonDown(0))
{
wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
Rigidbody wallsRigidbody = wall.AddComponent<Rigidbody>();
wall.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);
wallsRigidbody.mass = 1f;
wallsRigidbody.angularDrag = 0.05f;
wallsRigidbody.useGravity = true;
wallsRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
wall.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
Debug.Log(Camera.main.ScreenToWorldPoint(Input.mousePosition));
BoxCollider wallsCollider = wall.AddComponent<BoxCollider>();
wallsCollider.size = new Vector3(1f, 1f, 1f);
}
}
How should i change my code to get the right position?
This isn't a direct answer to your question, but I'm hoping it'll still get you where you need to go.
Prefabs are your friends! I'd highly recommend leveraging them here instead of constructing a cube directly in code.
But first, make sure everything else is set up right. Go ahead and construct a cube by hand in the Editor and make sure that when you hit Play, it falls as you expect. It should, provided it has a Rigidbody, collider, and you have gravity enabled (true by default).
If that works, drag that cube from your Hierarchy view into a folder in the Project view. This creates a prefab. You can now delete the cube from the Hierarchy view.
Update your script to have a public GameObject field, e.g.
public GameObject cubeToCreate;
Then, in the Inspector pane for whatever gameobject has that script attached, you should get a new field, "Cube To Create". Drag your prefab cube into that slot.
Lastly...update your code to wall = Instantiate(cubeToCreate). You'll still need to update the position, but you should be able to drop the rest of the initialization logic you have above, e.g. setting mass and drag.
As for the actual problem, the first thing that concerns me is how do you plan on turning a 2d mouse click into a 3d point? For the axis going "into" the screen...how should the game determine the value for that?
Camera.main.ScreenToWorldPoint accepts a Vector3, but you're passing it a Vector2 (Input.mousePosition, which gets converted to a z=0 Vector3), so the point is 0 units from the camera -- so in a plane that intersects with the camera.
I haven't done this, but I think you'll need to do raycasting of some sort. Maybe create an invisible 2d plane with a collider on it, and cast a physics ray from the camera, and wherever it hits that plane, that's the point where you want to create your cube. This post has a couple hints, though it's geared toward 2D. That might all be overkill, too -- if you create a new Vector3 and initialize it with your mouse position, you can set the z coordinate to whatever you want, but then your cube creation will be in terms of distance from the camera, which is not the best idea.
Hope this helps.

How to place objects when clicking onto mesh Unity

So I have this mesh that I generate using perlin noise
What I want to do is to be able to click to place an object in the game. My ultimate goal is to have a menu so you can place different objects but I want to just try to get a cube to work. I tried RayCasting:
public class Raycast : MonoBehaviour
{
Ray myRay; // initializing the ray
RaycastHit hit; // initializing the raycasthit
public GameObject objectToinstantiate;
// Update is called once per frame
void Update()
{
myRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(myRay, out hit))
{
if (Input.GetMouseButtonDown(0))
{
Instantiate(objectToinstantiate, hit.point, Quaternion.identity);
Debug.Log(hit.point);
}
}
I could not get this to work... I had no real idea how to use this script either (like what object to place it on) I tried just making a cube and putting the script on that but It did not work. I got no errors it just did not work.
I also had a mesh collider on my mesh and a box collider on my cube.
I see that you are following the tutorial on YouTube "Procedural Landmass Generation", which I would say is an excellent way to understand the basics of procedural content generation.
For your question I would suggest you add a camera on the top of the terrain, from where you will be able to point with your mouse where you want to instantiate the object (the cube for example). You would need a function which raycasts to the your land tiles. Check if its gameobject's tag is "Terrain" and check if there is no water at that current location. If terrain check returns true and water check returns false, then instantiate your desired object at the "hit" position of the raycast.
You can put the script on any object you want. I'd propose the camera. After adding this script-component to the camera, drag your mesh (that you want to instantiate) into the "objectToinstantiate" slot you see in the script.
Then see if it works, and for performance move the if (Input.GetMouseButtonDown(0)) up in your code, before you do the raycast, like #Basile said.
Note: This script will work in play-mode on the game-view - not in the editor scene-view.
If you'd like this to work too, you should add [ExecuteInEditMode] above the public class ... line. But be careful with those, it's sometimes hard to stop those scripts :P

Texture Annotation using OVRInput Touch Controller Raycast in Unity5

EDIT2:
Thanks to Draco in the comments referring me to the LineRenderer class.
Here is a link to a script that helped me draw ray lines in the game world space: http://answers.unity3d.com/questions/1142318/making-raycast-line-visibld.html
EDIT:
I changed the unit length from 1 to 100,000 and from black color to blue in the Debug.DrawRay method, and now I am able to see the rays drawn in the scene view only.
Debug.DrawRay(transform.position, transform.forward, Color.blue, 100000);
Also, I am now able to track the touch controller's ray by applying the below script to the game object LocalAvatar > controller_right.
ORIGINAL POST:
I am attempting to do something seemingly simple using the Oculus VR packages OVRAvatar, OVRCameraRig, and OVRInput in Unity 5.6.1 and Visual Studio C#.
Goal: I want to get the raycast from my Oculus touch controller's pointer finger, and intercept a plane to apply pixels to the plane's texture.
I was able to get the camera's raycast to intercept the plane using OVRCameraRig like so:
void Update() {
RaycastHit hit;
Vector3 fwd = ovrCamera.transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(ovrCamera.transform.position, fwd, out hit, 10000))
{
if (hit.collider.tag == "Plane"))
{
print("Hit the plane!");
// apply some pixels to plane texture
// setPixels(plane.texture)
}
}
// EDIT: I changed the unit length from 1 to 100,000 and now I am able to see the rays drawn in the scene view only.
// NOTE: this line below does not work in Unity's scene view or game view
Debug.DrawRay(ovrCamera.transform.position, ovrCamera.transform.forward, Color.black, 1);
}
Aside from the Debug.DrawRay function not working, the code which checks for the OVRcamera's raycast hitting the plane does in fact work.
However, now that I am trying to test the raycast hit from OVRInput.Controller.RTouch, I am unable to see the drawn ray and the hit collider check is not triggered.
I have added this script below as a component to OVRCameraRig's RightHandAnchor:
void Update() {
RaycastHit hit;
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, out hit, 10000))
{
if (hit.collider.tag == "Plane")
{
print("Hit plane with touch controller's raycast!");
}
}
// EDIT: I changed the unit length from 1 to 100,000 and now I am able to see the rays drawn in the scene view only.
// NOTE: this line below does not work in Unity's scene view or game view
Debug.DrawRay(transform.position, transform.forward, Color.black, 1);
}
Needless to say, the Debug.DrawRay function does not work here as well. I can't tell if the raycast from the touch controllers are actually being tracked.
Any help or insight is appreciated, thanks!
Thanks to Draco in the comments referring me to the LineRenderer class.
Here is a link to a script that helped me draw ray lines in the game world space: http://answers.unity3d.com/questions/1142318/making-raycast-line-visibld.html
I changed the unit length from 1 to 100,000 and from black color to blue in the Debug.DrawRay method, and now I am able to see the rays drawn in the scene view only.
Debug.DrawRay(transform.position, transform.forward, Color.blue, 100000);
Also, I am now able to track the touch controller's ray by applying the below script to the game object LocalAvatar > controller_right.

Categories