I am trying to cast a ray from inside source to Sphere.
my main camera position (0,0,0)
Sphere position (0,0,0) radius : 300
I want to know hit.position and hit.collider.gameobject
I am trying this below tutorial.
http://answers.unity3d.com/questions/129715/collision-detection-if-raycast-source-is-inside-a.html
Even if I tried tutorial, I can not see desirable result from console window.
(no Debug.Log result in my console window)
What should I have to do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EyeTrackingPoint : MonoBehaviour
{
public float sphereRadius = 300; // position(0,0,0) radius 300
public GameObject screen3D; // sphere
public void Update()
{
Camera cam = Camera.main; // position(0,0,0)
RaycastHit hit;
Ray ray = new Ray(cam.transform.position,cam.transform.rotation * Vector3.forward * sphereRadius );
ray.direction = -ray.direction;
if (Physics.Raycast(ray,out hit)&&hit.collider.gameObject.Equals(screen3D))
{
Debug.Log(hit.point);
}
}
}
Thank you for reading.
Raycast in unity has to be conform to these things; Use a worldpoint from where the ray should originate. Use a direction for that ray. And u need to specifiy in which layer it is supposed to check. On top of that only objects with colliders can be hit, even if the gameobject is in the correct layer but doesn't have a active collider nothing will happen. Example ;
{
RaycastHit hit = Physics.Raycast(start, direction, 1000f, 1<<10);
}
The information of a successful raycast is saved in a RaycastHit;
The 1000f is a float value that limits the range of the raycast That way u can control how far it looks for an object.
If u do not specify the layermask in the raycast it will return the first object hit with any kind of active collider regardless in which layer it is.
Raycasts from inside colliders do NOT generate collisions.
if (Physics.Raycast(Vector3.zero, Vector3.up, 100))
Debug.Log("HIT");
"Hit" will never be written in console if a sphere is around the 0,0,0 world origin. When you move the sphere out , over and away from the origin, you will see it printed.
Those are impact in backfaces. You can enable it, though, enabling the checkbox in the Physics settings. See the documentation on this parameter on c# too: https://docs.unity3d.com/ScriptReference/Physics-queriesHitBackfaces.html
Related
I'm currently trying to have a raycast detect the player caracter to have an event happen when a specific key is pressed here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class action: MonoBehaviour
{
public float dist;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
RaycastHit2D down = Physics2D.Raycast(transform.position, -Vector2.up, dist);
Debug.Log(transform.position);
if (Input.GetKeyDown(KeyCode.Z) == true && down.collider != null)
{
Debug.Log("hi");
}
}
}
I'm basicly trying to make a small raycast,which is why I place a distance instead of letting it go infinitely, and have it so if the raycast is triggered and the player presses z the event happens(which for now is the debug console), but all it does now is triggers whenever I press z no matter where the player caracter is. I tried drawing the raycast but I can't seem to make it work.
I think the reason for that is that the raycast is hitting the object containning the script it self and so the collider is allways non null try adding a LayerMask that differs from the GameObject's Layer
so it's something like this :
RaycastHit2D down = Physics2D.Raycast(transform.position, -Vector2.up,
dist , 1 << /*The Target's Layer*/);
You can find the layer in the up left corner of your inspector when you click on a GameObject
You have not provided a LayerMask on the down. The Raycast must be colliding with the player's Collider. In case you don't know what LayerMask is.
LayerMask can be used to detect Raycast that collides with only the objects with that layer on it.
The ayer Dropdown, on each GameObject, refers to the layer of the object as shown:
Head to the Unity Documentation for LayerMask for more details.
If you want make raycast when press Z will be good to do it in time press:
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Z)){
RaycastDown()
}
}
private void RaycastDown()
{
Debug.Log("Player position: " + transform.position);
RaycastHit2D hit = Physics2D.Raycast(transform.position,
Vector2.down, dist);
if(hit.collider != null){
Debug.Log($"Hit object: {hit.transform.name}" );
}
}
And about issue, make sure that hit object has a collider or collider is active.
Possibly problem in raycast direction. To check it, use Debug.DrawRay, it`s help you to visualize a ray which you draw
i am working on an enemy for my game that follows you until it doesnt see you anymore.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class pathfindingPlayer : MonoBehaviour
{
RaycastHit hit;
NavMeshAgent _navMeshAgent;
void Awake() => _navMeshAgent = GetComponent<NavMeshAgent>();
public bool seen;
public float noticeDistance = 7f;
void Update()
{
Debug.DrawRay(transform.position, transform.forward * noticeDistance, Color.red);
Ray PlayerRay = new Ray(transform.position, Vector3.back);
if(Physics.Raycast(PlayerRay, out RaycastHit hitInfo, noticeDistance))
{
if (hitInfo.collider.CompareTag("Player"))
{
Vector3 SeenPlayer = hitInfo.point;
_navMeshAgent.SetDestination(SeenPlayer);
}
}
}
}
Now the problem is that there is only one Raycast being shot out. Therefore the enemy only runs in one direction. Is there a way to add multiple raycasts to this or do i need to rewrite the code? Thanks in advance
You can make a function that makes raycasts and call it every x seconds, but for what you want to achieve i would try putting a circle collider on the enemy with the radius of how far the enemy can see and make sure to set the collider as trigger, then make it go towards the player if the player triggers the collider
I am using unity 2018.3.5f1 so a few solutions to this problem don't work.
Starting from the Roll-A-Ball demo project, I want to extend the camera script to follow the player, but also keeping track of the direction of movement. Ex: If the ball starts moving to the side, I need the camera to rotate around the player's axis to position behind him, and then start following him.
I have tried making the camera a child to the ball i'm trying to control and i've tried making a script but it won't follow the ball correctly it keeps rotating the camera as well as the ball (i'm using this bit of code and trying to modify it as it's the only one that works)
here is the code I have at the moment:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
I understand why it is rotating but no reasearch is helping me find out how to lock the camera so it is looking behind the ball at all times
Have you tried adding some restraints to your camera? If it is only supposed to turn to follow the ball, you can freeze the position of 2 axes (x and z), and only let the camera rotate around the y axis of the ball.
You can play around with the restraints on the Inspector, or use GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX; in the camera script.
(EDIT) Sorry, this is how you would do it if the gameObject has a rigidbody, but the idea is the same if it doesn't have one.
When you're setting the position or rotation of the camera, think about which components of the position/rotation you actually want to change (x,y,z).
Use offset = new Vector3 (offset.x, offset.y, offset.z)and replace anything that shouldn't change with a constant.
Also, when you made the Camera the child of the ball, you could have set it so that every frame, the Camera updates in such a way that it won't roll with the ball. You could do this by putting code in the update method of the camera that sets the component x, y, or z equal to some constant. Whatever axis the ground plane is on is probably the correct choice.
If you want the same camera angle that the camera should follow while following the ball (similar to Temple Run), then try the below code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CompleteCameraController : MonoBehaviour
{
public Transform Player;
public float distanceFromObject = 3f;
void Update()
{
Vector3 lookOnObject = Player.position - transform.position;
lookOnObject = Player.position - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
playerLastPosition = Player.position - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = Player.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
When the ball moves left or right, the camera will follow the same angle as the ball moves towards.
I am currently using mouse inputs to move a player (sphere) in a 3d world. I am doing this with a raycast and using the hit.point coordinates. This is the way I want my game to work, but it is a 3d game, so whenever I move the player, using the mouse coordinates, it won't align properly. This is due to the player being 3d and the mouse coordinates being 2d.
Here is my code:
public float speed;
public GameObject player;
private Ray ray;
private RaycastHit hit;
private Vector3 mousePos;
void Start ()
{
}
void FixedUpdate ()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit))
{
mousePos = new Vector3(hit.point.x, /*Insert Code*/, hit.point.z);
if(mousePos != player.transform.position)
{
player.transform.position = Vector3.MoveTowards(player.transform.position, mousePos, speed * Time.deltaTime);
}
}
}
My question is this:
If I have the player at 1.3f above the ground, how can I manipulate Vector3.MoveTowards so the mouse is centered in the player without affecting the height of the player (1.3f)?
I tried using player.transform.position.y, but it placed the mouse directly under the player (the x and z values worked, but the y-value didn't).
I, also, tried hit.point.y, but it gave me values greater than the player height (1.3f).
This might not be the best way to solve my issue but it solves it for now. I made a plane with a y value of 1.3f and put it through the player object. I, then, made the object invisible. Now, the raycast will hit that object instead of the ground.
I have a character controller which moves along the z-axis with a constant speed. I'd like to know the floor name under the character controller. The Character controller never collides with the floor. It's a parallel movement. I used a Raycast to find the floor in C# using:
myray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(myray, myhit, 1000)) {
Debug.DrawLine (ray.origin, hit.point);
print(myhit.collider.name);
}
This gives an error. Is there a better solution for this?
It's hard to tell what your issue is, but attaching this behaviour to your character-controlled object will get the name of the first object the raycast hits.
I'm using an inverted layer mask to ignore the "Player" layer, which I set the character-controlled object to. This is so the raycast doesn't hit the object before the floor.
using UnityEngine;
using System.Collections;
public class GetFloorName : MonoBehaviour
{
public string NameOfRaycastHitObject;
void Update ()
{
RaycastHit hitInfo;
int layerMask = ~(1 << LayerMask.NameToLayer("Player"));
float distance = 100f;
if (Physics.Raycast(transform.position, Vector3.down, out hitInfo, distance, layerMask))
{
NameOfRaycastHitObject = hitInfo.collider.name;
}
}
}