How can I raycast between two moving objects?
I want to raycast from a moving enemy to a moving player. I dont know how to actually code to make the direction work.
using UnityEngine;
using System.Collections;
public class Enemy_Manage_Two : MonoBehaviour {
public GameObject player;
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update () {
player = GameObject.FindGameObjectWithTag ("Player");
//Debug.Log (player.transform.position + " " + transform.position);
Ray ray = new Ray (transform.position, player.transform.position);
RaycastHit hit;
Debug.DrawRay (transform.position, player.transform.position,
Color.red);
if(Physics.Raycast(ray, out hit)) {
gameObject.renderer.material.color = Color.blue;
} else {
gameObject.renderer.material.color = Color.white;
}
}
}
Currently I haven't Unity so treat my answer as proof of concept.
//1. You have to calculate vector between enemy and player:
Vector3 direction=player.transform.position - transform.position;
direction.Normalize(); //Normalize vector
//2. Now you can create Ray
Ray ray=new Ray(transform.position,direction);
Related
So I'm working on a little top-down perspective game and wanted to add a combat system. I set it up so that it'll shoot a raycast and if it hits an enemy they'll take damage but the raycast is returning nothing.
Vector3 mouse_pos = Input.mousePosition;
mouse_pos.z = 5.23f;
Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
mouse_pos.x = mouse_pos.x - objectPos.x
mouse_pos.y = mouse_pos.y - objectPos.y
if (Input.GetMouseButtonDown(0))
{
Raycast hit;
print(Physics.Raycast(transform.position, mouse_pos, out hit));
if (Physics.Raycast(transform.position, mouse_pos, out hit))
{
if (hit.collider.gameObject.name.Contains("enemy"))
{
hit.collider.gameObject.GetComponent<enemyMovement>().life -= 1;
}
}
}
The print returns false even when there's a gameobject there. It's probably a simple problem but I don't know what to do lol.
I changed the code for you, because I am not very familiar with the ray, thank you and hope it can help you.
void update(){
if (Input.GetMouseButtonDown(0))
{
// When the left mouse button is pressed, emit a ray to the screen
position where the mouse is located
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray,out hitInfo))
{
// When the ray collides with the object, draw the ray in the scene view
Debug.DrawLine(ray.origin, hitInfo.point, Color.red);
if (hitInfo.collider.gameObject.name.Contains("enemy"))
{
hitInfo.collider.gameObject.GetComponent<enemyMovement>().life -= 1;
}
}
}
}
I have been on here forever it feels like and nothing is fixing the issue. So I am relatively new to c# and unity and I set up my weapon and my crosshairs. I went through and set up ray cast and got a impact effect set. When I load in and try to shoot, my impact effect seems to be landing in different positions and it never lands in the same spot. I want to get it to where the effect happens on the target where the crosshairs are.
This line was added after the fact to try and fix it but didn't end up doing anything:
Ray ray = Camera.main.ViewportPointToRay(new Vector2(0.5f, 0.5f));
Here's my script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class shooting : MonoBehaviour
{
public float damage = 10;
public float range = 100;
public Camera cam;
public AudioSource audioSource;
public AudioSource audio1;
public AudioClip clip;
public AudioClip reload;
public float volume = 0.5f;
public ParticleSystem muzzleflash;
public GameObject hitEffect;
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Shooting();
}
if (Input.GetKey(KeyCode.R))
{
Reload();
}
}
void Shooting()
{
muzzleflash.Play();
audioSource.PlayOneShot(clip, volume);
RaycastHit hit;
Ray ray = Camera.main.ViewportPointToRay(new Vector2(0.5f, 0.5f));
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, range))
{
Debug.Log("Shooting");
}
Instantiate(hitEffect, hit.point, Quaternion.LookRotation(hit.normal));
}
void Reload()
{
audio1.clip = reload;
audio1.Play();
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.LeftShift))
{
audio1.Stop();
}
}
}
You've created a ray, you need use it.
Instantiate should be in the if block.
Specify a layer to do raycast, otherwise it can hit any collider in the path.
Ray ray = Camera.main.ViewportPointToRay(new Vector2(0.5f, 0.5f));
var mask = LayerMask.GetMask("Enemy");
if (Physics.Raycast(ray, out hit, range, mask))
{
Instantiate(hitEffect, hit.point, Quaternion.LookRotation(hit.normal));
}
If the effect is still shown at a random place, add some debug code, check the red line in the scene window.
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine(ray.origin, hit.point);
}
Following a tutorial, I'm trying to use a grappling gun mechanic that utilizes a spring joint and Line Renderer.
I've got the line drawing upon mouseclick, but the end of the line is not drawing where the user clicks.
It looks like this:
Can anyone kind of help me out as to why it's not working? Here's the (wonky) project in action-
https://i.imgur.com/IuMsEsQ.mp4
Grappling gun code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrapplingGun : MonoBehaviour
{
private LineRenderer lr;
private Vector3 grapplePoint; //where we grapple to
public LayerMask whatIsGrappable;
public Transform gunTip;
public Transform cam;
public Transform player;
private float maxDistance = 100f;
private SpringJoint joint;
void Awake()
{
lr = GetComponent<LineRenderer>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
StartGrapple();
}
else if (Input.GetMouseButtonUp(0))
{
StopGrapple();
}
}
void LateUpdate()
{
DrawRope();
}
void StartGrapple()
{
RaycastHit hit;
if (Physics.Raycast(cam.position, cam.forward, out hit, maxDistance, whatIsGrappable))
//if (Physics.Raycast(transform.position, Vector3.forward, out hit, maxDistance, whatIsGrappable))
{
grapplePoint = hit.point;
joint = player.gameObject.AddComponent<SpringJoint>();
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = grapplePoint;
float distanceFromPoint = Vector3.Distance(player.position, grapplePoint);
joint.maxDistance = distanceFromPoint * 0.8f;
joint.minDistance = distanceFromPoint * 0.25f;
joint.spring = 4.5f;
joint.damper = 7f;
joint.massScale = 4.5f;
lr.positionCount = 2;
}
}
void DrawRope()
{
//If not grappling, don't draw anything
if (!joint) return;
lr.SetPosition(0, gunTip.position);
lr.SetPosition(1, grapplePoint);
}
void StopGrapple()
{
lr.positionCount = 0;
Destroy(joint);
}
}
Thank you.
The underlying issue is your raycast. the second parameter is the direction of the ray, which you have as the camera direction. Currently your ray is pointing forward from the camera at all times as a result.
What you can do is use Camera.ScreenPointToRay to give a ray to cast along to give you a 3d mouse position to cast to, then use your current raycast but replace the second parameter with the direction from the player to the point hit by the raycast from the function mentioned before
Ray ray = Camera.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out RaycastHit hit);
if (Physics.Raycast(transform.position, (hit.point - transform.position).normalized, out hit, maxDistance, whatIsGrappable)) {
// Your code here...
}
I want to detect a touch on a GameObject without sucess. My code copied from some examples is:
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Mouse Clicked!!");
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 worldPoint2D = new Vector2(worldPoint.x, worldPoint.y);
RaycastHit2D hit = Physics2D.Raycast(worldPoint2D, Vector2.zero);
Debug.Log(hit.collider);
}
}
The output is always null :(
The game object is not moving and is a simple Cube with a box colider.
Try switching your Vector3 worldPoint into Vector2. So like this:
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector2 worldPoint2D = new Vector2(worldPoint.x, worldPoint.y);
and then use worldPoint2D in the raycast.
Answering myself...I was not be able to resolve the question using Phisycs2D.Raycast method but Phisics.Raycast did the work:
void Update()
{
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
Debug.Log(hit.collider);
}
}
}
I am making a 2D point-and-click game where i want the player to move towards clicked objects. This is my code for moving the player towards a door:
using UnityEngine;
using System.Collections;
public class MoveOnClick : MonoBehaviour {
public GameObject door;
public GameObject player;
public float speed;
public Vector3 target;
void Update () {
if (Input.GetMouseButtonDown (0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.zero);
if (hit.collider != null) {
player.transform.position = Vector3.MoveTowards(player.transform.position, target, speed * Time.deltaTime);
}
}
}
}
The problem is that the player only moves one pixel per click. I want the player to move all the way to the door if the door is clicked.
That should work:
void Update () {
if (Input.GetMouseButtonDown (0)) {
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.zero);
target = hit.transform.position;
}
if (hit.collider != null) {
player.transform.position = Vector3.MoveTowards(player.transform.position, target, speed * Time.deltaTime);
}
}