Unity Add Component - c#

I am having some trouble in unity with adding a script I wrote to a cube in runtime. I have seen lots of other people asking about this but they seem to have fixed it.
Code:
// Insert
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
// Appearance
cube.GetComponent<Renderer>().material.SetColor("_Color", Color.yellow);
Shader transparent;
transparent = Shader.Find("UI/Default");
cube.GetComponent<Renderer>().material.shader = transparent;
//
//
// Postioning
//cxcxcxcxc
cube.transform.position = new Vector3((xpos), (ypos), zpos);
cube.transform.localEulerAngles = new Vector3(90, 0, 0);
var myScript = cube.gameObject.AddComponent<CoinCollect>();
This code creates a cube, adds shaders and positions it. I would now like to add a script to it which I have created called "CoinCollect" which is done with the last line of code. This doesn't spring up any errors but when the game is run the script isn't added. Could someone help? I looked at the documentation but it mainly showed what I was doing.

Make sure that the script name and class name within the scripts are equal. Other than that, there is nothing wrong with your code. Even the official docs do it in the same way:
Unity Docs:
// Adds the sphere collider to the game object
SphereCollider sc = gameObject.AddComponent<SphereCollider>();
And this answer on Unity Answers suggest the same way to add scripts:
AddComponent and GetComponent use the name of the class in the script, not a path to the script.
AddComponent("DestroyOnTouch");
Or preferably:
AddComponent<DestroyOnTouch>();
As this will give you a compile time error if the class cannot be found, rather than a runtime error.
Also:
How do you know that the script doesn't work? Try a simple Debug.Log() and verify, it might be some error in the script itself.
Does the code you posted in the question ever get executed? Where have you placed it? In a script? Then check that it is attached to some gameObject or gets called. Also, you might consider checking whether the method in which you wrote the code gets called.
To check the above, place a Debug.Log("The main script ran"); in the same code block and run your game. Then, check the console in Unity.

Related

Stopping the character from moving

So I'm using the unity standard assets pack and I was trying to figure a way to freeze the players location, at first I tried to freeze the players location using the rigidbody but the character was still able to walk. Next I tried to disable the script that allows the player to move but I cannot see the script is other scripts (when I use public script name variable name it doesn't show up as a script name.
Since I can’t see the script, I don’t have much to go off of, but I’m assuming you’re using some either Input.Horizontal and Input.Vertical, or Input.getKey() to do your things.
If you want to freeze the movement, you can simply wrap the function for movement that you are using in an if statement with some kind of bool that contains whether or not the player should be frozen.
Example:
If(!frozen){
Player.Position.x += 5;
}
Or something like that.
If you need to get the variable in another script you could do something like this (this is a rough example to try to explain it, syntax may not be perfect):
GameObject player;
Player.MoveScript.frozen = false;
Something like that.

Destroying Instantiated Clone Components Breaks Original Game Object Components?

Maybe im missing something obvious but to keep it short. I have working code for a character. When you "dash" I want to leave behind an after-image type effect, by cloning the player, removing its unneeded components and then applying a shader. Issue is as soon as I instantiate the clone the original player stops functioning (cant move etc). It still has all its components and everything as normal, and the clone does get the correct components removed. But it still breaks. As soon as I remove that line, its back to normal. Any ideas?
This is the only relevant code in the script that instantiates the clone.
private void DodgeEffect()
{
GameObject _DodgeSFX = Instantiate(gameObject, transform.position, transform.rotation );
Destroy(_DodgeSFX.GetComponent<PlayerController>());
Destroy(_DodgeSFX.GetComponent<PlayerCombat>());
Destroy(_DodgeSFX.GetComponent<WarpController>());
Destroy(_DodgeSFX.GetComponent<Animator>());
}
its because you are making a copy of gameObject. while Instantiate() returns a GameObject, it also returns whatever you put into the first section of the method. instead, make a seperate gameObject than the player in the editor, and make _DodgeSFX public so you can put the copy into the slot. Then, just instantiate that seperate GameObject and you wont have to destroy the components through script(because you remove the components in the editor), saving time
Ok so from some testing I think its down to the Unity.InputSystem only allowing 1 instance of each Input to be enabled at once. When I instantiated a clone of the player, it still goes through the Enable/Awake functions before those components are destroyed, and since the Inputs on that clone were never disabled, that becomes the "main" one. If I set the main player's scripts with Inputs deactive and then active again, it all works as normal. Note that the script was still working on the main character just fine, it was only the inputs that was broken. Im still not sure why this is the case, if its a limitation of the input system, or intentional, cant seem to find documentation of this experience anywhere.

Unity: Camera.main is failing after I switch scenes

I am having a weird issue with some of my code, and I could really use some help.
I have a script attached to a gameobject that is unique to a particular scene, so anything within Start() will only run when that scene is loaded. In this script, I am accessing Camera.main, since I use settings attached to the camera gameobject (it may sound inefficient, but it is necessary for the style of game we are creating). Anyway, if I start from that scene directly in Unity, it works just fine, but if I start from my intro scene and then load into the aforementioned scene, I get this error:
MissingReferenceException: The object of type 'Camera' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
The weird thing is, I can Debug.Log(Camera.main) and it gives me the name of the camera. So Camera.main is not null, and it is not destroyed like it says in the error message. Here is my full script:
private void Start()
{
Debug.LogError(Camera.main);
gameManager = FindObjectOfType<GameManagerScript>();
if (Camera.main == null)
{
Debug.LogError("Camera.main is null");
}
else
{
gameManager.LoadMusic(Camera.main);
gameManager.LoadAmbient(Camera.main);
gameManager.FadeStereoPan(Camera.main.gameObject.GetComponent<SwipeActivator>().stereoPanInNode);
}
}
The three functions above are custom functions I wrote, but I don't know why they would be causing the issue, since they work if I start up the scene directly.
I wasn't having this issue for months, and then all of a sudden, I am getting this error, even though I didn't change any of the code. Any help would be greatly appreciated.
I believe your MainCamera is being destroyed between scenes. Set it up as "DontDestroyOnLoad()"
See this Unity question:
https://answers.unity.com/questions/430141/need-the-same-main-camera-for-multiple-scenes.html
Ah, I fixed it. I dove into my custom functions and found that I was accessing a camera variable that is set at the beginning of the game, and then on each camera transition, but it was failing since I was loading a scene and no transitions that scene had yet to be completed. I just had to reassign that variable in the script above so it was not pointing to the destroyed object in the previous scene. Thank you JiveTurkey for pointing me in the right direction!

How to find a GameObjects Prefab during runtime with Unity version 2018.3

After updating to Unity 2018.3.0f2 I`m unable to find a GameObjects prefab while the game is running. In the previous versions i was simply using this line:
GameObject prefabObject =
PrefabUtility.GetCorrespondingObjectFromSource(gameObject);
But after the update this function only returns null, so I tried the new functions:
PrefabUtility.GetPrefabInstanceHandle
PrefabUtility.GetNearestPrefabInstanceRoot
PrefabUtility.GetOutermostPrefabInstanceRoot
but all of them return null but I`m sure that I am handing a prefab over as parameter. Any ideas what I am doing wrong here?
As soon as editor start playing (Application.isPlaying=true) prefab linkage with scene game objects will be broken (blue game objects turned into gray) and thus you cannot obtain prefab related information from it.
If you really need a scenario were you want to access such information on runtime, you should save it as Serialized variable in script component so that it will later available on runtime.
For example: this is a simplified contraption of what Mirror (Unity network plugin) is doing by issuing asset ID related stuff to help distinguish each prefab to spawn things in network on runtime.
[SerializeField] string m_AssetId;
void OnValidate() // Which will be called on build or editor play
{
#if UNITY_EDITOR
// Deposit UnityEditor API dependent into some field
m_AssetId = UnityEditor.AssetDatabase.GetAssetPath( gameObject );
#endif
}
Anyway, for running editor script, if you want to test or look for original prefab. UnityEditor.PrefabUtility is somewhat hard to find a full example of how to use them.
You can refer to my git repository on how to use them with examples.
https://github.com/wappenull/UnityPrefabTester

"Object reference" needed in script

I am currently working on a foxes & rabbits simulation, and I am completely stuck on "breeding".
The way I have built the simulation, three scripts are used; “TheGame”, “FoxScript” and “RabbitScript. Since the foxes and rabbits are essentially the same, we can reduce these three to two scripts; “RabbitScript” and “TheGame”. The RabbitScript is attached to the respective prefab; the “rabbitPrefab”, whereas TheGame is attached to an empty GameObject.
TheGame instantiates a number of RabbitPrefabs, which then move, age and breed. Since the build is supposed to collect and present data at a later stage, the rabbits are included in a list as well as being counted. This list is found in the main script, and when the rabbits breed, the offspring needs to be included in this list as well as adding to the counter.
I have tried instantiating a primitive with this method, and it works.
The Breed function in the script attached to the rabbits:
void Breed(){
float p = Random.Range (0.0f, 1.0f);
if (p < probability2breed) {
position = gameObject.transform.position;
TheGame.BreedRabbit(position);
}
}
And the BreedRabbit method in TheGame script:
public static void BreedRabbit(Vector3 position) {
GameObject rabbit = Instantiate(RabbitPrefab) as GameObject;
rabbit.transform.position = new Vector3(position);
Rigidbody gameObjectsRigidBody = rabbit.AddComponent<Rigidbody>();
rabbit.GetComponent<Rigidbody>().useGravity = false;
rabbit.name = "Rabbit#:" + rabbitCount;
rabbit.tag = "rabbittag";
rabbits.Add(rabbit);
rabbitCount++;
}
NOTES: (I figure a lot of this code seems pointless, so to answer any questions about that beforehand: I use collider to handle interactions between the agents involved, and to my understanding this calls for a rigidbody. With rigidbody they started falling, even without mass, so I had to turn of gravity. The tags are to my understanding needed for collision handlig as well.I could probably skip the count and just count the list, but this shouldn't matter now)
It keeps asking for an object reference , and I just can't figure out how this can be solved?
THe error message: "an object reference is required for the nonstatic field method or property"
I'd assume the object reference error occurs on this line?:
GameObject rabbit = Instantiate(RabbitPrefab) as GameObject;
If this is the case, it may be because the prefab hasn't been set, i.e, the script doesn't know what RabbitPrefab is.
You could set a variable in the script, and then drag your prefab onto the corresponding slot into the inspector:
public GameObject theRabbitPrefab;
GameObject rabbit = Instantiate(theRabbitPrefab) as GameObject;
If this is not the case, can you edit your question to where you are getting the error? Surely the error states which line of code the error is being generated from? :)
Edit: From Diego, if this is the case, you can add the rigidbody and configure it in your prefab, and you won't need to do it in the code for every new rabbit!

Categories