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;
}
}
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
}
}
@ 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
}
}