Why is Unity3D RaycastHit.textureCoord always 0,0? - unity3d

var startPoint =
shaft.transform.position
+ shaft.transform.forward;
var ray = new Ray(
startPoint,
-shaft.transform.forward
);
RaycastHit rayCastHit;
Physics.Raycast(ray, out rayCastHit);
var textured2D = (Texture2D)discoBall.renderer.material.mainTexture;
Vector2 textureCoord = rayCastHit.textureCoord;
Debug.Log(string.Format(
"{0},{1} at distance {2}",
textureCoord.x * textured2D.width,
textureCoord.y * textured2D.height,
rayCastHit.distance
));
I have a sphere with an object "Shaft" object inside it. I work out a startPoint as a distance away from the shaft in the direction the shaft points (to get outside the sphere). I then create a ray pointing back at the sphere with the same distance, so that it collides with the outside of my sphere.
The Debug.Log outputs x,y = 0,0 for the textureCoord, and the correct value of 0.35 for the distance. Why is the textureCoord always 0,0 when I do in fact have a material with a texture on my sphere?

Actually let me move my comment here, does the sphere use a mesh collider or a sphere collider? If it doesn't use a mesh collider, textureCoord returns Vector2.zero.
Update:
To change the collider type of a GameObject highlight it in the Unity editor and go to Component->Physics->MeshCollider. If prompted to 'Replace Existing Component', select 'Replace'.
GameObjects added from Unity's GameObject->Create_Other menu tend to default to colliders based on the shape of the object (spheres, boxes, etc), since mesh colliders are computationally more expensive.

Is the texture2d width and height actually what you expect? Possibly maintexture is not the correct texture on the shader you are using.

Related

How do I make my 2D character's legs snap to non flat terrain?

I am creating a 2D platformer type game, and it has non flat terrain. How do I make it so that my character's legs always smoothly transition from a flat surface to a slope surface?
For reference you can check out [Alto's Adventure] (http://altosadventure.com/) (mobile). In that, the skateboard snaps to the curvy terrain.
Feel free to ask for more details.
To make such a possibility, you have to send a ray to the ground and then set the direction of up transform according to the Normal vector point of impact. The following code solves the basic problem.
public LayerMask groundLayer;
public float maxRayLength = 3;
public float offset = .5f; // set it to half of your character height
public void Update()
{
var ground = Physics2D.Raycast(transform.position, -transform.up, maxRayLength, groundLayer.value);
if (ground)
{
transform.up = ground.normal;
transform.position = new Vector3(ground.point.x, ground.point.y) + transform.up*offset;
}
}
In addition to the script, you must specify a suitable 2D collider as well as its layer. For layers, make sure that both the script inspector and the layer are set to the hypothetical ground layer.
Example Result:

How can I get the position of the tracked picture when detected in Unity with AR foundation?

I am using unity AR foundation image tracking. When a tracked picture appears on the screen, how can I get its position or its relative distance to the camera?
You can get the distance from the camera to the picture by giving the camera position and the game object transform position of the identified picture. I'm currently using this in one of my apps and its working nicely.
Vector3.Distance(pictureGameObject.transform.position, Camera.main.transform.position)
well you would need the position of that other object to check the Distance. This can be done by using Vector3.Distance.
First however you need the Transform of the other object. You can do this by making a Raycast, in this case I'm casting the raycast from the middle of the screen. Then I will assign the Transform of whatever object was hit to the hitTransform variable. After that I can use a Vector3.Distance to compare 2 positions and calculate the distance.
Transform hitTransform;
private float distance;
void Update()
{
Ray ray = cam.ViewportPointToRay(new Vector3(0.5F, 0.5F, 0));
RaycastHit hit
if (Physics.Raycast(ray, out hit))
{
hitTransform = hit.transform;
}
distance = Vector3.Distance(hitTransform.position, transform.position);
}
So in short, if you look at an object that is in the middle of the screen the distance between that object and the camera will be in the distance variable, you can also use a raycast when you click or press a button but for the sake of simplicity I used the middle of the screen for this.

How to clamp gameobject movement in a irregular shape in Unity3d

I am using a runtime gizmo to translate gameobjects in my game. I need to know how to clamp the objects movement in an irregular shape.
For example: If the shape is a Box.
n calculate the Bounds of this shape and using the Bounds.max.x, Bounds.min.x, Bounds.max.y, Bounds.min.y, Bounds.max.z, Bounds.min.z and clamp the position like this:
Vector3 pos = gameObject.transform.position;
pos.x = Mathf.Clamp(pos.x,Bounds.min.x,Bounds.max.x);
pos.y = Mathf.Clamp(pos.y,Bounds.min.y,Bounds.max.y);
pos.x = Mathf.Clamp(pos.z,Bounds.min.z,Bounds.max.z);
gameObject.transform.position = pos;
This is all good till it's a box or a rectangular shape, because I can use either Renderer.Bounds or Collider.Bounds, However, if it is a irregular shape like this:
calculate Bounds value, it will be incorrect since Bounding box/bounds will always be calculated in a square/box shape and will give incorrect max and min value, making the gameObject go outside the shape.
I am using the below RuntimeGizmo to translate my gameObject. https://github.com/HiddenMonk/Unity3DRuntimeTransformGizmo
p.s. The Shape in my case is a square shape and a L-shape room, made by using primitive cubes acting as walls. gameObject in question is a piece of furniture.

Move 3d object to mouse click position in unity

I create a scene in unity. I add camera and 3d unity cube object to the scene. To move object to mouse click position, I add raycast and it works.
But I want to use my model. I have an obj and mtl file. I copy them to Assets folder. I use below code. The object moves but not exact my click position.
Plane plane = new Plane(Camera.main.transform.forward, transform.position);
pos = Input.mousePosition;
Ray ray = Camera.main.ScreenPointToRay(pos);
float dist;
if (plane.Raycast(ray, out dist))
{
Vector3 v = ray.GetPoint(dist);
objectPos = v;
}
transform.position = objectPos;
Origin of model is not (0,0,0). I cut this object from a big 3d model.
I try to move to (Screen.width/2, Screen.Height/2, 0.0f) and result is below
EDIT
EDIT 2
I add box collider to object. But the collider position is not same as the object.
You have to move the null point of the object or save a variable which is representing the vector by which it has to be moved and add it to the objectPos befor setting the transform.position

Instantiate prefab around a object

I have a scene with a body maked with makehuman, and I need to add a simple prefab (a torus) around the arm of the body when the user touch the arm.
I tried:
Instantiate the prefab in the point where the user touch, but the prefab apear in the border of the arm.
Instantiate the prefab in the center of the arm, with this code:
float radio = hit.transform.collider.radius; // the arm has a capsuleCollider
Ray r = Camera.main.ScreenPointToRay(Input.GetTouch(0));
Vector3 origin = r.origin;
float distance = (origin - hit.point).magnitude;
RaycastHit ou;
Vector3 position = hit.point;
Ray r2 = new Ray(r.GetPoint(distance + 10f), -r.direction);
if (cc.Raycast(r2, out ou, distance + 10f))
position = (hit.point + ou.point) / 2;
Instantiate(Prefab, position, Quaternion.identity);
This try to Select the center of the arm and initialite a torus.
The second option works in some cases, but the general impression is that is the wrong way to do it.
How can I add a prefab around a collider? or, how can I modify the mesh to add a visual indicator?
This should work a lot better as well as look a lot cleaner:
Vector3 center = hit.transform.collider.bounds.center;
Instantiate(Prefab, center, Quaternion.identity);
hit.transform.collider is a vital part of this process and you got that part. collider.bounds is the bounding box that surrounds the collider (http://docs.unity3d.com/ScriptReference/Collider-bounds.html), and bounds.center is the center of the bounding box (http://docs.unity3d.com/ScriptReference/Bounds-center.html). The Vector3 that bounds.center returns is where you want to spawn your prefab.
From there, you should be able to rotate the prefab to the desired angle and perform any number of operations you want.