When the code starts I instantiate a Random amount of new raycasts (from 1 to 4) from the original Raycast:
public class MultipleRaycasts : MonoBehaviour
{
public GameObject Raycastobj;
private GameObject RCclone;
public int RandomSTRUNKnumber;
void Start()
{
Destroy(gameObject);
RandomSTRUNKnumber = Random.Range(1, 4);
for (int m = 0; m < RandomSTRUNKnumber; m++)
{
RCclone = Instantiate(Raycastobj);
}
}
}
After the button is clicked all the moving raycasts are stopping if they hit the object (I am not attaching this one), and instantiate the "RandomSTrunk" object on the other object:
public class PlayerRayINST : MonoBehaviour {
public Transform RandomSTrunk2;
public bool RCnn;
public bool RCCheck;
public void Update()
{
Debug.DrawRay(transform.position, transform.forward * 100f, Color.yellow);
RCnn = true;
RCCheck = true;
Ray ray1 = new Ray(transform.position, transform.forward);
RaycastHit hit1;
if (Physics.Raycast(ray1, out hit1))
{
if (hit1.collider.gameObject.GetComponent<SelectableTrunk>())
{
RCnn = false;
RCCheck = false;
}
else
{
RCnn = true;
RCCheck = true;
}
}
}
public void OnMouseDown()
{
Invoke("Addbranch", 0.5f);
}
void Addbranch()
{
Ray ray2 = new Ray(transform.position, transform.forward);
RaycastHit hit2;
if (Physics.Raycast(ray2, out hit2))
{
if (hit2.collider.gameObject.GetComponent<SelectableTrunk>())
{
Transform clone = Instantiate(RandomSTrunk2);
clone.position = hit2.point;
clone.LookAt(hit2.transform.position - hit2.transform.forward, hit2.normal);
}
}
}
}
My code somehow instantiates the "RandomSTrunk" only from the original Raycast. It ignores the instantiated earlier Raycasts and does not want to Instantiate the "RandomSTrunk" from the other raycasts.
However, if I put Update instead of OnMouseDown It will instantiate correctly but with millions of generated clones. I've just started learning unity, so please help me ;)
Related
I apologize for the block of code below but I am not sure where the issue is. I am trying to get a laser to appear off screen and attempt to hit the player. I have no idea why this code does nothing. It is most likey just a stupid mistake I have made.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lasers : MonoBehaviour
{
private LineRenderer lr;
public bool Above = true;
public bool Below = false;
public bool Left = false;
public bool Right = false;
public Transform LaserStartPoint;
public Transform LaserEndPoint;
public Transform Player;
public float LaserWidth = 0.75f;
public float LaserLength = 19f;
public float LaserDuration = 0.5f;
public float LaserFadeDuration = 0.5f;
public GameObject Laser;
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
ShootLaser();
}
}
void ShootLaser()
{
if(Above)
{
LaserStartPoint.position = new Vector3(Random.Range(-10,10), 6, -1);
}
if(Below)
{
LaserStartPoint.position = new Vector3(Random.Range(-10,10), -6, -1);
}
if(Left)
{
LaserStartPoint.position = new Vector3(-10, Random.Range(-6,6), -1);
}
if(Right)
{
LaserStartPoint.position = new Vector3(10, Random.Range(-6,6), -1);
}
Instantiate(Laser, LaserStartPoint.position, Quaternion.identity);
lr = Laser.GetComponent<LineRenderer>();
lr.startWidth = LaserWidth;
lr.endWidth = LaserWidth;
lr.positionCount = 2;
Vector3 dir = Player.position - LaserStartPoint.position;
LaserEndPoint.position = LaserStartPoint.position + dir.normalized * LaserLength;
lr.SetPosition(0, LaserStartPoint.position);
lr.SetPosition(1, LaserEndPoint.position);
Invoke("FadeLaser", LaserDuration);
}
void FadeLaser()
{
lr.startColor = Color.Lerp(lr.startColor, Color.clear, LaserFadeDuration);
lr.endColor = Color.Lerp(lr.endColor, Color.clear, LaserFadeDuration);
Laser.SetActive(false);
}
}
`
I have looked in the Hierarchy and nothing is spawning. None of the values are changing on the Script. I have the script attached to the main camera and it spawns in my LaserLineRenderer prefab.
You are attempting to modify the line renderer component of the prefab. You need to grab the reference of the instantiated object when it is spawned in.
private GameObject instantiatedLazer;
/*In ShootLaser function*/
instantiatedLazer = Instantiate(Laser, LaserStartPoint.position, Quaternion.identity);
lr = instantiatedLazer.GetComponent<LineRenderer>();
/*In FadeLaser function*/
instantiatedLazer.SetActive(false);
I have made a gun with multiple firing modes. Upon loading in the weapon (both through loading the scene and through switching to another gun and back to it) it will fire a single shot with sound and light. What is causing it to fire this one bullet and how do I stop the weapon from doing so?
I already tried to add a delay before it should be allowed to fire by making the 1 higher in start. I also tried to add more time to "timeBeforeShooting" in the Void auto section. Setting "shooting" to false and true instead of leaving it blank did not help either.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutomaticGun1 : MonoBehaviour
{
public enum firingMode
{
auto = 1,
semi = 2,
burst = 3
}
[SerializeField] private firingMode currentFiringMode = firingMode.auto;
[SerializeField] private LayerMask enemyLayer;
[SerializeField] private float damage;
[SerializeField] private float fireRate;
private float timeBeforeShooting;
private bool shooting;
private int firingModeID = 1;
public Camera playerView;
public ParticleSystem muzzleFlash;
public AudioSource bang;
// Start is called before the first frame update
void Start()
{
timeBeforeShooting = 1 / fireRate;
playerView.GetComponent<Camera>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.V))
{
firingModeID++;
if(firingModeID > 3)
{
firingModeID = 1;
}
currentFiringMode = (firingMode)firingModeID;
Debug.Log(firingModeID);
}
switch(currentFiringMode)
{
case firingMode.auto:
auto();
break;
case firingMode.semi:
semi();
break;
case firingMode.burst:
burst();
break;
}
}
void auto()
{
if (Input.GetMouseButton(0))
{
if (timeBeforeShooting <= 0f)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
timeBeforeShooting = 1 / fireRate;
}
else
{
timeBeforeShooting -= Time.deltaTime;
}
}
else
{
timeBeforeShooting = 0f;
}
}
void semi()
{
if (Input.GetMouseButtonDown(0))
{
if (timeBeforeShooting <= 0f)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
}
}
}
void burst()
{
if (Input.GetMouseButtonDown(0) && !shooting)
{
StartCoroutine(burstShots(3));
shooting = true;
}
}
IEnumerator burstShots(int timesToShoot)
{
for (int timesShot = 1; timesShot <= timesToShoot; timesShot++)
{
muzzleFlash.Play();
bang.Play();
Ray gunRay = new Ray(playerView.transform.position, playerView.transform.forward);
if (Physics.Raycast(gunRay, out RaycastHit hitInfo, 100f, enemyLayer))
{
if (hitInfo.collider.gameObject.TryGetComponent(out enemy1 enemyHit))
{
enemyHit.SubtractHealth(damage);
Debug.Log(enemyHit.health);
}
}
yield return new WaitForSeconds(0.5f / fireRate);
}
shooting = false;
}
}
I'm trying to assign a skill to a projectile that, when used, divides the project into 3 (the original projectile and 2 more new ones).
However, when I instantiate these two clones, I cannot attribute any movement to them. The idea would be for them to take this route:
The green dotted curve indicating the motion of the original bullet, the blue vector indicating the instantaneous velocity of the original bullet at time of special activation, the red vectors indicating the two velocity vectors belonging to each of the newly spawned bullets, and the green angle indicating the direction of the new bullet relative to the original velocity direction
But at the moment, they are just standing at the point of the parabola where they were instantiated. No matter what I do, I can't seem to attach any value to their rigidbody2D. Does anyone know how to fix this?
This is my code so far
Ability Script:
public class AirSpecialSplit : MonoBehaviour, IAirSpecial
{
public float SplitAngleInDegrees = 10;
GameObject bird_down;
GameObject bird_up;
public void ExecuteAirSpecial()
{
{
//hold the velocity of the original bird
Vector2 original_velocity = this.gameObject.GetComponent<Rigidbody2D>().velocity;
//clone two new birds
bird_down = Birb.MakeBirbCopy(this.gameObject);
bird_up = Birb.MakeBirbCopy(this.gameObject);
//get the rigidboy from the clones
Rigidbody2D rb_bird_down = bird_down.GetComponent<Rigidbody2D>();
Rigidbody2D rb_bird_up = bird_up.GetComponent<Rigidbody2D>();
rb_bird_down.velocity = new Vector2(original_velocity.x, original_velocity.y) * Time.deltaTime;
rb_bird_up.AddForce(new Vector2(3, 5) * 500);
}
}
}
Main Bird:
public class Birb : MonoBehaviour
{
#region Provided Code, Do Not Edit
private Rigidbody2D m_rigidbody;
private bool m_canExecuteAirSpecial = true;
public bool CanExecuteAirSpecial
{
get
{
return m_rigidbody.simulated && m_canExecuteAirSpecial;
}
}
private void Awake()
{
m_rigidbody = GetComponent<Rigidbody2D>();
StopBirbSimulation();
}
public void StopBirbSimulation()
{
m_rigidbody.simulated = false;
}
public void StartBirbSimulation()
{
m_rigidbody.simulated = true;
}
public void SetPosition( Vector3 position )
{
if ( m_rigidbody.simulated )
{
m_rigidbody.MovePosition( position );
}
else
{
transform.position = position;
}
}
public void ExecuteAirSpecial()
{
GetComponent<IAirSpecial>().ExecuteAirSpecial();
m_canExecuteAirSpecial = false;
}
private void OnCollisionEnter2D( Collision2D collision )
{
m_canExecuteAirSpecial = false;
}
public static GameObject MakeBirbCopy( GameObject original )
{
Birb newBirb = Instantiate(original).GetComponent<Birb>();
newBirb.m_canExecuteAirSpecial = false;
return newBirb.gameObject;
}
#endregion
[Range( 0, 25 )]
public float LaunchForce = 12;
public void Launch(Vector3 offset, float maximumStretch, Rigidbody2D rigidbody)
{
rigidbody.velocity = new Vector2(offset.x * -LaunchForce, offset.y * -LaunchForce) * (maximumStretch/2);
}
}
Ok, apparently, I just need to set the "simulated" to true after instantiate.
rb_bird_down.simulated = true;
rb_bird_up.simulated = true;
The documentation could be clearer about this since they say that all attributes are copied, which is not the case...
I have a script so far that moves an object a small distance upon a mouse click, however I want to change it so that when I click this object, it swaps places with another obejct next to it, instead of just the small distance it is moving now. I am a little confused on how to do this, because I am new to unity.
using UnityEngine;
using System.Collections;
public class NewBehaviourScript: MonoBehaviour
{
public float movementSpeed = 10;
void Update(){
if ( Input.GetMouseButtonDown(0))
{
transform.Translate(Vector3.right * movementSpeed * Time.deltaTime);
}
}
}
Try this:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript: MonoBehaviour {
public GameObject objectA; //Needs to be initialized in the editor, or on Start
public GameObject objectB; //Needs to be initialized in the editor, or on Start
public float movementSpeed = 10;
private Vector3 posA = Vector3.zero; //Vector3.zero is for initialization
private Vector3 posB = Vector3.zero; //Vector3.zero is for initialization
void Update() {
if ( Input.GetMouseButtonDown(0)) {
posA = objectA.gameObject.transform.position;
posB = objectB.gameObject.transform.position;
objectA.gameObject.transform.position = posB;
objectB.gameObject.transform.position = posA;
}
}
}
This just saves each objects position into the posA and posB variables, then you move objectA to posB and objectB to posA.
-OR-
Now if objectB is always a different object (NOT constant) and you aren't sure how to find the nearest object, you could use a raycast. Add the following function to your code:
gamObject NearestObject () {
int dist;
int nearestIndex;
//Create an array to contain objects to be hit by the raycast
RaycastHit[] nearby;
//Hit all objects within 100 units with a raycast, change the 100 as needed
nearby = Physics.RaycastAll(objectA.transform.position, transform.forward, 100.0f);
//Check if there is at least one object
if(nearby.Length > 0) {
//If there is only one object and it's not objectA
if(!(nearby.Length == 1 && nearby[0].transform == objectA.transform)) {
dist = nearby[0].distance;
nearestIndex = 0;
for (int i = 1; i < nearby.Length; i++) {
if(nearby[i].transform != gameObject.transform && nearby[i].distance < dist)
dist = nearby[i].distance;
nearestIndex = i;
}
}
} else {
//There is only one object in the raycast and it is objectA
nearestIndex = -1;
}
} else {
//There are no objects nearby
nearestIndex = -1;
}
//nearestIndex will only be negative one if there are no objects near objectA, so return null
if (nearestIndex == -1) {
return null;
} else {
//return nearest object to update
return nearby[nearestIndex].gameObject;
}
}
Finally, change Update to:
void Update() {
if ( Input.GetMouseButtonDown(0)) {
objectB = NearestObject ();
if (objectB != null) {
posA = objectA.gameObject.transform.position;
posB = objectB.gameObject.transform.position;
objectA.gameObject.transform.position = posB;
objectB.gameObject.transform.position = posA;
}
}
}
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{
//making them public just to be able watch values change in game mode
public float movementSpeed = 10;
public GameObject g1;
public GameObject g2;
public Vector3 vec1;
public Vector3 vec2 = new Vector3(2F, 2F, 2F);
public bool swapBack = false;
void Start()
{
g1 = GameObject.Find("Cube");
g2 = GameObject.Find("Sphere");
vec1 = new Vector3(g1.gameObject.transform.position.x, g1.gameObject.transform.position.y, g1.gameObject.transform.position.z);
vec2 = new Vector3(g2.gameObject.transform.position.x, g2.gameObject.transform.position.y, g2.gameObject.transform.position.z);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
transform.Translate(Vector3.right * movementSpeed * Time.deltaTime);
swap(swapBack);
}
}
public void swap(bool back)
{
if (back)
{
g1.transform.position = vec1;
g2.transform.position = vec2;
swapBack = false;
}
else
{
g1.transform.position = vec2;
g2.transform.position = vec1;
swapBack = true;
}
}
}
public class green : MonoBehaviour
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "BLUE")
{
Destroy(other.gameObject);
gm.mylife -= 1;
}
}
}
public class gm : MonoBehaviour
{
public GameObject blue;
static public bool tr = false;
public Text life;
public static int mylife = 0;
void Start()
{
makebox();
}
void makebox()
{
StartCoroutine("timedelay");
}
IEnumerator timedelay()
{
yield return new WaitForSeconds(3f);
Debug.Log("sdfaDF");
GameObject br = Instantiate(blue, new Vector3(-6, -2, 0), Quaternion.identity) as GameObject;
makebox();
}
void Update()
{
life.text = (mylife.ToString());
}
}
I made a blue box which is destroyed when it meets something and has -1 score.
And it is made at (-2,2)position .
Then I made a prefab. But the prefab does not work as its origin. It is JUST created at the same position as its origin.
I want to make my prefab destroy and score -1 also.
How can i fix it ?
PLEASE HELP ME...
You are spawning the object at same position all the time:
GameObject br = Instantiate(blue, new Vector3(-6, -2, 0), Quaternion.identity) as GameObject;
Instead you should give a new position every time like this:
public Vector3 offSet = new Vector3(2,0,0);
Vector3 pos;
IEnumerator timedelay()
{
yield return new WaitForSeconds(3f);
Debug.Log("sdfaDF");
GameObject br = Instantiate(blue, pos, Quaternion.identity) as GameObject;
pos += offSet;
makebox();
}
GameObject blue = Instantiate(bluep);
blue.tag = "BLUE";
I solved by giving tag to the object at the script.