- Home /
,How to lock the raycast on the first point hit?
Hello I am new to unity/coding. I would like to make a grapple hook so that when you press fire1 you move towards the place you fired. I already got it working but the script creates multiple rays so it keeps changing direction. What I want is the when user inputs fire1 he shoots a ray and that ray stays in the same position (except the origin since the camera will be moving towards the direction along with the player),so kind of like look the ray. I am sure there's an easy answer but I don't know:(
Script :
[SerializeField] private GameObject player; [SerializeField] private float hook_speed;
public float weaponRange = 50f;
public Transform gunEnd;
private Camera fpsCam;
private WaitWhile shotDuration;
private AudioSource gunAudio;
private LineRenderer laserLine;
private CharacterController controller;
void Start()
{
laserLine = GetComponent<LineRenderer>();
gunAudio = GetComponent<AudioSource>();
fpsCam = GetComponentInParent<Camera>();
controller = player.GetComponent<CharacterController>();
}
void Update()
{
if (Input.GetButton("Fire1"))
{
Vector3 origin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0f));
RaycastHit hit;
laserLine.SetPosition(0, gunEnd.position);
if(Physics.Raycast(origin,fpsCam.transform.forward,out hit, weaponRange))
{
laserLine.SetPosition(1, hit.point);
Vector3 move = fpsCam.transform.forward*hook_speed*Time.deltaTime + fpsCam.transform.up * hook_speed * Time.deltaTime;
controller.Move(move);
}
else
{
laserLine.SetPosition(1, origin + (fpsCam.transform.forward * weaponRange));
}
laserLine.enabled = true;
}
else
{
laserLine.enabled = false;
}
}
Answer by unity_ek98vnTRplGj8Q · Jan 30, 2020 at 03:48 PM
You are casting a new ray every update call. I recommend casting one ray when the fire button is initially pressed, and then traveling along that ray while the button is held down. You shouldn't have to write much new code, just reorganize and make corrections to follow this general outline:
private bool isGrappling = false; //This will show if our initial raycast hit anything
private Vector3 hitLocation, hitDirection; //Save raycast results here
void Update () {
if(Input.GetButtonDown("Fire1")){
//Put your raycast here. Save the resulting direction and hit position to some variables
//Make sure you set isGrappling to true if the raycast was successful
}
if (Input.GetButton ("Fire1")) {
//If your initial raycast was successful, we can move the character
//You can also update your line renderer points here
}
if (Input.GetButtonUp("Fire1")){
//Set isGrappling to false
//Disable lineRenderer
}
}
Answer by babadany2999 · Jan 30, 2020 at 05:14 PM
@ unity_ek98vnTRplGj8Q It kind of works until my player gets to that point then he continues but in the opposite direction, kind of like an anti grapple hook. What I would like for him to do is when he reaches that point he just sits there .I probably just messed up the code though :(
void Update() { Vector3 origin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0f)); if (Input.GetButtonDown("Fire1")) { RaycastHit hit;
if (Physics.Raycast(origin, fpsCam.transform.forward, out hit, weaponRange))
{
isHooking = true;
laserLine.enabled = true;
}
hitLocation = hit.transform.position;
hitDirection = fpsCam.transform.forward;
//Put your raycast here. Save the resulting direction and hit position to some variables
//Make sure you set isGrappling to true if the raycast was successful
}
if (Input.GetButton("Fire1"))
{
laserLine.SetPosition(0, gunEnd.position);
if (hitLocation != null)
{
laserLine.SetPosition(1, hitLocation);
Vector3 move = hitDirection * hook_speed * Time.deltaTime + fpsCam.transform.up * hook_speed * Time.deltaTime;
controller.Move(move);
//If your initial raycast was successful, we can move the character
//You can also update your line renderer points here
}
else
{
laserLine.SetPosition(1, origin + (hitDirection * weaponRange));
}
}
if (Input.GetButtonUp("Fire1"))
{
isHooking = false;
laserLine.enabled = false;
//Set isGrappling to false
//Disable lineRenderer
}
}
So here is the code where you move
Vector3 move = hitDirection * hook_speed * Time.deltaTime + fpsCam.transform.up * hook_speed * Time.deltaTime;
controller.$$anonymous$$ove (move);
I'm wondering why you are adding the camera's up vector? It seems like this would not make you travel in a straight line. But if the movement works for you and it takes you to the grapple point then its fine.
A couple things you could do -
Check distance to the grapple point before you move
if(Vector3.Distance(transform.position, hitLocation) >= 1) Vector3 move = blah blah blah
You can set this to whatever distance you want
You can also use the current direction to the hit point rather than just the starting direction to move
Vector3 move = (hitLocation - transform.position) * hookSpeed * Time.deltaTime + blah blah blah
@unity_ek98vnTRplGj8Q I like how it moves with fpsCam.transform.up that's the only reason why :)) Also it now works but there's yet another problem. When he gets to the hit point he kind of shakes and moves a little down then up and so on. Is there a way for this to be "smooth"? Also ty for help :) (Same happens without using fpsCam.transform.up btw I tested)
I'm happy to help you out with your code but probably not in the comments thread just because I'm not immediately sure what the problem is so the will probably be some debugging to do. Feel free to email me at bdoobie01@gmail.com and I can help you out directly.
Your answer
Follow this Question
Related Questions
Destroy the object i am looking UNITY 3D 1 Answer
Adding a raycast to prevent camera from going through walls? 0 Answers
How do i get the Raycast rotation? 1 Answer
Creating 3d maze game 1 Answer
How to find colider steepness? 1 Answer