Hello, I am making a 3d game and I have made a grapple gun (dani grapple gun), and I have made a working gun. Okay so I made a pick up and drop system that works fine without the grapple or gun main scripts enabled. But obviously I want them to be enabled, so I made a really bad code for the scripts to enable, but when I equip one of the guns on the floor the scripts for the gun gets enabled, which I want. But the other gun also has a script and that script also gets enabled. I know why cause the code is made like that, but I want to make so when I pick up the grapple gun the grapple gun scripts are going to get enabled. and when I pick up the gun the gun scripts are going to be enabled and the grapple scripts disabled. I just can’t figure out how I can code that. I appreciate every help I get, thanks!
PickupAndDropGun Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickupAndDropGun : MonoBehaviour
{
public GameObject gun;
public Rigidbody rb;
public BoxCollider coll;
public Transform player, gunContainer, fpsCam;
public float pickUpRange;
public float dropForwardForce, dropUpwardForce;
public bool equipped;
public static bool slotFull;
public GrapplingGun grapple;
public RotateGun rotateGrapple;
public ProjectileGun handGun;
private void Start()
{
if (!equipped)
{
rb.isKinematic = false;
coll.isTrigger = false;
}
if (equipped)
{
rb.isKinematic = true;
coll.isTrigger = true;
slotFull = true;
}
}
private void Update()
{
Vector3 distaceToPlayer = player.position - transform.position;
if (!equipped && distaceToPlayer.magnitude <= pickUpRange && Input.GetKeyDown(KeyCode.E) && !slotFull) PickUp();
if (equipped && Input.GetKeyDown(KeyCode.Q)) Drop();
}
public void PickUp()
{
equipped = true;
slotFull = true;
transform.SetParent(gunContainer);
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.Euler(Vector3.zero);
transform.localScale = Vector3.one;
rb.isKinematic = true;
coll.isTrigger = true;
grapple.enabled = true;
rotateGrapple.enabled = true;
handGun.enabled = true;
}
public void Drop()
{
equipped = false;
slotFull = false;
transform.SetParent(null);
rb.isKinematic = false;
coll.isTrigger = false;
rb.velocity = player.GetComponent<Rigidbody>().velocity;
rb.AddForce(fpsCam.forward * dropForwardForce, ForceMode.Impulse);
rb.AddForce(fpsCam.up * dropUpwardForce, ForceMode.Impulse);
float random = Random.Range(-1f, 1f);
rb.AddTorque(new Vector3(random, random, random) * 10);
grapple.enabled = false;
rotateGrapple.enabled = false;
handGun.enabled = false;
}
}
ProjectileGun Script:
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class ProjectileGun : MonoBehaviour
{
//bullet
public GameObject bullet;
//bullet force
public float shootForce, upwardForce;
//Gun stats
public float timeBetweenShooting, spread, reloadTime, timeBetweenShots;
public int magazineSize, bulletsPerTap;
public bool allowButtonHold;
int bulletsLeft, bulletsShot;
//Recoil
public Rigidbody playerRb;
public float recoilForce;
//bools
bool shooting, readyToShoot, reloading;
//Reference
public Camera fpsCam;
public Transform attackPoint;
//Graphics
public TextMeshProUGUI ammunitionDisplay;
//bug fixing :smile:
public bool allowInvoke = true;
//Muzzleflash
public ParticleSystem muzzleFlash;
//Weapon Recoil
public bool randomizeRecoil;
public Vector2 randomRecoilConstraints;
//You only need to assign this if randomize recoil is off
public Vector2[] recoilPattern;
private Vector2 _currentRotation;
//Aiming
public Vector3 normalLocalPosition;
public float recoilSmoothing = 10;
private void Awake()
{
//make sure magazine is full
bulletsLeft = magazineSize;
readyToShoot = true;
}
private void Update()
{
MyInput();
DetermineAim();
//Set ammo display, if it exists :smile:
if (ammunitionDisplay != null)
ammunitionDisplay.SetText(bulletsLeft / bulletsPerTap + " / " + magazineSize / bulletsPerTap);
}
private void MyInput()
{
//Check if allowed to hold down button and take corresponding input
if (allowButtonHold) shooting = Input.GetKey(KeyCode.Mouse0);
else shooting = Input.GetKeyDown(KeyCode.Mouse0);
//Reloading
if (Input.GetKeyDown(KeyCode.R) && bulletsLeft < magazineSize && !reloading) Reload();
//Reload automatically when trying to shoot without ammo
if (readyToShoot && shooting && !reloading && bulletsLeft <= 0) Reload();
//Shooting
if (readyToShoot && shooting && !reloading && bulletsLeft > 0)
{
//Set bullets shot to 0
bulletsShot = 0;
Shoot();
muzzleFlash.Play();
}
}
private void Shoot()
{
DetermineRecoil();
readyToShoot = false;
//Find the exact hit position using a raycast
Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); //Just a ray through the middle of your current view
RaycastHit hit;
//check if ray hits something
Vector3 targetPoint;
if (Physics.Raycast(ray, out hit))
targetPoint = hit.point;
else
targetPoint = ray.GetPoint(75); //Just a point far away from the player
//Calculate direction from attackPoint to targetPoint
Vector3 directionWithoutSpread = targetPoint - attackPoint.position;
//Calculate spread
float x = Random.Range(-spread, spread);
float y = Random.Range(-spread, spread);
//Calculate new direction with spread
Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0); //Just add spread to last direction
//Instantiate bullet/projectile
GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity); //store instantiated bullet in currentBullet
//Rotate bullet to shoot direction
currentBullet.transform.forward = directionWithSpread.normalized;
//Add forces to bullet
currentBullet.GetComponent<Rigidbody>().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
currentBullet.GetComponent<Rigidbody>().AddForce(fpsCam.transform.up * upwardForce, ForceMode.Impulse);
bulletsLeft--;
bulletsShot++;
Destroy(currentBullet, 2f);
//Invoke resetShot function (if not already invoked), with your timeBetweenShooting
if (allowInvoke)
{
Invoke("ResetShot", timeBetweenShooting);
allowInvoke = false;
//Add recoil to player (should only be called once)
playerRb.AddForce(-directionWithSpread.normalized * recoilForce, ForceMode.Impulse);
}
//if more than one bulletsPerTap make sure to repeat shoot function
if (bulletsShot < bulletsPerTap && bulletsLeft > 0)
Invoke("Shoot", timeBetweenShots);
}
private void ResetShot()
{
//Allow shooting and invoking again
readyToShoot = true;
allowInvoke = true;
}
private void Reload()
{
reloading = true;
Invoke("ReloadFinished", reloadTime); //Invoke ReloadFinished function with your reloadTime as delay
}
private void ReloadFinished()
{
//Fill magazine
bulletsLeft = magazineSize;
reloading = false;
}
private void DetermineRecoil()
{
transform.localPosition -= Vector3.forward * 0.1f;
if (randomizeRecoil)
{
float xRecoil = Random.Range(-randomRecoilConstraints.x, randomRecoilConstraints.x);
float yRecoil = Random.Range(-randomRecoilConstraints.y, randomRecoilConstraints.y);
Vector2 recoil = new Vector2(xRecoil, yRecoil);
_currentRotation += recoil;
}
else
{
int currentStep = magazineSize + 1 - bulletsLeft;
currentStep = Mathf.Clamp(currentStep, 0, recoilPattern.Length - 1);
_currentRotation += recoilPattern[currentStep];
}
}
private void DetermineAim()
{
Vector3 target = normalLocalPosition;
Vector3 desiredPosition = Vector3.Lerp(transform.localPosition, target, Time.deltaTime * recoilSmoothing);
transform.localPosition = desiredPosition;
}
}
Grappling Gun Script:
using UnityEngine;
public class GrapplingGun : MonoBehaviour {
private LineRenderer lr;
private Vector3 grapplePoint;
public LayerMask whatIsGrappleable;
public Transform gunTip, fpsCam, 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();
}
}
//Called after Update
void LateUpdate() {
DrawRope();
}
/// <summary>
/// Call whenever we want to start a grapple
/// </summary>
void StartGrapple() {
RaycastHit hit;
if (Physics.Raycast(fpsCam.position, fpsCam.forward, out hit, maxDistance, whatIsGrappleable)) {
grapplePoint = hit.point;
joint = player.gameObject.AddComponent<SpringJoint>();
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = grapplePoint;
float distanceFromPoint = Vector3.Distance(player.position, grapplePoint);
//The distance grapple will try to keep from grapple point.
joint.maxDistance = distanceFromPoint * 0.8f;
joint.minDistance = distanceFromPoint * 0.25f;
//Adjust these values to fit your game.
joint.spring = 4.5f;
joint.damper = 7f;
joint.massScale = 4.5f;
lr.positionCount = 2;
currentGrapplePosition = gunTip.position;
}
}
/// <summary>
/// Call whenever we want to stop a grapple
/// </summary>
void StopGrapple() {
lr.positionCount = 0;
Destroy(joint);
}
private Vector3 currentGrapplePosition;
void DrawRope() {
//If not grappling, don't draw rope
if (!joint) return;
currentGrapplePosition = Vector3.Lerp(currentGrapplePosition, grapplePoint, Time.deltaTime * 8f);
lr.SetPosition(0, gunTip.position);
lr.SetPosition(1, currentGrapplePosition);
}
public bool IsGrappling() {
return joint != null;
}
public Vector3 GetGrapplePoint() {
return grapplePoint;
}
}
Rotate Grapple Gun Script:
using UnityEngine;
public class RotateGun : MonoBehaviour {
public GrapplingGun grappling;
private Quaternion desiredRotation;
private float rotationSpeed = 5f;
void Update() {
if (!grappling.IsGrappling()) {
desiredRotation = transform.parent.rotation;
}
else {
desiredRotation = Quaternion.LookRotation(grappling.GetGrapplePoint() - transform.position);
}
transform.rotation = Quaternion.Lerp(transform.rotation, desiredRotation, Time.deltaTime * rotationSpeed);
}
}