Unity light scripting - c#

I just started Unity last week, but I have a few years of programming experience. I want a light to come on when the game ends. Here is my code, the light doesn't light up.
using UnityEngine;
using System.Collections;
public class Collide : MonoBehaviour {
// Use this for initialization
void OnTriggerEnter(Collider other) {
light.intensity = 1;
}
}

You can toggle any bool by setting it to the opposite of its current value:
myBool = !myBool;
So you can toggle a light source by toggling its enabled state:
myLight.enabled = !myLight.enabled;
Now you want to do that if you press a certain button:
Light myLight = lightPoint.GetComponent("Light");
if (Input.GetButtonDown("Fire1")) {
myLight.enabled = !myLight.enabled;
}
If you copy/paste the code as is, it won't work. The code given is in C#, so you'd need to create a C# script (with all the attendant file/class name matching) and put the if expression inside the Update function.

Related

Why Camera.current returns null when I am in Unity Editor? And is there any other ways to catch the current camera?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class SkyBox : MonoBehaviour
{
public Material[] skyboxes;
public Camera skyboxCamera;
public float skyboxMoveSpeed = 2f;
private int index = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
SwitchSkybox();
}
if (RenderSettings.skybox == skyboxes[1])
{
RenderSettings.skybox.SetFloat("_Rotation", Time.time * skyboxMoveSpeed);
}
}
public void SwitchSkybox()
{
index++;
if (index == skyboxes.Length)
{
index = 0;
}
RenderSettings.skybox = skyboxes[index];
if (RenderSettings.skybox == skyboxes[1])
{
skyboxCamera.enabled = true;
Camera.current.enabled = false;
Time.timeScale = 1.0f;
}
else
{
skyboxCamera.enabled = false;
Camera.current.enabled = true;
Time.timeScale = 0.0f;
}
}
}
The script switch between skyboxes the default and my skybox and also switch between the currently active camera and the sky box camera.
But when I'm hitting the escape key it's throwing null exception in the editor on the line number 46 :
Camera.current.enabled = false;
The current of the Camera is null
I want to make that when I press the escape key it will switch to my skybox and to the skybox camera and also will pause the game (Later I will make a main menu when the game is paused).
This is the Camera.current, from the manual.
The camera we are currently rendering with.
Also worth noting the comment from Ruzihm.
The Unity engine typically assigns an already-instantiated instance of
Camera to Camera.current
So, from your scripts, I see 2 issues. The one directly related to this questions happens just in editor mode and I will start from that one.
Editor Issue: Camera.current is null
When working in the editor, Camera.current won't be just your own application's camera, but it could be any camera. It could even refer to the editor's scene view camera.
In this last case, if your scene view is not in focus (IE when you've focus on Game Window) Camera.current will be null.
Logical Issue: you couldn't switch back
When you try to switch back from skyboxCamera, your Camera.current will be the same skyboxCamera, and not your default camera. So you won't be able to retrieve the previous camera.
SOLUTION
Do not use Camera.current, but store all of your cameras in your script (this solution is also better for perfomance, since both Camera.current and Camera.Main are not performant scripts).
In your case you will need to add this piece of code to your script and use the EnableSkyBoxCamera method.
public Camera defaultCamera;
public Camera skyBoxCamera;
private Camera _currentCamera;
public void EnableSkyBoxCamera(bool enableSkyBox)
{
defaultCamera.enabled = !enableSkyBox;
skyBoxCamera.enabled = !enableSkyBox;
if (enableSkyBox) _currentCamera = skyBoxCamera;
else _currentCamera = defaultCamera;
}
If camera is null you can't set the enabled to false without getting a nullpointerexception. Instantiate the camera first or remove that line of code.
*** Edit ill take another crack at this
try
Camera.main.enabled = false;
instead of
Camera.current.enabled = false;
As per Unity docs in reference to Camera.current: 'Most of the time you will want to use Camera.main instead. Use this function only when implementing one of the following events: MonoBehaviour.OnRenderImage, MonoBehaviour.OnPreRender, MonoBehaviour.OnPostRender'

Unity Animation playing from coroutine

As the title states the animation is not playing. the line telling it to play is in a coroutine and the code is before a waitforseconds(3f).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Play : MonoBehaviour {
public Animator AnimatorRef;
// Use this for initialization
void Start () {
if (AnimatorRef == null)
{
AnimatorRef = GetComponent<Animator>();
}
}
public void PlayGame()
{
StartCoroutine(TitlePlay());
Debug.Log("playing");
}
IEnumerator TitlePlay()
{
Debug.Log("playing1");
AnimatorRef.SetBool("Enlarge", true);
yield return new WaitForSeconds(3f);
Debug.Log("playing2");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
}
it grabs the animator reference fine and all three of the comments show.
2 Considerations.
1st -
Did you check your transitions and AnimationController?
You can open up the AnimationController to see if the bool changes during runtime, if it does you'll know there is a transition error somewhere between your animation states.
2nd -
If you comment out the "LoadScene" part, does the animation then play correctly?
I suspect that the Animation bool is for some reason not allowed to carry out it's actions before the entire method has been run through, could be wrong though.
My unity shutdown without saving but it now works. If anyone has this problem remake the animation and MAKE SURE you go from the initial animation and click add clip. Then it worked for me :)

What is the difference between playing Animator State and/or playing AnimationClip ? And why i can't play animation clips?

The states and animations not my own.
I have a prefab of a character that have Animator component attached to it. The character in the Hierarchy have Animator with some states and blends and also have some animation clips.
Now when i play/run a State of the Animator is that meaning i'm playing animation? Or the animation clips is something else ?
And why i can't playing the animation clips ? I'm not getting errors or exceptions it's just not playing it.
Here is a script that attached to this character and i also added to this character a Animation component. So now the character object have both Animator and Animation components.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SwitchAnimations : MonoBehaviour
{
private Animator animator;
private int index = 0;
private static UnityEditor.Animations.AnimatorController controller;
private UnityEditor.Animations.AnimatorState[] an;
// Use this for initialization
void Start()
{
animator = GetComponent<Animator>();
an = GetStateNames(animator);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
animator.Play(an[index].name);
if (++index == an.Length)
index = 0;
}
}
private static UnityEditor.Animations.AnimatorState[] GetStateNames(Animator animator)
{
controller = animator ? animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController : null;
return controller == null ? null : controller.layers.SelectMany(l => l.stateMachine.states).Select(s => s.state).ToArray();
}
private void RollSound()
{
}
private void CantRotate()
{
}
private void EndRoll()
{
}
private void EndPickup()
{
}
}
Inside the variable an there are 9 states:
Aiming
Death_A
Use
Grounded
Roll
PickupObject
Reload_Rifle
Shoot_Rifle
Empty
When i click on A key it's playing the states one by one each time i click on A Everything is working fine i can play the 9 states by clicking on A.
what i don't understand with the States is inside the editor when i'm in the hierarchy selecting the character and in the menu make: Window > Animator i see the 9 states on the LegsLayer:
But then if i click on state Grounded double click i see a blend tree and i'm not sure if this is also states or maybe this is animation clips ? Then how can i get access to them ?
Ok this is one part i don't understand yet about the Animator and what and how i can play with it.
The second part is related to AnimationClip/s and why i can't play them ?
The script for animations clips:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
public class SwitchAnimations : MonoBehaviour
{
private Animation animation;
private AnimationClip[] animationClips;
// Use this for initialization
void Start()
{
animation = GetComponent<Animation>();
animationClips = AnimationUtility.GetAnimationClips(gameObject);
foreach (AnimationClip clip in animationClips)
{
animation.AddClip(clip, clip.name);
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
animation.clip = animationClips[6];
animation.Play(animationClips[6].name);
}
}
private void RollSound()
{
}
private void CantRotate()
{
}
private void EndRoll()
{
}
private void EndPickup()
{
}
private void FootStep()
{
}
}
And in the variable animationClips i have 9 animations:
Rifle_Aiming_Idle
Rifle_Aiming_Walk_F_RM
Rifle_Aiming_Walk_B_RM
Rifle_Aiming_Walk_L_RM
Rifle_Aiming_Walk_R_RM
Rifle_Idle
Rifle_Walk_F_RM
Rifle_Run_F_RM
Rifle_Sprint_F_RM
When i'm running the game and clicking on A this time i see in the Inspector inside the Animation component all the animation clips and in Animation i see the animation clip to play.
I'm not getting any errors or exceptions but it's just not playing it. The character stay still idle. Even if i choose another animation clip index to play 5 or 3 or 1 nothing is playing.
I wonder why it's not playing the animations when i click A. In this case animation number 6 from the List but still not playing.
The Animation component is a legacy component, kept in Unity to ensure backward compatibility with older projects, so you should never use it for animations.
Basically, the system works this way:
First of all, you need an Animator Controller asset. This Animator is a Finite State Machine (with substates etc.), and every single state can have an Animation Clip (you assign it via script of via Inspector in the Motion field). When the FSM enters a specific state, it will play the Animation Clip assigned.
Clearly the Animator, in order to be used by a game object, has to be assigned to that object via the Animator component.
Animation Clips are assets which contain the actual animation, they're never assigned as components to game objects, but instead they must be referenced by an Animator to be played, as I said before.
Blend trees are used to blend different animations in a seamless way by using linear interpolation. They're a "special" state of the Animator, which has multiple Animation Clips that you can interpolate to display transitions from a state to another, for example when you need to change the animation among running forward, running left and running right.
The argument is very broad, you can start to get into it by reading the official documentation about Animators, Animation Clips and Blend Trees here:
https://docs.unity3d.com/Manual/AnimationSection.html

On trigger exit subctract mana

I have perform a c# script to add mana to the slider ontriggerEnter and Subtract mana on trigguerExit wen touch on Enemy object, but it seems to have some thing wrong, the script have no errors but wen its touch the Enemy Object It Take all the mana, and not the value i set.
I am new on c# scripting, tank you in advance.
This is my Script
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class mana : MonoBehaviour {
public void addmana()
{
manaBar.value += 300;
}
public void Takemana()
{
manaBar.value -= 30;
}
public Slider manaBar;
// Use this for initialization
void Start ()
{
manaBar.value = 300;
if (manaBar != null)
{
manaBar.IsActive();
}
}
void OnTriggerEnter(Collider other)
{
// The switch statement checks what tag the other gameobject is, and reacts accordingly.
switch (other.gameObject.tag)
{
case "manapickup":
Debug.Log(other.gameObject.tag);
Invoke("addmana", 0f);
Destroy (other.gameObject);
break;
}
// Finally, this line destroys the gameObject the player collided with.
//Destroy(other.gameObject);
}
void OnTriggerExit(Collider other)
{
// The switch statement checks what tag the other gameobject is, and reacts accordingly.
switch (other.gameObject.tag)
{
case "Enemy":
Debug.Log(other.gameObject.tag);
Invoke("Takemana", 0f);
break;
}
// Finally, this line destroys the gameObject the player collided with.
//Destroy(other.gameObject);
}
Looking at your code it seems like the problem may come from your Slider component : are you sure its maxValue property is set to the right value ?
(by default this value is set to 1 : you can change it in the Inspector or programmatically calling manaBar.maxValue = 1000.0f;)
Also I'd recommend moving the case "Enemy": [...] part of your script inside the switch of your OnTriggerEnter method : I see no benefit from calling it inside the OnTriggerExit method (but I may be wrong depending on your game's logic).
Some side notes to conclude :
Try to keep your code organized as much as possible : one common layout is _Attributes (Properties) / Monobehaviour methods (Start, Update, OnTriggerEnter, ...) / Custom methods. This helps other when trying to solve your problems and will ease later maintenance of your code.
Try to respect some coding standards (same as code being organized, this will vary a lot from one person/compagny to another) : in C# method names usually start with an uppercase while property names start with a lowercase.
Finally try to stick to the "rules" you've set for yourself : here I see one of your tags is capitilized (Enemy) while the other isn't (manapickup).

simple score system in unity5

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class score : MonoBehaviour {
public int ballValue;
public Text scoretext;
// Use this for initialization
void Start () {
ballValue = 0;
}
// Update is called once per frame
void Update () {
scoretext.text = ballValue.ToString();
}
void OnTriggerEnter2D(Collider2D other)
{
if(other.gameObject.tag == "bucket")
{
ballValue = ballValue + 1;
}
}
}
ok guys what am i doing wrong over here ,i am a beginner.what i am trying to achieve here is i want my ball to fall down to the bucket and get 1 point or score ,my ball has a actual circle collider and a rigidbody and my bucket has box collider which is a trigger and both of these are prefabs which is being used multiple times in the games just in case if anyone want to know.so can anyone tell me what i am doing wrong hereor can someone guide me to the right tutorial .thank you
(after playing with it for a whilei am able to get 1 point it does not increase and i am getting this error)
Object reference not set to an instance of an object.
and it refers to this line.
void Update () {
scoretext.text = ballValue.ToString();
}
ok guys i just found the real problem,as i said the bucket is a prefab which randomly generating like the pipes in flappy bird, so after creating my core system i drag and drop the text ui into the given place ,and i apply the changes and delete that prefab and when i go back to asset and check that prefab the given place for text says none.so how can i link the text ui directly to the script so it wont dlete it self.
A way to get around this, is having a static class that holds the score and then have your buckets invoke a method in the static class to increase the score.
All you have to do then, is have an empty game object with the static class attached.

Categories

Resources