- Home /
please help, completely new, don't understand
Im trying to learn c# and unity from a scratch as a beginner can someone please help me with this script. This script I have made is attached to a cylinder in my scene and it fires the cylinder simulating a projectile. I have a few other cylinders all positioned next to each other in my scene. How can I fire them like the first cylinder, doing it one by one ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class rocket : MonoBehaviour
{
public float force = 900f;
private Rigidbody rb;
public float fakeGravity = 1f;
public Transform tip;
public bool IsLaunched;
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
if (IsLaunched)
{
rb.AddForce(transform.up * force);
rb.AddForceAtPosition(Vector3.down * fakeGravity, tip.position);
}
}
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
IsLaunched = true;
rb.useGravity = true;
}
}
}
I have seen you posting this question again and again.
What are you trying to achieve with this? If you are new you won't understand most part of the script provided to you.
You should try to do something easy if you can't even do such a super simple thing.
No I understand the scripts, I know a little bit, im just having trouble with this currently. And I explained what im trying to achieve
I just need to launch separate objects one after the other. One for each click !!
Try to make a script attached to the launcher.
Tell me more about how much should the ammo be? Should it be relodable? And any other things which you think might differ.
Answer by $$anonymous$$ · Jan 19, 2021 at 08:56 AM
Okay so first you should make a scriptable object for your weapons. Like this-
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapons")]
public class WeaponInfo : ScriptableObject
{
public string weaponName;
public float damage;
public float clipSize;
public float reloadSpeed;
public float timeBetweenBullets;
public Vector3 holdOffset;
public GameObject bullet;
public float bulletSpeed;
// public Transform bulletSpawnLoc;
public Vector3 bulletOffset;
public float hitRadius;
public Vector3 hitOffset;
public LayerMask hitMask;
// public LayerMask targetMask;
public LayerMask groundMask;
// Not neccessary at all
public void Print()
{
Debug.Log(weaponName + damage);
}
}
As you told in your previous questions that you have the launcher mounted on a Truck. So you can modify the movement method according to your needs or don't use it if you want.
If your launcher don't need to change than you use the WeaponPickupLogic method's part inside the if(weaponPickedUp) statement
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Serialization;
public class PlayerController : MonoBehaviour
{
#region Variables
public enum State
{
Still,
Running,
Jumping,
Crouching
}
private Rigidbody rb;
public Transform playerCam;
private float x;
private float y;
private bool jumpInput;
public float speed;
public float maxSpeed;
public float jumpForce;
public float friction = 1f;
public Transform groundCheck;
public float checkRadius = 0.3f;
public LayerMask groundMask;
private bool isGrounded;
private Collider[] inRangeWeapons;
private float weaponsCheckRadius = 2f;
public Transform weaponCheckLocation;
public LayerMask weaponMask;
private GunLogic gunLogic;
private bool isWeaponPickedUp = false;
private Collider gun;
[FormerlySerializedAs("desiredRot")] public Vector3 currLoc;
public float rotSpeed;
public float damping;
[FormerlySerializedAs("currLoc")] public Quaternion noCurrLoc;
public Vector3 holdOffset;
public Transform bulletSpawnLoc;
public Transform gunLookAt;
#endregion
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void Update()
{
MyInput();
noCurrLoc = transform.rotation;
}
private void FixedUpdate()
{
WeaponPickupLogic();
Movement();
gunLookAt.transform.position = playerCam.position + playerCam.forward + playerCam.forward /* + playerCam.forward*/;
}
public void MyInput()
{
x = Input.GetAxisRaw("Horizontal");
y = Input.GetAxisRaw("Vertical");
jumpInput = Input.GetKey(KeyCode.Space);
}
public void Movement()
{
// x = Input.GetAxis("Horizontal");
// y = Input.GetAxis("Vertical");
isGrounded = Physics.CheckSphere(groundCheck.position, checkRadius, groundMask);
jumpInput = Input.GetKeyDown(KeyCode.Space);
if (isGrounded && jumpInput) Jump();
Vector2 mag = FindVelRelativeToLook();
float magX = mag.x;
float magY = mag.y;
float maxSpeed = this.maxSpeed;
Frictionize(mag);
if (x > 0 && magX > maxSpeed) x = 0;
if (x < 0 && magX < -maxSpeed) x = 0;
if (y > 0 && magY > maxSpeed) y = 0;
if (y < 0 && magY < -maxSpeed) y = 0;
rb.AddForce(transform.forward * (y * speed * Time.deltaTime));
rb.AddForce(transform.right * (x * speed * Time.deltaTime));
// Debug.Log(FindVelRelativeToLook());
}
public void Jump()
{
rb.AddForce(Vector3.up * (jumpForce * Time.deltaTime));
}
public void Frictionize(Vector2 mag)
{
// float decrease = Time.deltaTime * 5;
if (Math.Abs(mag.x) > 2f && Math.Abs(x) < 0.1)
{
rb.AddForce(transform.right * (speed * Time.deltaTime * -mag.x * friction));
}
if (Math.Abs(mag.y) > 2f && Math.Abs(y) < 0.1)
{
rb.AddForce(transform.forward * (speed * Time.deltaTime * -mag.y * friction));
}
}
public void WeaponPickupLogic()
{
if (weaponCheckLocation == null)
weaponCheckLocation = transform;
inRangeWeapons = Physics.OverlapSphere(weaponCheckLocation.position, weaponsCheckRadius, weaponMask);
if (inRangeWeapons.Length > 0 && Input.GetKeyDown(KeyCode.F))
{
gunLogic = inRangeWeapons[0].GetComponent<GunLogic>();
isWeaponPickedUp = true;
gunLogic.isPickedUp = true;
gunLogic.cam = playerCam;
gunLogic.bulletSpawnLoc = bulletSpawnLoc;
holdOffset = gunLogic.holdOffset;
}
if (isWeaponPickedUp)
{
Vector3 gunHoldLoc = playerCam.position + (playerCam.forward * 0.5f);
gun = inRangeWeapons[0];
Vector3 posVel = Vector3.zero;
inRangeWeapons[0].transform.SetParent(transform);
// inRangeWeapons[0].transform.position = playerCam.position + playerCam.forward;
inRangeWeapons[0].transform.position = Vector3.SmoothDamp(gun.transform.position, gunHoldLoc /*+ playerCam.forward*/, ref posVel, 0.25f);
// Vector3.SmoothDamp(gun.transform.position, new Vector3(1, 2, 3) /*+ playerCam.forward*/, ref posVel, 0.25f);
gunLogic.cam = playerCam;
// gunRotation = playerCam.rotation;
// gunRotation.y = transform.rotation.y;
// inRangeWeapons[0].transform.rotation = gunRotation;
RotateTo();
}
}
public void RotateTo()
{
// currLoc = inRangeWeapons[0].transform.rotation;
// currLoc.y = transform.rotation.y;
// gunRotation = inRangeWeapons[0].transform.rotation;
// gunRotation.y = transform.rotation.y;
// Quaternion outGunRot = gunRotation;
// if(gunRotation.x > outGunRot.x) outGunRot.x += Time.deltaTime;
// if(gunRotation.x < outGunRot.x) outGunRot.x -= Time.deltaTime;
// if(gunRotation.y > outGunRot.x) outGunRot.y += Time.deltaTime;
// if(gunRotation.y < outGunRot.x) outGunRot.y -= Time.deltaTime;
// if(gunRotation.z > outGunRot.x) outGunRot.z += Time.deltaTime;
// if(gunRotation.z < outGunRot.x) outGunRot.z -= Time.deltaTime;
// outGunRot.y += Time.deltaTime;
// outGunRot.z += Time.deltaTime;
// return outGunRot;
// inRangeWeapons[0].transform.rotation = Quaternion.RotateTowards(currLoc, gunLookAt.rotation, Time.deltaTime * damping);
currLoc = inRangeWeapons[0].transform.position;
Vector3 preDirection = gunLookAt.position - currLoc;
Quaternion direction = Quaternion.LookRotation(preDirection, Vector3.up);
inRangeWeapons[0].transform.rotation = Quaternion.Lerp(inRangeWeapons[0].transform.rotation, direction, 0.1f);
}
public Vector2 FindVelRelativeToLook() {
float lookAngle = transform.eulerAngles.y;
float moveAngle = Mathf.Atan2(rb.velocity.x, rb.velocity.z) * Mathf.Rad2Deg;
float u = Mathf.DeltaAngle(lookAngle, moveAngle);
float v = 90 - u;
float magnitue = rb.velocity.magnitude;
float yMag = magnitue * Mathf.Cos(u * Mathf.Deg2Rad);
float xMag = magnitue * Mathf.Cos(v * Mathf.Deg2Rad);
return new Vector2(xMag, yMag);
}
public void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(weaponCheckLocation.position, weaponsCheckRadius);
}
}
Then the gun logic-
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
public class GunLogic : MonoBehaviour
{
public GameObject gameManager;
private GameManager _gameManagerScript;
[FormerlySerializedAs("weaponScriptable")] public WeaponInfo weaponInfo;
public string weaponName;
public float damage;
public float clipSize;
public float reloadSpeed;
public float timeBetweenBullets;
public Vector3 holdOffset;
public GameObject bullet;
public Vector3 bulletOffset;
// public bool isPickedUp;
public Transform bulletSpawnLoc;
public Transform cam;
public Vector3 camRot;
public bool isPickedUp;
private void Start()
{
gameManager = GameObject.Find("GameManager");
_gameManagerScript = gameManager.GetComponent<GameManager>();
weaponName = weaponInfo.weaponName;
gameObject.name = weaponName;
damage = weaponInfo.damage;
clipSize = weaponInfo.clipSize;
reloadSpeed = weaponInfo.reloadSpeed;
timeBetweenBullets = weaponInfo.timeBetweenBullets;
// bulletSpawnLoc = weaponInfo.bulletSpawnLoc;
holdOffset = weaponInfo.holdOffset;
bullet = weaponInfo.bullet;
bulletOffset = weaponInfo.bulletOffset;
}
private void Update()
{
if (timeBetweenBullets <= 0)
{
if (Input.GetButtonDown("Fire1") && isPickedUp)
{
Shoot();
}
}
else
{
timeBetweenBullets -= Time.deltaTime;
}
}
public void Shoot()
{
// camRot = Quaternion.Euler(cam.transform.rotation.eulerAngles);
PlayerController playerMovement = _gameManagerScript.player.GetComponent<PlayerController>();
camRot = playerMovement.currLoc;
GameObject currentBullet = ObjectPooler.instance.SpawnFromPool("Bullet", bulletSpawnLoc.transform.position + bulletOffset, Quaternion.Euler(camRot.x, camRot.y, camRot.z));
// GameObject currentBullet = Instantiate(bullet, (cam.transform.position + cam.transform.forward) + bulletOffset, camRot);
BulletLogic bulletLogic = currentBullet.GetComponent<BulletLogic>();
bulletLogic.damage = damage;
bulletLogic.speed = weaponInfo.bulletSpeed;
bulletLogic.hitRadius = weaponInfo.hitRadius;
bulletLogic.preHitOffset = weaponInfo.hitOffset;
bulletLogic.hitMask = weaponInfo.hitMask;
bulletLogic.groundMask = weaponInfo.groundMask;
bulletLogic.addForceInDir = transform.forward;
}
}
The object pooler so you don't instantiate a bullet every time.
You can use an int var in the gun logic if your bullets are limited and then reduce it every time.
Then the bullet logic-
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
public class BulletLogic : MonoBehaviour
{
#region Variables
public float speed;
public Vector3 addForceInDir;
public float damage;
public float hitRadius = 1f;
public Vector3 preHitOffset;
public Vector3 hitOffset;
[FormerlySerializedAs("targetMask")] public LayerMask hitMask;
public LayerMask groundMask;
public Collider[] hit;
private bool _hasHit = false;
private bool _hasTakenDamage = false;
#endregion
// private void Start()
// {
// hitOffset = transform.position;
// }
//
// private void Update()
// {
//
// MoveForward();
// hitOffset = transform.position;
// hitOffset += preHitOffset;
//
//
// hit = Physics.OverlapSphere(hitOffset, hitRadius, hitMask);
//
// if (hit.Length > 0)
// {
// Target target = hit[0].GetComponent<Target>();
//
//
// if (!_hasTakenDamage)
// {
// target.TakeDamage(damage);
// _hasTakenDamage = true;
// }
// // _hasHit = true;
// }
//
//
// if (CheckSphere(hitMask) || CheckSphere(groundMask))
// {
// _hasHit = true;
// }
// }
//
//
// public bool CheckSphere(LayerMask layerMask)
// {
// return Physics.CheckSphere(hitOffset, hitRadius, layerMask);
// }
//
//
// public void MoveForward()
// {
// if (!_hasHit)
// {
// transform.Translate(Vector3.forward * (speed * Time.deltaTime));
// }
// else
// {
// Debug.Log(this.name + " should stop!");
// }
// }
private Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
rb.velocity = addForceInDir * (speed * Time.deltaTime);
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(hitOffset, hitRadius);
}
}
Then the offset setter (a script you don't need to use but I am just giving it if you might want to know what it is)-
using System;
using UnityEngine;
using UnityEngine.Serialization;
public class GfxOffsetSetter : MonoBehaviour
{
[FormerlySerializedAs("_gunLogic")] private GunLogic _gunLogic;
[FormerlySerializedAs("_gun")] public GameObject gun;
private void Start()
{
_gunLogic = gun.GetComponent<GunLogic>();
}
private void FixedUpdate()
{
// // gun = GetComponentInParent<Transform>();
// _gunLogic = gun.GetComponent<GunLogic>();GetComponentInParent<GunLogic>();
if (_gunLogic.isPickedUp)
{
SetOffset(_gunLogic.holdOffset);
}
}
public void SetOffset(Vector3 holdOffset)
{
transform.localPosition = holdOffset;
// float duh;
//
// duh = Time.deltaTime;
// if (duh);
}
}
Now as you were asking again and again so I gave it all. Ask me something if you want help. And copy the codes and paste them in a good ide like Rider (It is extremely great and paid but you can get it for free here). And I know this code is not the best or anywhere near it. But I am upgrading this every day.
man I really appreciate all this, but I think what I was asking for does not require this long solution. Is there anywhere in your solution that deals with what I was originally asking about ?
Well projectile shooting isn't a simple thing. And can vary a lot depending on what you want. It is something you should try to do by yourself. First try some easy stuff. The odds of someone making a custom script just to help a random person are quite low. Even I didn't made it for you, it was just from one of my game.
this is way way to much for a beginner, and you just write out an answer with no explanation.. how are they supposed to know what any of it means? They said they are new to unity and C#.. This maybe an excellent solution, but a terrible answer. Also launching projectiles it not a hard complex thing, you did it in a complex way, you don't need scriptable objects, regions, 5 scripts! 2 scripts is all that is needed, 2 short scripts, also half of 2 of your scripts is commented out code.. This is no help to a beginner at all then you tell them this is a complicated thing when it doesn't have to be..
He told that he had to expand his game too! You can't do it with 2 scripts! If I would have wanted than I could have gave him a simple unexpandable script. But as he was asking this question a lot of time, it must be something important to him. And you know it took a few days to make this script how do you expect me to explain all this in text? Someone can make a video or even a whole series on this. No one came to me and taught this or told me where I can learn this.I myself searched for learning resources and learnt it. You can't ask someone to make a whole script for you. He was trying to get spoon fed.
Answer by $$anonymous$$ · Jan 21, 2021 at 05:15 PM
You could throw this whole script on an empty Gameobject instead.
Then make a List or an Array of Rigidbodies and launch in order from that using an int to keep track of the index.
I made a script named RocketLauncher, a modified version of your script. You can throw this onto a new GameObject, line your projectiles up how you want them, then add them to the 'rbs' list in your inspector. In play mode, you should be able to left-click and see each Rigidbody react in the specific order you added them to the list. When it hits the end of the list, the index resets to zero, looping through the list again from the beginning.
Here's the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RocketLauncher : MonoBehaviour
{
public float force = 30f;
public List<Rigidbody> rbs = new List<Rigidbody>();
List<Transform> rbOriginalPositionsAtRuntime = new List<Transform>();
public Transform tip;
public bool useLaunchTip;
int index = 0;
Rigidbody currentRb;
bool bodyNotNull, IsLaunched;
void Start() {
GameObject originalPositionsParent = new GameObject();
for (int i = 0; i < rbs.Count; i++){
Transform posAtRuntime = new GameObject(rbs[i].name).transform;
posAtRuntime.position = rbs[i].transform.position;
posAtRuntime.SetParent(originalPositionsParent.transform);
rbOriginalPositionsAtRuntime.Add(posAtRuntime);
}
}
private void FixedUpdate(){
if (IsLaunched && bodyNotNull){
currentRb.transform.position = useLaunchTip && tip? tip.position : currentRb.transform.position;
Vector3 selfUpDir = currentRb.transform.up * force;
Vector3 direction = selfUpDir;
if(tip && useLaunchTip){
Vector3 tipForwardDir = tip.forward * force;
direction = tipForwardDir;
}
currentRb.AddForce(direction, ForceMode.Impulse);
//currentRb.AddForceAtPosition(Vector3.down * fakeGravity, tip.position);
}
}
private void Update(){
bodyNotNull = (index < rbs.Count) && rbs[index];
IsLaunched = (Input.GetButtonDown("Fire1"));
print(currentRb);
if(currentRb && IsLaunched){
currentRb.velocity = Vector3.zero;
currentRb.angularVelocity = Vector3.zero;
currentRb.transform.position = rbOriginalPositionsAtRuntime[index].transform.position;
currentRb.transform.rotation = rbOriginalPositionsAtRuntime[index].transform.rotation;
index++;
if(!(index < rbs.Count)){
index = 0;
}
}
if(IsLaunched){
currentRb = GetRbFromList();
currentRb.useGravity = true;
}
}
Rigidbody GetRbFromList(){
Rigidbody bodyFromList = rbs[index];
return bodyFromList;
}
}
can you explain the part about rotating the projectile
My example doesn't cover rotating the projectile to match the guntips', my apologies. To do that, rotate the guntip so that the blue arrow of the transform matches the direction you wanna fire things from. Then drag this transform into the "Tip" slot in the inspector for the object containing this script. Finally, sometime before this line in FixedUpdate,
currentRb.AddForce(direction, ForceMode.Impulse);
add in this little line here:
currentRb.transform.rotation = tip.rotation;
this will match the projectile's rotation with the tip's rotation. I hope this helps some.
Answer by VoidBreakX · Jan 30, 2021 at 07:41 AM
Just try to use Instantiate? I guess you could check this out: