I’m trying to add a ‘public static class GameData’ (my script) to a GameObject.
But when i move the script as a component, the console says
“Can’t add script behaviour GameData. The script class can’t be abstract!”
What i have to do?
I’m trying to add a ‘public static class GameData’ (my script) to a GameObject.
But when i move the script as a component, the console says
“Can’t add script behaviour GameData. The script class can’t be abstract!”
What i have to do?
You can’t add a static class to an object.
Remove the static. And make sure to inherit from monobehaviour
But then, i get errors from my other scripts, like “UnityException: You are not allowed to call this function when declaring a variable.”
It would help if you pasted your scripts. Nobody can help you without seeing what you’re doing wrong. Seems like these are simple rules that are being broken. Check out some tutorials (link my in signature).
GameData script:
using UnityEngine;
using System.Collections;
public static class GameData
{
public static Camera cam = Camera.main;
public static GameObject player = GameObject.Find ("Player");
public static Rigidbody body = player.GetComponent <Rigidbody> ();
public static CharacterController control = player.GetComponent <CharacterController> ();
public static bool inGame = true; // change preference
public static bool key87 = false; // w
public static bool key65 = false; // a
public static bool key83 = false; // s
public static bool key68 = false; // d
public static bool walking = false;
public static float xRotation = 0f;
public static float yRotation = 0f;
public static float sensitivity = 10f;
public static float speed = 2f;
public static float horizontal = 0f;
public static float vertical = 0f;
public static int camMin = -80;
public static int camMax = 80;
}
KeyBinding:
using UnityEngine;
using System.Collections;
public class KeyBinding : MonoBehaviour
{
void UpdateKeyBindingSystem ()
{
if (Input.GetKeyDown (KeyCode.W))
{
GameData.key87 = true;
}
else if (Input.GetKeyUp (KeyCode.W))
{
GameData.key87 = false;
}
if (Input.GetKeyDown (KeyCode.A))
{
GameData.key65 = true;
}
else if (Input.GetKeyUp (KeyCode.A))
{
GameData.key65 = false;
}
if (Input.GetKeyDown (KeyCode.S))
{
GameData.key83 = true;
}
else if (Input.GetKeyUp (KeyCode.S))
{
GameData.key83 = false;
}
if (Input.GetKeyDown (KeyCode.D))
{
GameData.key68 = true;
}
else if (Input.GetKeyUp (KeyCode.D))
{
GameData.key68 = false;
}
if (GameData.horizontal != 0f || GameData.vertical != 0f)
{
GameData.walking = true;
}
else if (GameData.horizontal == 0f && GameData.vertical == 0f)
{
GameData.walking = false;
}
}
void LateUpdate ()
{
UpdateKeyBindingSystem ();
}
}
Nexus:
using UnityEngine;
using System.Collections;
public class Nexus : MonoBehaviour
{
void Start ()
{
GameData.xRotation = 0f;
GameData.yRotation = 0f;
GameData.sensitivity = 10f;
GameData.speed = 2f;
GameData.horizontal = 0f;
GameData.vertical = 0f;
GameData.camMin = -80;
GameData.camMax = 80;
}
void UpdateMovement ()
{
GameData.player.transform.rotation = Quaternion.Euler (0f, GameData.yRotation, 0f);
GameData.horizontal = Input.GetAxisRaw ("Horizontal")*GameData.speed;
GameData.vertical = Input.GetAxisRaw ("Vertical")*GameData.speed;
Vector3 direction = new Vector3 (GameData.horizontal, 0f, GameData.vertical);
direction = GameData.player.transform.rotation*direction;
GameData.control.SimpleMove (direction);
}
void UpdateCam ()
{
GameData.xRotation -= Input.GetAxis ("Mouse Y")*GameData.sensitivity*(Time.deltaTime*20f);
GameData.yRotation += Input.GetAxis ("Mouse X")*GameData.sensitivity*(Time.deltaTime*20f);
GameData.xRotation = Mathf.Clamp (GameData.xRotation, GameData.camMin, GameData.camMax);
GameData.cam.transform.rotation = Quaternion.Euler (GameData.xRotation, GameData.yRotation, 0f);
}
void UpdateAllVoids ()
{
UpdateMovement ();
UpdateCam ();
}
void LateUpdate ()
{
UpdateAllVoids ();
}
}
I’m just trying to add the GameData script (which is a class that just hold data of the player) to the Player GameObject, so that i can access player “properties” (which is the script) and assign other GameObjects “properties”
Add this above your GameData class:
[System.Serializable]
^ syntax for that may be incorrect, use the tool tip.
In your player class, or any mono behavior, add:
public GameData data;
You will now be able to see the properties of GameData in the inspector on the object that has the variable data declared.
Ok, that’s helpful, but that’s not what i was looking for.
I want to just put the script as a component in my Player GameObject
That’s not doable as long as the class is static. IF you want to see the properties of that static class on your object and manipulate the data, you have todo it the way I just showed you.
data.doSomething();
You can’t physically drag that script to the object.
That’s not possible with a static class. Also, components need to be derived from MonoBehaviour.
Since your GameData class is static, why would you need to add it anyway? Just access it from code.
By making something static you’re saying that there is only ever ONE of that thing. A static class, then, cannot be placed as a monobehaviour because it would mean you could add many of them.
Make a wrapper class or custom editor that modifies the static class variables, then put that on some GameObject and go to town. I’m assuming that you want to do this so you can define initial values in the inspector.
I haven’t tested serializing static classes, but I assume what I mentioned would work? no?
I haven’t tested it either, but I assume it would be fine…
Lemme whip up a test, now im curious
Thanks. Looking forward to your results. Curious too
Serializing does not seem to work, but you can still make a custom editor to access the GameData variables easily enough.
GameData is the static class
public static class GameData
{
public static string Name = "pants";
public static float Value = 12f;
}
Front End which you place on some GameObject
using UnityEngine;
public class GameDataFrontEnd : MonoBehaviour
{
void Update()
{
Debug.Log(GameData.Value);
Debug.Log(GameData.Name);
}
}
Custom Editor
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(GameDataFrontEnd))]
public class GameDataEditor : Editor
{
private readonly GUIContent _val = new GUIContent("Value!!", "Something!");
private readonly GUIContent _name = new GUIContent("Nameeroni", "Something!");
public override void OnInspectorGUI()
{
GUI.changed = false;
GameData.Name = EditorGUILayout.TextField(_name, GameData.Name);
GameData.Value = EditorGUILayout.FloatField(_val, GameData.Value);
if (GUI.changed) EditorUtility.SetDirty(target);
}
}
However in the editor code, using …
EditorGUILayout.PropertyField(serializedObject.FindProperty("Value"), _val, false);
serializedObject.ApplyModifiedProperties();
Did not work. So it does not seem like you can serialize it. Just access it via a wrapper.
That’s too complicated for me… I don’t want to do something that i don’t understand how to do it.
But if i just put public variables inside the script (so they will be visible as a Player Component), i can reffer to them inside another script?
Yes, you just have to get a reference to the script first.
How could i do that? Scopes?
If in the editor… You have to make a variable field of your script type, drag the script into it, then have code do something to that variable.
Like
public myScript reference;
...
...
reference.runSpeed = 12f;
Also, didn’t work
using UnityEngine;
using System.Collections;
public class PlayerData : MonoBehaviour
{
public Camera cam;
public GameObject player;
public bool inGame; // change preference
public bool key87; // w
public bool key65; // a
public bool key83; // s
public bool key68; // d
public float xRotation;
public float yRotation;
public float sensitivity;
public float horizontal;
public float vertical;
public Rigidbody body;
public CharacterController control;
}
using UnityEngine;
using System.Collections;
public class KeyBinding : MonoBehaviour
{
private PlayerData gameData;
void UpdateKeyBindingSystem ()
{
gameData.key87 = true;
}
void LateUpdate ()
{
UpdateKeyBindingSystem ();
}
}
It says: “NullReferenceException: Object reference is not set to an instance of an object. KeyBinding.UpdateKeyBindingSystem () (at Assets/Scripts/KeyBindings.cs:10)”
Please, someone?