Blender models not being detected by Physics.Raycast() - unity3d

I'm relatively new to Unity. I'm making a Chess Game. In the screenshot below, you see the following GameObjects:
3D Planes as the squares.
Blender models for chess pieces.
For now, here's a very basic script I'm using to detect the clicked object and delete it (will add more functionality later).
void Update () {
if (Input.GetMouseButtonDown(0))
{
Ray ray = mainCamera.GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//highlightPiece(hit.transform.gameObject, whiteSelectedTexture, false);
Destroy(hit.transform.gameObject);
}
}
}
The problem is that the GameObjects native to Unity (the plane objects making the squares) are detected by the ray cast but the blender models are not. This is confirmed by the screenshot since the closest object should be detected. The script ended up deleting the squares but not the chess pieces (which I actually plan to select and work on).

You surely haven't added a Collider to your imported Blender Objects.
Select every chess pieces and add a BoxCollider / CapsuleCollider.
By the way, I think you can remove the Collider of the chess plate.
Moreover, I highly recommand you to use layers when you raycast so as to be even more efficient. Check the following Unity article : https://unity3d.com/fr/learn/tutorials/topics/physics/physics-best-practices

Related

Making player character behave as if using mouse events Unity

I have a game that has a player ship hovering a fixed distance over a tower defense grid. I'd like the tile beneath the ship to highlight when the ship is over it. By using the OnMouseOver() function, this is quite easy, however, I do not want this to be controlled by the mouse but by the player ship. Is there a way to pass mouse event simulations to a game object? How would i go about assigning this function to the ship?
Like derHugo siad you can use OnTriggerStay(). Altough you can also use a raycast to check if something is underneath the ship:
public void FixedUpdate()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit, 10f))
{
//Here obj will be filled with the gameobject under your ship. You can use this to check for the tag, get components and outline the object.
var obj = hit.transform.gameObject;
}
}
Hope this sets you into the right direction.

How to I add and delete objects from an AR scene using unity ARKit

I need to create an a furniture dropping app. While I have managed to figure out how to rotate scale the object and detect planes in AR world, I also need to enable the users to be able to choose from a list of furniture, add multiple furniture into the scene and also delete them as when they like. I can't seem to find any tutorials that teach this. There are plenty with ViewAR and Vuforia but since it is a school project, I am restricted to using the ARKit plugin in Unity. Any help in this would be highly appreciated!
So currently what I am doing is, I create an empty gameObject to which I attach a script that has the function call AddObject which is as such:
public void AddObject()
{
GameObject summonedFurni = Instantiate(prefab);
summonedFurni.transform.position = new Vector3 (0f, 0f, 0f);
summonedFurni.transform.localScale = new Vector3 (10f, 10f, 10f);
summonedFurni.AddComponent<Rigidbody> ();
furniList.Add (summonedFurni);
//summonedFurni.SetActive (true);
}
Each type of furniture is a separate gameObject to which the script is attached to.
However, firstly the instantiated objects can't detect the plane and fall right through it. Adding a BoxCollider component simply causes all the furniture to stack up above me in the real world. Also I am unable to delete any objects from the scene as I am unable to keep track of the created objects. Any advice on this?
Adding a BoxCollider component simply causes all the furniture to
stack up above me in the real world.
Try adding z position. By default z is 0. Which is your position as well. That's why it is stacking up above you.

How to calculate the length of platform/object in Unity 5?

I'm new to Unity and after watching and reading some tutorials I'm now trying to make a simple 2D platformer kind of game. In the said game both enemies and player can jump to different platforms and traverse it like the old SnowBros game.
The problem I'm facing is related to programming the enemy movement. In my game there would be several types of enemies but generally for now there are two types, one that can jump from the platform and one that only walks upto the length of the platform, wait for 1 second then flip and walk backwards; meaning they don't get off the platform. Now this is an issue I'm having trouble with. I can't seem to find a way to calculate the length of the underlying current platform. I thought of using the collider.bound.min.x and max.x to come around the problem but the issue is I can't seem to find a simple way to reach the current platform's collider without fetching the script and then going through it.
Since, there would be many platforms of many different sizes and each platform is made up of a prefab of other platforms, it just doesn't seem like a workable solution to use the platform script and then traverse through it.
You can use Physics2D.Raycast to "sense" for collisions on a Ray. Imagine the enemy putting their toe one step forward, feeling if there is still solid ground, and then deciding whether to stop.
void Update()
{
Vector2 newPosition = transform.position + velocity * Time.deltaTime;
Vector2 downwardDirection = Vector2.down; // you may have to replace this with your downward direction if you have a different one
RaycastHit2D hit = Physics2D.Raycast(newPosition, downwardDirection);
if (hit.collider != null)
{
// solid ground detected
transform.position = newPosition;
}
else
{
// no ground detected. Do something else...
}
}
You can and should define the Layers your Raycast is supposed to hit, so it can ignore the enemy itself and avoid self-collision.
Well, I hope that you have prefabs of platform and in those prefabs put colliders at start and at end. You can specify layers and tags so that only enemy can detect those colliders and then you can detect tags on collision from enemy script and make your operation.
First create layers by opening Edit -> Project Settings -> Tags and Layers. Create two Layers
Create layers for enemy and enemyColliders and Goto Edit -> Project Settings -> Physics2D. Set collision matrix as EnemyCollider will collider with enemy only.
And your prefab will be looks like,
I hope this would help you.

Collision Detection of objects in certain area of camera in Unity3d

I am creating a 3rd person action game where the player is a helicopter and he can shoot other objects while moving. The problem is I am trying to find the enemy objects who are inside a circle in the center of the camera and I need to track them and shoot them.
Raycast wouldn't help as i need a thicker raycast and so I tried spherecast and capsulecast.
I have a GUI element which gives the player idea on where he can shoot.When using Spherecast or Capsulecast, It is working when the enemy is near but when the enemy is far behind I guess the spherecast becomes small while traveling along z and doesn't hit the object most times.
if (Physics.SphereCast (startPoint, 1f, transform.forward, out hit)) {
if (hit.collider.CompareTag ("Shootable") ){
Debug.Log(hit.collider.name);
Destroy(hit.collider.gameObject);
}
}
I have seen raycast from camera and so i was wondering if there is something to do like circlecast from the camera which would be appropriate for this. If not how can I proceed?
Any help is really appreciated.
If you want to detect whether enemies lie within a conical area in front of your camera, using a SphereCast or RayCast will not be able to meet your needs.
Instead, you might consider checking the angle between an enemy's relative position and your camera's forward vector, to see if it is below a particular value, and hence within the cone.
For a 60-degree field of view, and assuming you store your enemy Transform components in an array/List, your code might look like:
foreach (Transform enemy in enemies){
if (Vector3.Angle(transform.forward, enemy.position - transform.position) < 30){
Destroy(enemy.gameObject);
}
}
Hope this helps! Let me know if you have any questions. (Answer adapted from this Unity question.)

Raycast without using a collider

I am doing a Voxel game and my engine was using Physics.raycasts and Mesh colliders for getting the coordinates of the block you clicked on until now. I decided to remove the mesh collider, because it was just eating too much performance in some situations and I got fps dropdowns to 0.1fps for a few seconds (eg you should be able to scroll through the y-layers) and I only needed it for raycasting. I don't use any other physics related stuff. Without the mesh colliders the framerate is stable at 60 to 100 fps, but now I find it hard finding another way getting the information on which block I am clicking.
Any suggestions?
So far I was using this piece of code:
public Vector3? GetBlockCursor(){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray, out hit)) {
hit.point += (hit.normal * -0.5f);
hit.point = new Vector3(Mathf.RoundToInt(hit.point.x), Mathf.RoundToInt(hit.point.y),
Mathf.RoundToInt(hit.point.z));
return hit.point;
}
else return null;
}
Hard to say as it always depends on the game logic what and where optimisations are efficient. Basically one or a few ray cast(s) per frame should not be a big deal for PhysX, so I think there are other culprits. Some Suggestions (maybe you have considererd them already):
Use compound colliders especially box and sphere s. Rigidbody manual
Always attach rigidbodies to moving items
Limit the calls to GetBlockCursor to once per Update or even less by calling it every 2nd or 3rd Update only
If you need more than one raycast consider using Physics.RaycastAll
If the physics engine is to blame for significant frame rate Drops, check whether you can use layers to optimise calculations
Use the profiler (provided you have Pro license)