My raycast passes through objects with mesh collider/box collider with layers.
I can't seem to find a solution. Please help me.
I tried different solutions but the raycast still passes through objects. Even objects behind intractable objects are also being called out.
public float maxRayDistance = 2.0f;
public LayerMask layerMask;
public GUISkin mySkin;
public bool showGui = false;
public RaycastHit hit;
void Update()
{
Vector3 dir = gameObject.transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, dir, out hit, maxRayDistance, layerMask))
{
showGui = true;
if (Input.GetButtonDown("Use"))
{
Invoke("SendAction", 0.3f);
}
}
else
{
showGui = false;
}
}
public void SendAction()
{
GameObject target = hit.collider.gameObject;
target.BroadcastMessage("Action");
}
Layers
Object with Layer other
You need to check IsTrigger in Collider (UnityEditor) to have Raycast working on your object.
If this is not working, there is a setting in your projets about Raycast that you might have turned off in Physics Settings.
Related
NullReferenceException: Object reference not set to an instance of an object
DragBlock.Update () (at Assets/Script/DragBlock.cs:13)
using UnityEngine;
public class DragBlock : MonoBehaviour
{
private bool isBeingHeld = false;
private Vector3 startPos;
private Transform heldObject;
private void Update()
{
if (Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.CompareTag("Blocks"))
{
isBeingHeld = true;
startPos = hit.transform.position;
heldObject = hit.transform;
}
}
}
if (isBeingHeld)
{
Vector3 currentMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
currentMousePos.z = heldObject.position.z;
heldObject.position = currentMousePos;
}
if (Input.GetMouseButtonUp(0))
{
isBeingHeld = false;
}
}
}
I tried to change the group of the object tried to check the position and so on in this code it should check the position of the mouse and drag the object with the Blocks tag
If line 13 is this one...
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
... then the only part of the code that could realistically be null is the Camera.main property. Camera.main is returned by Unity when Unity looks for, and finds, a Camera in your scene that's tagged "MainCamera".
I suggest that you might have removed or changed that tag of the Camera, or a parent of the camera, and now Unity can't find an appropriate camera.
This is echoed in the online documentation https://docs.unity3d.com/ScriptReference/Camera-main.html
[![ hey guys so i need help please! i need my claw hand to be able to grab my object holder(orange thingy next to the red ball. my objectholder has a spring joint already so I want my clawhand to be able to grab it and pull it with the ball. When my hand opens then it shoots. But when I try to grab it, my hand goes right through.
My claw hand has rigidbody,box collider,configuration joint and is animation by this code
public class open2close : MonoBehaviour
{
public float speed;
private Animation anim;
Rigidbody rb;
void Start()
{
anim = gameObject.GetComponent<Animation>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
//********************Open pincher ********************
if (Input.GetKey(KeyCode.X))
{
anim.Play("clawopen");
}
//*******************Close pincher ********************
if (Input.GetKey(KeyCode.Y))
{
anim.Play("clawclose");
}
}
}
as for my object holder it has box collider,spring joint, rigidbody, and rotation constraint. Can someone guide me or help me in what i can do thank you.
It is probably best to not have a collider on the claw hand. This is because you are mixing rigidbodies with animation, which can get messy. I would reccomend keeping everything, excpt for the box collider on the claw hand. Set it to a trigger. You can put booleans in the if statements to open and close the claw. This way, you can set the position of the objectholder to be at the claw (if they are touching).
Change your script to something like
public class open2close : MonoBehaviour
{
public float speed;
private Animation anim;
[SerializeField] bool isClosed;
Rigidbody rb;
void Start()
{
anim = gameObject.GetComponent<Animation>();
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.X))
{
anim.Play("clawopen");
isClosed = false;
}
if (Input.GetKey(KeyCode.Y))
{
anim.Play("clawclose");
isClosed = true;
}
}
void OnTriggerStay(Collider obj)
{
Rigidbody colRb = obj.attachedRigidbody;
if (colRb != null && isClosed)
{
colRb.position = transform.position;
}
}
}
Let me know if this works and be specific! thanks :)
I am currently am making a detail with blood where when the player shoots an enemy, a object spawns with a random sprite to represent blood. The problem is that the sprite simply only spawns in the same angle. I tried looking up how to get the angle of the bullet to give it to the newly spawned object. Does anyone here know how to get such a angle? so I could give it to another object? here are both scripts incase it helps
// Script for the gun
public Transform firepoint;
public GameObject bulletprefab;
public float bulletforce = 20f;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shoot();
}
}
void Shoot()
{
GameObject bullet= Instantiate(bulletprefab, firepoint.position, firepoint.rotation);
Rigidbody2D rby = bullet.GetComponent<Rigidbody2D>();
rby.AddForce(firepoint.up * bulletforce, ForceMode2D.Impulse);
SoundEffectScript.Playsound("gunshot");
}
// script for the blood object so far
private int rand;
public Sprite[] sprites;
void Start()
{
rand = Random.Range(0,sprites.Length);
GetComponent<SpriteRenderer>().sprite = sprites[rand];
}
I've created a simple scene and I'm now trying to make a rabbit move to the mouse-click position on a Plane.
So I've added a Rigidbody, a Nav Mesh Agent and a simple "Pathfinding" script to the rabbit.
The planes Mesh Renderer is set to "Navigation Static", "Generate OffMeshLinks" and "Walkable"
Now as soon as the rabbit gets close to the given destination, it will not stop but rather is "running around" in a very small circle around the destination.
Here is my script
using UnityEngine;
using UnityEngine.AI;
public class Pathfinding : MonoBehaviour {
private NavMeshAgent agent;
private Animator animator;
// Use this for initialization
void Start() {
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update() {
RaycastHit hit;
if(Input.GetMouseButtonDown(0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit)) {
agent.SetDestination(hit.point);
animator.SetInteger("AnimIndex", 1);
animator.SetBool("Next", true);
}
}
}
}
and a picture of my rabbit object ;)
Stopping Distance should be > 0
Actually I was wrong, updating Unity didn't fix the problem, but I recognized that the problem was that the animations "Root Transformation Position (XZ)"/ Bake Into Pose was deactivated.
I also changed my script to
using UnityEngine;
using UnityEngine.AI;
public class Pathfinding : MonoBehaviour {
private NavMeshAgent agent;
private Animator animator;
private bool run = false;
// Use this for initialization
void Start() {
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update() {
RaycastHit hit;
if(Input.GetMouseButtonDown(0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit)) {
Debug.Log("start");
agent.SetDestination(hit.point);
animator.SetInteger("AnimIndex", 1);
animator.SetBool("Next", true);
run = true;
}
}else if(agent.remainingDistance <= agent.stoppingDistance && run) {
Debug.Log("stop");
animator.SetInteger("AnimIndex", 0);
animator.SetBool("Next", true);
run = false;
}
}
}
Is it possible to have two colliders for one object?
My situation is that I have a CircleCollider2D that causes my enemy to chase the player when it enters. This works well but I want to also have a BoxCollider2D that will switch scene to my scene called "BattleScene" when the player enters.
I want it so that when my player enters the circle collider my enemy will follow him but when the player gets closer and enters the box collider (both attached to the enemy) it will switch scenes to the scene called "BattleScene".
Another alternative I thought of was using a rigid body collision but I don't know how to implement that.
Here is my code
private bool checkContact;
private bool checkTrigger;
public float MoveSpeed;
public Transform target;
public Animator anim;
public Rigidbody2D myRigidBody;
BoxCollider2D boxCollider;
public string levelToLoad;
// Start is called before the first frame update
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();//getting the position of our player
anim = GetComponent<Animator>();
myRigidBody = GetComponent<Rigidbody2D>();
boxCollider = gameObject.GetComponent<BoxCollider2D>();
}
// Update is called once per frame
void Update()
{
if (checkTrigger == true)
{
transform.position = Vector2.MoveTowards(transform.position, target.position, MoveSpeed * Time.deltaTime); //move towrds from your position to the position of the player
if (myRigidBody.position.y < target.position.y && Mathf.Abs(target.position.y - myRigidBody.position.y) > Mathf.Abs(target.position.x - myRigidBody.position.x)) //if it is further away from target in x direction than y direction the animation for moving in y is loaded and vice versa
{
anim.SetFloat("MoveY", 1);
anim.SetFloat("MoveX", 0);
}
if (myRigidBody.position.y > target.position.y && Mathf.Abs(target.position.y - myRigidBody.position.y) > Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveY", -1);
anim.SetFloat("MoveX", 0);
}
if (myRigidBody.position.x > target.position.x && Mathf.Abs(target.position.y - myRigidBody.position.y) < Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveX", -1);
anim.SetFloat("MoveY", 0);
}
if (myRigidBody.position.x < target.position.x && Mathf.Abs(target.position.y -myRigidBody.position.y) < Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveX", 1);
anim.SetFloat("MoveY", 0);
}
anim.SetBool("checkTrigger", checkTrigger); //updating if in range
}
}
public void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.name == "Player")
{
checkTrigger = true; //setting our check trigger = true so it will follow if in radius
anim.SetBool("checkTrigger", checkTrigger);
}
}
public void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.name == "Player")
{
checkTrigger = false; //setting our check trigger = false so it will not follow if not in radius
anim.SetBool("checkTrigger", checkTrigger);
}
EDIT: THIS PROBLEM HAS BEEN RESOLVED
The best way to handle this is by having an empty GameObject with the other collider attached to it, while making sure both GameObjects have a Rigidbody - the child with IsKinematic ticked. Why? Because this will separate the child GameObject from the parent collision structure. Read more about compound colliders.
You should only have more than one collider in one GameObject if they all make part of the same collision structure. If they have different purposes, use different GameObjects with kinematic Rigidbodies, each handling it's own task.
In your specific scenario, I would have the CircleCollider in the enemy itself and the BoxCollider in a child GameObject with a kinematic Rigidbody. This child GameObject can also contain a script with the sole purpose of checking against the Player and loading the BattleScene.