I currently have a particle system that is suppposed to represent a leafblower. I have got this working to proc on and off on mouse clicks.
The thing is, I want it to "blow" objects out of the way like a realistic leafblower. I have heard some people like to use AddForceAtPosition or something like that, it's just I do not know how to use it.
Currently I am enabling and disabling a box collider when my 'leafblower' is on and having everything the collider touch be knockedback but this proves to have various in game problems.
Here is my code I am working with:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class leafblower : MonoBehaviour {
private Rigidbody rb;
protected bool letPlay;
public ParticleSystem blow;
public Collider lcol;
// Use this for initialization
void Start ()
{
rb = GetComponent<Rigidbody>();
blow = GetComponent<ParticleSystem>();
lcol.enabled = !lcol.enabled;
}
void LeafBlower()
{
if (Input.GetKeyDown(KeyCode.Mouse1))
{
var isBlowing = blow.emission;
isBlowing.enabled = true;
lcol.enabled = !lcol.enabled;
}
else if (Input.GetKeyUp(KeyCode.Mouse1))
{
var isBlowing = blow.emission;
isBlowing.enabled = false;
lcol.enabled = !lcol.enabled;
}
}
// Update is called once per frame
void Update()
{
LeafBlower();
}
void FixedUpdate()
{
}
}
What force should I be adding or what should I put in a void OnCollisionEnter()?
Thank you so much :)
What you probably need is Particle System collision OnParticleCollision.
Please check Unity Scripting API here: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnParticleCollision.html
Related
I am making a gunshot code for a zombie shooter, but for some reason whenever I fire more than once in the same time period as the other shot, they don't overlap? Is there any way I can make it so that they do? Also, it only plays occasionally when I wait
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class audioplay : MonoBehaviour
{
public AudioSource source;
public AudioClip clip;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
source.PlayOneShot(clip);
}
}
}
You wouldn't want a shoot function without any cooldown, especially in update. Also check your audio file to see if has blank space in it, like the one I used:
I used Audacity to trim the audio file. (it's free and open source :D )
Code stuff:
using UnityEngine;
public class MyPlayAudio : MonoBehaviour {
public AudioSource audioSource;
public AudioClip audioClip;
public float shootCooldown; //change this according to how fast you want to shoot
private float currentShootCooldown;
void Update()
{
//if you are holding mouse button down and we are ready to shoot
if(Input.GetMouseButton(0) && currentShootCooldown <= 0)
{
Pewpew();
}
//make sure you are not changing the public value
currentShootCooldown -= Time.deltaTime;
}
public void Pewpew()
{
//code whatever gun is supposed to do, like dealing damage
//resets cooldown for pewpew
currentShootCooldown = shootCooldown;
//plays the audio
audioSource.PlayOneShot(audioClip);
}
}
I think .Play might be better if we are thinking about a gun. I don't know, try both and see which one is better for your needs
audioSource.clip = audioClip; //this is not necessary if your gun is only going to do 1 sound.
audioSource.Play();
`
If you want it to overlap, you could for example add that component to two different gameobjects in the scene, that way there will be one frame where the function is called twice. Since Update would run on two objects.
I'm using this method and tried some others as well but unable to play the particle system(i.e for bullet shells ).
public ParticleSystem particleSystem;
void Start() {
particleSystem = GetComponent<ParticleSystem>();
}
void Update() {
particleSystem.Play();
}
Do not put your play triggers in the Update() of a MonoBehaviour because it will call play on every frame.
Try something like this instead:
public ParticleSystem particleSystem;
private bool isPlaying = false;
void Start() {
particleSystem = GetComponent<ParticleSystem>();
particleSystem.Clear(); // Reset the particles
}
void Update() {
if(!isPlaying) {
particleSystem.Play();
isPlaying = true;
}
}
Using particleSystem.Clear() before calling particleSystem.Play() can also help with particle issues.
The easiest way to stop and play a particle system is to deactivate and activate the particle system game object. To do this, the controlling script must be placed in a parent or separate object.
You have to make sure it's not already playing, or you will reset it
void Update() {
if(!particleSystem.isPlaying) particleSystem.Play();
}
okay so after trouble of hours i found that the best way to manipulate the particle system i.e activate and detivate on your will is to create an empty gameobject assign the particle system you made to it and then on and off this gameobject exactly at which part in the code you want to by setActivce command. I hope it will help someone in someway
I am a bit stuck with lights management.
I have 4 lights; each with a tag ""lights_hall". In my code, I do assign all these lights to a gameobject list
roomlights = Gameobject.FindGameObjectsWithTag("lights_hall");
I get the list with the gameobjects, which I assume they are lights.
Then I go through each element of the list, to turn them on and off, but I get an error when the script try to retrieve the component "Light".
foreach (GameObject single_light in roomlights)
{
if (single_light.GetComponent<Light>().intensity == 1)
single_light.SetActive(false);
else
single_light.SetActive(true);
}
Unity tell me that there is no light component attached to the gameobject. How is this possible if the light component is part of a light gameobject?
I did check some examples and they all do the same: create a list of gameobjects, use find to get all the lights that has the tag as specified, and then access the light component for each element in the list.
Am I missing something here? I did also try to access each single element light component, so I can use .enable, but it does not appear in auto completion.
EDIT==================================
This is the script that I use; it is attached to a simple cube, which has a collider, so when the first person controller get in the trigger area, and you press "l" on the keyboard, the ligths should turn off.
I did verify the names, and the names are matching the point light game objects in the scene; although Unity print the error "MissingComponentException: There is no "Light" attached to the "switch" game object, but a script is trying to access it. You probably need to add a Light to the game object "switch". Or your script needs to check if the component is attached before using it"
The ligts are point lights; nothing out of the ordinary.
using UnityEngine;
using System.Collections.Generic;
public class LightsSwitch : MonoBehaviour {
private bool istriggered = false;
public GameObject[] roomlights;
// Use this for initialization
void Start () {
roomlights = GameObject.FindGameObjectsWithTag("lights_hall");
foreach (GameObject light in roomlights)
Debug.Log(light.name);
}
// Update is called once per frame
void Update () {
if (istriggered && Input.GetKeyDown(KeyCode.L))
{
foreach (GameObject single_light in roomlights)
{
if (single_light.GetComponent<Light>().intensity == 1)
single_light.SetActive(false);
else
single_light.SetActive(true);
}
}
}
void OnTriggerEnter(Collider world_item)
{
istriggered = true;
Debug.Log("light switch");
}
void OnTriggerExit(Collider world_item)
{
istriggered = false;
Debug.Log("light switch gone");
}
}
A few issues.
First, in your code:
roomlights = Gameobject.FindGameObjectsWithTag("lights_hall");
Make sure to change Gameobject to GameObject.
Now, assuming roomlights is a GameObject[], set your code as follows:
foreach (GameObject single_light in roomlights)
{
if (single_light.GetComponent<Light>().enabled == true)
single_light.SetActive (false);
else
single_light.SetActive (true);
}
My suggestion would be to disable the Light component, rather than the whole GameObject itself. This can be achieved with:
single_light.GetComponent<Light>().enabled = false;
I've setup an example project, this implementation should work for you.
using UnityEngine;
using System.Collections;
public class turnofflight : MonoBehaviour {
public GameObject[] roomlights;
// Use this for initialization
void Start () {
roomlights = GameObject.FindGameObjectsWithTag("light_comp");
foreach (GameObject light in roomlights)
Debug.Log(light.name);
}
// Update is called once per frame
void Update () {
foreach (GameObject single_light in roomlights)
{
if ((single_light.GetComponent<Light>().intensity == 1.0f))
single_light.SetActive(false);
else
single_light.SetActive(true);
}
}
}
I'm having no issues with this implementation.
I'm having an issue where I can't disable a script from the other script - they are both public and within the same package (I think).
Here is my code for the script I'm trying to disable from:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
using RTS;
public class PauseMenu : MonoBehaviour {
Canvas canvas;
private Player player;
public Button Button2;
void Start()
{
Debug.Log ("asdf");
player = transform.root.GetComponent< Player >();
canvas = GetComponent<Canvas>();
canvas.enabled = false;
ResourceManager.MenuOpen = false;
Button2.GetComponent<Button>().onClick.AddListener(() => { Resume();});
if(player) player.GetComponent< UserInput >().enabled = false;
}
And the code for the other script:
//sets up what resources we are using
using UnityEngine;
using System.Collections;
using RTS;
public class UserInput : MonoBehaviour {
//sets up a private variable for only this class - our player
private Player player;
// Use this for initialization
void Start () {
//this goes to the root of the player ie the object player and allows us to
player = transform.root.GetComponent< Player > ();
}//end Start()
So the part that is not working is:
if(player) player.GetComponent< UserInput >().enabled = false;
And the code runs and then causes the runtime error:
NullReferenceException: Object reference not set to an instance of an object
PauseMenu.Pause () (at Assets/Menu/PauseMenu.cs:40)
PauseMenu.Update () (at Assets/Menu/PauseMenu.cs:29)
Here is a picture showing my scene hierarchy and components:
The issue here is that you try to execute transform.root.GetComponent< Player >(); from within PauseMenu, which is on the "Canvas" object.
The problem with that is that the topmost transform in the hierarchy of your "Canvas" object (which is what transform.root returns) is, well, the transform of the "Canvas" object - which is in no way related to the UserInput script you are trying to access. For this script to actually work, you would need the transform of your "Player" object, which is the object that actually has the UserInput script.
My suggestion is to eliminate the need to run GetComponent() at all - create a public UserInput variable in your PauseMenu class, then (while selecting your "Canvas") in the editor, drag the "Player" object into that new field. This will cause the UserInput script of your "Player" object to be accessible within the PauseMenu.
So your PauseMenu script might look like:
public class PauseMenu : MonoBehaviour {
Canvas canvas;
public UserInput playerInput; // Drag the Player object into this field in the editor
public Button Button2;
void Start()
{
Debug.Log ("asdf");
canvas = GetComponent<Canvas>();
canvas.enabled = false;
ResourceManager.MenuOpen = false;
Button2.GetComponent<Button>().onClick.AddListener(() => { Resume();});
playerInput.enabled = false;
}
}
Hope this helps! Let me know if you have any questions.
(An alternative is to use GameObject.Find("Player") to get GameObject of "Player". This needs a bit more code but doesn't use the editor.)
I would say your player = transform.root.GetComponent< Player >(); arrives null.
So you are trying to disable something that doesnt exist.
Enter debug mode and see if your player is null or not.
I recently started messing with the Unity 5 Scripting API and I can't seem to make this piece of code work for my Simple Smiley Face Sprite1. All I want it to do is move slightly. I have tried multiple solutions. I believe it is not accepting the key board button or it is not finding the sprite. Thank you for the help in advance!
...Super simple code, I am just experimenting.
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKey ("q")) {
var Sprite1 = GameObject.Find("Sprite1");
Sprite1.transform.Translate(1,3,5);
}
}
}
try using KeyCode.Q:
if(Input.GetKeyDown(KeyCode.Q))
{
var Sprite1 = GameObject.Find("Sprite1");
Sprite1.transform.Translate(1,3,5);
}
if (Input.GetKeyDown(KeyCode.Space))
{
Vector3 forward = transform.TransformDirection (Vector3.forward) * 10;
}
you can simply add this code to your sprite and change the number 10 or any other the speed you want