probably is too easy but.....
This Script is working well, got it from Boris Media it shows a text when the character enter in the box collider, I do not use characters I am using a 3D model so the user has to touch the model, not walk through the game.
Thanks in advance.
#pragma strict
var note : GameObject;
function Start () {
note.SetActive (false);
}
function OnTriggerEnter () {
note.SetActive (true);
}
function OnTriggerExit () {
note.SetActive (false);
}
Here is an example in C# but it shouldn't be too hard to convert to JavaScript if you need to:
Vector2 touchPos = Input.GetTouch(0).position;
Ray ray = Camera.main.ScreenPointToRay(new Vector3(touchPos.x, touchPos.y, 0));
RaycastHit hit;
if (Physics.Raycast (ray, out hit)) {
// The user's touch has collided with something now we have to check what it collided with
// You can also use hit.point if you want to get the position of the touch in the world
if (hit.collider.tag == "GameObjectTag") {
Debug.Log("Hit " + hit.collider.name);
hit.collider.gameObject.setActive(true);
}
}
Related
so, basically, I have created a pretty simple turret script that basically just smoothly aims at the player, so long as the player is within a certain amount of range. The problem I am having, is that the Raycast I wrote that actually checks if the 'bullet' (which is nothing - it's just a raycast), would hit the target. This means that even if the player hides behind a wall, the turret can still shoot him.
My current raycast script allows the raycast to go straight through the wall, and since I am new to Unity, I have no idea how to make it check if the first object it hits is the player, so that it cannot go through walls.
Here is my current raycast script:
void Shoot()
{
//I think the problem is here - I want the raycast to return false if it hits a wall - which has the layer "ground", and true if it hits the player. Problem is, I need to make the turret return to resting position when the player is behind a wall.
//To do this, I can just set inRange = true; But I need to be able to determine when the player is behind a wall.
LayerMask layerMask = LayerMask.GetMask("Player");
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity, layerMask))
{
//This determines how much damage will the player take.
int damage = Random.Range(1, 5);
hit.collider.gameObject.GetComponent<playerMovement>().Shot(damage);
//I personally THINK this means that it only triggers collisions with the player, which is why it is not working.
// The player has layer "Player", and tag "Player", so if anyone who wants to help can figure out how to make it stop when it hits anything - and then only return true if it hit the player (meaning the player is not behind walls).
}
}
If you want to check if there is anything between the player and the Raycast, then simply remove the Layermask
Change this:
LayerMask layerMask = LayerMask.GetMask("Player");
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity, layerMask))
To this:
Ray ray = new Ray(transform.position, transform.TransformDirection(Vector3.forward));
if (Physics.Raycast(ray, out RaycastHit hit) {..}
You want to
remove the check for the layer in order to hit everything with the raycast
then you can use TryGetComponent to check whether the hit object has such component attached or not
and in general instead of
transform.TransformDirection(Vector3.forward)
simply use transform.forward ;)
So something like
void Shoot()
{
if (Physics.Raycast(transform.position, transform.forward, out var hit))
{
// Without the need for any tag or layer check
// Simply check if the object you hit has a playerMovement component
// GetComponent was improved a lot lately and now uses hashes
// it's not that performance intense anymore and almost as fast as CompareTag
if(hit.gameObject.TryGetComponent<playerMovement>(out var movement)
{
int damage = Random.Range(1, 5);
movement.Shot(damage);
}
}
}
All you'd need to do is cast from the turret to the player and detect what the raycast has hit. Your current code is setting a mask to only be on the player, so it will never hit a wall. You can change your code to something like this:
private LayerMask layerMask = (1 << LayerMask.NameToLayer("Player") | (1 << LayerMask.NameToLayer("ground")));
void Update () {
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out RaycastHit hit, Mathf.Infinity, layerMask))
{
if(hit.collider.gameObject.layer == LayerMask.NameToLayer("Player"))
{
// you can shoot as you see the player
}
else
{
// you hit the ground - player is behind a wall
}
}
}
I'm really surprised by what I see in my Unity3D project and was wondering if anyone has an explanation as I didn't find one after looking for it on google.
So I have a project where I instantiate multiples objects, which are basically cubes, with their colliders (not triggered) and where I want to know if the mouse is over one of them.
So I attached a very basic script taken from the unity documentation:
void OnMouseEnter()
{
Debug.Log("enter block " + this.name);
// Change the color of the GameObject to red when the mouse is over GameObject
m_Renderer.material.color = m_MouseOverColor;
}
void OnMouseOver()
{
Debug.Log("over block " + this.name);
// Change the color of the GameObject to red when the mouse is over GameObject
m_Renderer.material.color = m_MouseOverColor;
}
void OnMouseExit()
{
Debug.Log("exit block " + this.name);
// Reset the color of the GameObject back to normal
m_Renderer.material.color = m_OriginalColor;
}
And I don't seem to see any result. While looking for options I scaled the collider box to way bigger and can get some results, but they are not precise, the mouse needs to be slightly on the side of the cubes to work. It looks like a perspective effect caused by hte size of the collider by that would be annoying for the final user.
So I tried to use a simple raycast test in a script attached to the camera:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100000000, LayerMask.GetMask("TrackPartEnd")))
{
Debug.DrawRay(ray.origin, ray.direction * 100000000, Color.blue, 3);
myCursorObject.transform.position = hit.point;
}
else
{
if (Physics.Raycast(ray, out hit, 100000000, LayerMask.GetMask("Floor")))
{
Debug.DrawRay(ray.origin, ray.direction * 100000000, Color.green, 3);
myCursorObject.transform.position = hit.point;
}
else
{
Debug.DrawRay(ray.origin, ray.direction * 100000000, Color.red, 3);
}
}
And with this one I get a really good result, it's fast and really precise.
But I didn't find any explanation on why? To my knowledge, OnMouseOver uses raycast as well. I've double-checked and I don't see anything blocking the rays neither.
Does anyone have an explanation?
I have a Physics Raycaster attached to the Camera. The Pointer Click Event Trigger is working correctly. However I need to do it from the source code. These are my attempts:
private void SetOnPushButtonFireManager(){
cardboard.OnTrigger += () => {
Debug.Log("Button triggered!");
RaycastHit hit;
// if(Physics.Raycast(headGameObject.GetComponent<GvrHead>().Gaze, out hit, Mathf.Infinity)){
if(Physics.Raycast(cameraGameObject.transform.position, cameraGameObject.transform.forward, out hit, Mathf.Infinity)){
Debug.Log("Collision detected!");
}
};
}
"Button triggered!" is shown in the Console. Unfortunately "Collision detected!" is not. However the Pointer Click Event Trigger is working correctly (the component attached in the inspector). How can I know what is going on? Why isn't it working?
UPDATE: I have answered this answer here: http://answers.unity3d.com/answers/1200449/view.html
(stackoverflow does not allow me to delete this question)
Here's some code I've been using to fire a ray from the camera. I don't have Google Cardboard, this was setup for a camera and a mouse pointer.
// Fire ray from camera
float rayLength = 2f
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
// If ray hits object within length
if (Physics.Raycast(ray, out hit, rayLength))
{
Debug.Log("Collision detected!:);
}
It didn't work for me either, in the end, I forgot to put the "GvrPointerPhysicsRaycaster" class in the camera. Inspector Image
Once added, it worked perfectly.
void Update()
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, Mathf.Infinity))
{
if (activeSelected == null)
{
if (hit.collider.tag == "Plane")
activeSelected = Instantiate(mainApp.mainModel.preafabSelect, hit.point, Quaternion.LookRotation(hit.normal));
} else
{
activeSelected.transform.position = hit.point;
activeSelected.transform.rotation = Quaternion.LookRotation(hit.normal);
}
}
}
I am trying to create a maze game where the player can move only when it can see a sweet.
Currently the raycast is searching in every direction (360 degrees) But I only want the raycast to look directly Up,Left,Down,Right (instead of 360 degrees)... This way the player can only move when a sweet is placed in direct line of sight.
public function setTargetSweet(target:GameObject)
{
too = target.transform.position;
targetSweet = target;
var fwd = too - transform.position;
Debug.Log("Setting target sweet: " + target.name);
Debug.DrawRay(transform.position, fwd, Color.red, 5f);
Physics.Raycast (transform.position, fwd, hit);
if ( hit.collider.tag == "MoveToSweet") {
print ("Can See Sweet");
gotoSweet = true;
}
else
{
Debug.Log(hit.collider.name);
Debug.Log(hit.collider.tag);
gotoSweet = false;
}
}
You're doing ray casts in the direction of any sweet every time. You want four calls like Physics.Raycast(transform.position, Vector3.forward, hit) and check the hit between calls.
I have a camera looking down on my game world. I want to allow the user to click on objects. The following script is attached to the MainCamera.
void Update () {
if (holdingSomething)
{
if (Input.GetMouseButtonUp(0))
{
holdingSomething = false;
}
}
else if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Vector3 mousePos = new Vector3(Input.mousePosition.x,Input.mousePosition.y,0);
Vector3 rayOrigin = new Vector3(Camera.main.ScreenToWorldPoint(mousePos).x,Camera.main.ScreenToWorldPoint(mousePos).y,Camera.main.transform.position.z);
Vector3 rayDirection = new Vector3(Camera.main.transform.rotation.x,Camera.main.transform.rotation.y,Camera.main.transform.rotation.z);
Debug.Log("Mouse button is down" + mousePos);
Debug.Log("rayOrigin " + rayOrigin);
Debug.Log("rayDirection " + rayDirection);
Ray ray = new Ray(rayOrigin,rayDirection);
if (Physics.Raycast(ray, out hit))
{
Debug.Log("We just touched " + hit.collider);
}
}
}
The line Debug.Log("We just touched " + hit.collider); is never called. I don't think my ray is being built right. Here is the output of the other debug messages. At each message they rayOrigin is the same, even though the mousePos changes.
Mouse button is down(418.7, 195.1, 0.0)
rayOrigin (0.0, 6.2, -7.3)
rayDirection (0.3, 0.0, 0.0)
Mouse button is down(417.7, 278.0, 0.0)
rayOrigin (0.0, 6.2, -7.3)
rayDirection (0.3, 0.0, 0.0)
So where am I going wrong?
I would define your Ray like this:
Ray ray = Camera.Main.ScreenPointToRay(Input.mousePosition);
As for your code, I can't test your code right now so I don't know what exactly goes wrong. Because you should be able to do as you described, even though my answer is an easier alternative.
You can use Debug.DrawLine to draw a line of the raycast you use. Then, you can see what your raycast looks like in the debugger, during runtime. You can see then how your raycast is positioned. You'd be able to see the start and end point of the ray. If one of them is off, you can check your code while knowing which part is wrong.