Accessing functions from different scripts in unity C# - unity3d

I am relatively new to unity and I'm trying to make collectibles in a game but i need to keep a tally of how many items have been collected but still have the collected item disappear. So far I have this. And yes the collectables are hairspray :p
Collection.cs
using UnityEngine;
using System.Collections;
public class Collection : MonoBehaviour {
public control controlSrc;
void OnTriggerEnter () {
controlSrc.AddScore();
killHairSpray();
}
void killHairSpray () {
Destroy(gameObject);
}
}
control.cs
using UnityEngine;
using System.Collections;
public class control : MonoBehaviour {
public int hcTot = 0;
public void AddScore () {
hcTot = hcTot + 1;
Debug.Log("Working");
}
}
I'm not sure why it isn't working but the console says;
NullReferenceException: Object reference not set to an instance of an object
Collection.OnTriggerEnter () (at Assets/Collection.cs:10)
Thanks:) this has been driving me crazy!

You most likely haven't connected anything to the controlSrc variable so it's empty. Hence the null reference exception.
In the Unity editor select the GameObject with the Collection.cs script, then in the Inspector set the controlSrc (most likely listed as "Control Src") by assigning the game object containing the control.cs script.

Related

I'm trying to figure out how to change from one static variable to another in the inspector

new game dev here. I'm not sure if this is a stupid question but I will ask it anyway. I'm trying to figure out how to change from one variable to another in the inspector. I have a few static variables in an empty game object called currencyMaster. Sorry if my question is hard to understand.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class currencyDisplay : MonoBehaviour
{
private TextMeshProUGUI textMecH;
void Start()
{
textMecH = GetComponent<TextMeshProUGUI>();
}
// Update is called once per frame
void Update()
{
//i want to change moneyPlus since all the variables are in
//currencyMaster
textMecH.text = currencyMaster.moneyPlus.ToString("0.0");
}
}
By default, Unity only serializes public fields. In order to expose a private variable to the inspector, you need to mark it with the attribute SerializeField.
[SerializeField] private TextMeshProUGUI textMecH;

See Methods Called Through UnityEvents in Performance Tab

So I have this script that has UnityEvent called on FixedUpdate. The idea is that I attach various methods to this OnFixedUpdate through the Editor like this:
This is the Brain script where this OnFixedUpdate resides:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using Sirenix.OdinInspector;
public class Brain : MonoBehaviour
{
[SerializeField, FoldoutGroup("Fixed Update")]
private UnityEvent OnFixedUpdate = null;
void FixedUpdate()
{
OnFixedUpdate.Invoke();
}
}
But the problem is that in the Performance tab I only see the Brain.OnFixedUpdate method called. I can't see what specific methods were called through this OnFixedUpdate:
Is there a simple way to see the methods that are being called through OnFixedUpdate?
Use:
for(int i=0;i<OnFixedUpdate.GetPersistentEventCount();i++){
Debug.Log(OnFixedUpdate.GetPersistentMethodName(i));
}

Unity Random is detroying all objects

I'm trying to make the system work so that when a game starts and for each wall, it will either be in the game or not, randomly. Somehow, when I run it, it either keeps or destroys all the walls. How do I fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallGen : MonoBehaviour{
public GameObject wallObject;
System.Random rnd = new System.Random();
// Use this for initialization
void Start () {
generate();
}
void generate()
{
int number = rnd.Next(1, 5);
if (number == 2)
{
OnDestroy();
}
}
private void OnDestroy(){
Destroy(wallObject);
}
// Update is called once per frame
void Update () {
}
}
Every time you do new System.Random() it is initialised using the clock. Now as the Start function is called at the same time, you get the same value for all the gameobjects. You should keep a single Random instance for all gameobjects and keep using Next on the same instance.
Or the easy solution
just Use Random.Range (1,5) instead of rnd.Next(1, 5);
As a side note, don't use the function name OnDestroy, as it is one of the MonoBehaviour functions in Unity and is called automatically when the attached gameobject is destroyed.

Unity Editor Can't Edit Multiple Objects

I want to build a custom inspector for one of my classes... and well... I thought I would start simple ... and I still can't get it to draw the basic inspector:
My editor script is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(AbilityBluePrint))]
[CanEditMultipleObjects]
public class AbilityBluePrintEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
// Show default inspector property editor
DrawDefaultInspector();
}
}
And the class I want to edit is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[CreateAssetMenu(fileName = "New Ability BluePrint", menuName = "Ability BluePrint")]
public class AbilityBluePrint : ScriptableObject {
public AbilityName abilityName;
public Characteristic[] characteritics;
public Effect[] effects;
public float coolDown;
public Sprite icon;
public string description;
}
Any suggestions, on how to solve the "multi-object editing not supported" message I get instead of my beautiful custom editor ??
You need to use Serialized properties if like to use Multiple object edition.
[CustomEditor(typeof(AbilityBluePrint))]
[CanEditMultipleObjects]
public class AbilityBluePrintEditor : Editor
{
var AbilityName : SerializedProperty;
function OnEnable ()
{
// Setup the SerializedProperties
AbilityName = serializedObject.FindProperty ("Ability");
}
function OnInspectorGUI()
{
// Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
serializedObject.Update ();
...
This is not explained in the documentation and I think it is quite important.
Apart from the option of using Serialized Properties, if you are not able to use those, in case you have your own items, not using the automatically managed Serialized Properties, then you have to use "targets" variable instead of "target".
I noted that if you select different types of objects with no shared script, it doesn't show shared properties, so we don't need to check if the targets are all the same type, it is always one or more. Then you do whatever you want to do by hand with each of them, inside a foreach loop.
Here's a working example of the contents of OnInspectorGUI method inside an Editor class with a simple checkbox that is changed across several scripts. Hope it helps.
var myScript = (UnityTerrainWrapper)target;
var allSelectedScripts = targets;
EditorGUI.BeginChangeCheck();
var value = GUILayout.Toggle(myScript.ShowNativeTerrain, "Draw Unity Terrain");
if (EditorGUI.EndChangeCheck())
{
foreach (var script in allSelectedScripts)
((UnityTerrainWrapper)script).ShowNativeTerrain = value;
SceneView.RepaintAll();
}
DrawDefaultInspector();

Cannot call IVirtualButtonEventHandler Vuforia 5.0.10

Im using Unity 4.7.0 and Vuforia 5.0.10, i cannot call the IVirtualButtonEventHandler.
using UnityEngine;
using System.Collections;
public class VBEventHandler : MonoBehaviour, IVirtualButtonEventHandler
{
}
I just came across this, hope you're still using Unity & Vuforia. You need to add using Vuforia to make the call.
using UnityEngine;
using System.Collections;
using Vuforia;
Register the Virtual Button:
To add a virtual button to an image target, add the VirtualButton element and its attributes to the ImageTarget element in the .xml file.
XML Attributes:
Name - a unique name for the button
Rectangle - defined by the four corners of the rectangle in the
target's coordinate space
Enabled - a boolean indicating whether the button should be enabled
by default
Sensitivity - HIGH, MEDIUM, LOW sensitivity to occlusion
After Registering Virtual Button Code is simple then:
using UnityEngine;
using System.Collections;
using Vuforia;
public class Custom_VirtualButton : MonoBehaviour, IVirtualButtonEventHandler
{
// Use this for initialization
void Start () {
// here it finds any VirtualButton Attached to the ImageTarget and register it's event handler and in the
//OnButtonPressed and OnButtonReleased methods you can handle different buttons Click state
//via "vb.VirtualButtonName" variable and do some really awesome stuff with it.
VirtualButtonBehaviour[] vbs = GetComponentsInChildren<VirtualButtonBehaviour>();
foreach (VirtualButtonBehaviour item in vbs)
{
item.RegisterEventHandler(this);
}
}
// Update is called once per frame
void Update () {
}
#region VirtualButton
public void OnButtonPressed(VirtualButtonAbstractBehaviour vb)
{
Debug.Log("Helllllloooooooooo");
}
public void OnButtonReleased(VirtualButtonAbstractBehaviour vb)
{
Debug.Log("Goooooodbyeeee");
}
#endregion //VirtualButton
}