I have started learning Unity and already have learned JavaScript for web development so I do have some programming experience.
While programming in unity I came across a few things involving classes that I didn't quite get.
1) When I wright code as a component of a unity object I write it inside the public class shown below. (name Mover is just an example.) However I never create an instance of this class so how does this work? All I see is the class being created.
using UnityEngine;
using System.Collections;
public class Mover : MonoBehaviour {
}
2) Also shown in the code above is MonoBehaviour. I read the api and it said it is a base class. I never came across this in JavaScript. What does this mean and what does it do to the class Mover?
Try this.
Go to your project in Unity, create a c# script, name it whatever you want. Create a cube in your scene. Drag and drop this script onto the object. Open the script and you should see a start method and an update method.
Type Debug.Log("Start"); in the void Start() function, same in the void Update() method but change to the string to whatever. Click play in unity and watch the console.
You should see the console printing stuff.
Anything that is a child of Monobehaviour enables you to do a lot in which I am not going to get into here.
https://docs.unity3d.com/Documentation/ScriptReference/
At the top, you can choose the language. Get used to that page. =D
Hope this leads you somewhere!
For the first question, you may attach the script to a gameobject in the scene to use it.
For example,
public class Mover : MonoBehaviour {
private bool started = false;
void Start () {
Debug.Log ("Mover Started");
started = true;
}
}
If you attach this script to a gameobject in your scene and play the scene. The script will run and print out "Mover Started" and set the private boolean to true.
This are many other ways to interact with other objects or scripts too. Hope it clears things up a little.
If you take a look at Unity's docs for MonoBehaviour you'll see that every JS file associated with your project automatically derives from MB. If you're coding c#, understand that not everything must be a MB. Objects in the game hierarchy may only attach component scripts that inherit from MB objects. Unity handles the construction of these objects, and a MB is actually something that you are forbidden from constructing yourself.
Also, I think you might be better off at unityAnswers for Unity related help.
Related
So, i'm trying to make a Multiplayer Game here with various game objects and scripts in c# for every object on the scene.
Thing is, when i spawn the player controlled objects every player shares control over scripts for each spawned gameObject on the scene, that means, when somebody presses "s" for example, every player moves backwards, and that's not how i want game to behave.
--So, the only way i know to solve this, is by spawning 'em with all their scripts (the components) disabled and enable 'em with another script on the gameobject, but i had to make a script to enable every component one by one, and it got really time comsuning to create or edit a new script every time i add a new one to new units n' so on, so i figured out i could do something like this script below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class PlayerNetControl : NetworkBehaviour {
public MonoBehaviour[] components2enable;
public override void OnStartLocalPlayer()
{
foreach (MonoBehaviour cmp in components2enable)
{
cmp.enabled = true;
}
}
}
after doing this, i expected every "monobehaviour component" i added to the script using unity, to be enabled when for the player who controlled the game object only, but it does nothing, i check the components on the gameobject testing this out, they are all still disabled.
Also, is there any way for me to solve this problem in any other way than the one i know? if so, i would love you to illuminate me teaching me how.
Please help, i've started coding recently and i really need help with C#
Check for islocalplayer.
I think this solves all your problems.
https://docs.unity3d.com/ScriptReference/Networking.NetworkBehaviour-isLocalPlayer.html
This question already has an answer here:
Error in C#: "An object reference is required for the non-static field, method, or property"
(1 answer)
Closed 5 years ago.
Doing a quick 2d game to get familiar with Unity and I came across an issue that no one else seems to have a problem with.
This is the Error I was originally receiving:
Assets/scripts/Receiver.cs(33,13):
error CS0120: An object reference is required to access non-static member
`UnityEngine.Animator.SetTrigger(string)'
I have updated the code from Animator.SetTrigger to myAnimator.SetTrigger and it has removed the error and I can test the game, but the animation does not come through.
I am looking to have these objects animate and disappear after being hit, but these are non moving objects and do not have an Idle animation. I set a trigger "IsDead" to activate the animation. I think I missed something or just not 'getting it'. I have tried to find similar problems to try and connect the dots (I'm new to c#) and ended up finding old functions from previous versions of Unity that didn't work or even exist in the same way.
before trying to add the animation, the game worked fine. I just need to see how the animation looks in-game.
I'm not trying to do individual sprite swaps. I am trying to understand how to make a death animation that connects to this prefab script that I can adapt to future prefabs. Also, can I reuse the "IsDead" trigger for separate animators in different prefab objects that have different animators attached to them?
the line in question is :
if(timesHit >= maxHits) *{Animator.SetTrigger ("IsDead");}
would this work as is with the reference?
working with prefabs and similar reacting objects in the future, this is something I want to have a good understanding of.. thank you for your time.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Receiver : MonoBehaviour {
public int maxHits;
private LevelManager levelManager;
private int timesHit;
Animator myAnimator;
void Start () {
var animator = gameObject.GetComponent<Animator>();
timesHit = 0;
levelManager = GameObject.FindObjectOfType<LevelManager> ();
}
void Update () {
}
void OnCollisionEnter2D (Collision2D col) {
timesHit++;
if (timesHit >= maxHits) {Animator.SetTrigger ("IsDead");}
}
void OnCollisionExit2D (Collision2D col) {
if (timesHit >= maxHits) {Destroy (gameObject);}
}
}
There are two kinds of Functions in strictly OOP Languages:
Static Function, that you call on the class. The Console Class functions are textbook examples for this.
Instanc functions, that you call on a specific instance. You want to SetTriggers for this specific instance.
There sometimes are static overrides - usually those require you hand in the instance as one of the arguments.
But thsi all has nothing to do with Unity or game development. That is just basic programming that you could have learned in a simple Console Appliation.
I am quite new in game development, I am using Unity in combination with C# with Models which are made in Blender.
I was wondering, if there is a way to "play" a scene from a certain point. For example, if I have a game (single scene for simplicity now) and like to test a certain part of the Game (e.g. I would like to test the 3rd of 5th quests within this scene, assuming that you can access the 2nd quest only if you successfully completed the 1st one, and so on).
But I really don't wanna to play through my scene for a while, just to reach the point which I originally wanted to test.
How can i achieve this? And if it is not possible in some simple way, is there some kind of workaround for this?
Thanks!
Not sure if I understood correctly, but if you want to jump from scene to scene, within your project, you can always use the sceneManager.
https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
Hope that helps.
In your class, create a variable that holds the value for starting quest. e.g. 3.
Then for testing purpose, in the Start() method, you can check the value of that variable and write some code to change the elements in the scene to represent the corresponding quest(3 in this case) like the position of the character, or next objective or anything that is specific to the quest.
You can make this variable public so that you can change its value from unity instead of opening the script every time.
I am not sure if it is feasible for your game, but if you have a lot of things that change for each quest, it is best to have a different scene for each one of them.
Here is the sample code on how i did it.. hope this will help you..
Create a C# script called GoScene1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoScene1 : MonoBehaviour {
public void Scene1Change() {
Application.LoadLevel("GoScene1");
}
}
Then Create a C# Script Called GoScene2
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GoScene2 : MonoBehaviour {
public void Scene2Change() {
Application.LoadLevel("GoScene2");
}
}
Heres the Screen shot...
I have almost identical classes, PaddleLeft and PaddleRight. I am tired of calling both of those classes when I need something done, I rather them be done all at once. For example, here is what I have to do:
public void pause() {
GameObject.Find("Paddle Objects/paddleRight").GetComponent<Paddle>().setIsPaused(true);
GameObject.Find("Paddle Objects/paddleLeft").GetComponent<Paddle>().setIsPaused(true);
}
And here is what I want to do:
public void pause() {
GameObject.Find("Paddle Objects/paddles").GetComponent<Paddle>().setIsPaused(true);
}
This seems unnecessary, however, in my game, there are times where the same line of code are copied and adjusted to up to ten similar objects.
Question Is there a way to make a super class like in Java for these objects. I have searched the internet and have found info, however I can't seem to understand how to make it work because I can't extend MonoBehavior and a superclass in Unity.
Thanks in advanced!
I have almost identical classes, PaddleLeft and PaddleRight
But your code is totally saying different stuff
GameObject.Find("Paddle Objects/paddleRight").GetComponent<Paddle>().setIsPaused(true);
GameObject.Find("Paddle Objects/paddleLeft").GetComponent<Paddle>().setIsPaused(true);
Maybe you want meant to write the code below?
GameObject.Find("Paddle Objects/paddleRight").GetComponent<PaddleRight>().setIsPaused(true);
GameObject.Find("Paddle Objects/paddleLeft").GetComponent<PaddleLeft>().setIsPaused(true);
I will assume the second code is what you meant to write.
When you have multiple GameObjects or Scripts with similar actions, you should create a central manager script that will make it easy to communicate with a those GameObjects or classes.
Since both your classes are called PaddleRight and PaddleLeft, You can simply call this class PaddleManager.
Don't forget that, of course, PaddleManager is just a script, it's not a "thing" in Unity. Naturally you will attach PaddleManager to some game object. You might ask "where should I attach it?" In a simple game, you might attach it to your camera, say. (Since you always have a camera, other developers working on your project always know to "look n the camera" for odds and ends like sound-effects, managers like this and so on.) Alternately, say that physically all your paddles are associated with (for example) an object that is the ping pong table. Then, a good place to attach PaddleManager.cs would be on the ping pong table. It doesn't matter where you attach it, so long as it is tidy. Some people like to make simply an empty object (you can refer to an empty object as a "marker"), just make an empty object named say "manager holder", put it at 0,0,0, and you can add scripts like PaddleManager.cs to that object.
Your PaddleManager.cs script:
public class PaddleManager : MonoBehaviour
{
private PaddleRight rightPaddle = null;
private PaddleLeft leftPaddle = null;
//Initialize variables
void Start()
{
//Get reference/Cache
rightPaddle = GameObject.Find("Paddle Objects/paddleRight").GetComponent<PaddleRight>();
//Get reference/Cache
leftPaddle = GameObject.Find("Paddle Objects/paddleLeft").GetComponent<PaddleLeft>();
}
//Call to pause and unpause
public void pause(bool pausePaddle)
{
rightPaddle.setIsPaused(pausePaddle);
leftPaddle.setIsPaused(pausePaddle);
}
}
Now, you can access both of your Paddles from one script, in another script.
public class YourOtherScript : MonoBehaviour{
PaddleManager paddleManager = null;
void Start()
{
//Get reference/Cache
paddleManager = GameObject.Find("GameObjectPaddleManaerIsAttchedTo") .GetComponent<PaddleManager>();
//To pause
paddleManager.pause(true);
//To un-pause
paddleManager.pause(false);
}
}
By doing this, you will avoid using static variable and also avoid using GameObject.FindGameObjectsWithTag("paddles")) in foreach loop like mentioned in the other answer. GameObject.Find... functions should NOT be used in the middle of the game because it will slow down your game. You need to use it once and cache the GameObject in the Start function, then you can re-use it without slowing down your game.
First of all paddle right and left are game-objects and not classes , the class name is paddle , and if the same script is on both the objects , the most simplest way would be to put it on another empty object and call it once and the code will work on all game-objects that the script is attached to . BUT! that is only regarding to what I cuold make out of your question , Here is what I really recommend , as you said "because I can't extend Mono-behavior and a super-class in Unity" . Ok so you have class A inheriting monobehavior , and you make class's B and C, then when you inherit them from A you will get all the abilities of a monobehaviour in class B and C and you can attach them to game objects , you can even make start and update functions as vrtual and override them in B and C and you can even call A's function use the keyword Base , So read on it , it will take time but in the long run makes you a better coder
Mm, wait. There is something wrong with your question:
YouPaddleLeft and PaddleRight are not classes. They are GameObjects existing in Unity scene. Class is Paddle to which you get reference by GetComponent<Paddle>() .
Now if you have a variable/function that affects all the instances of the class the same than you shell make them static. (Google static variables and functions if you don't know what they are).
So go to your Puddle class and change the declaration of setIsPaused(bool val) to this:
public static void setIsPaused(bool val) { /* implemenetation */ }
and then make a call to it via class token, not object:
Paddle.setIsPaused(true/false);
note that if the static function has references to class variables all those variables should be marked static as well. (e.g. if you have a bool isPaused than mark it static because it should be the same for all the objects all the time anyways)
I was following a unity tutorial started on Unity 4 but I am on Unity 5, and when I try to use the script seen (https://youtu.be/vwUahWrY9Jg?t=1337) and I try to use it, it gives an error:
Assets/Scripts/DestroyFinishedParticle.cs(18,17): error CS0246: The type or namespace name `Destroy' could not be found. Are you missing a using directive or an assembly reference?
this is the code:
using UnityEngine;
using System.Collections;
public class DestroyFinishedParticle : MonoBehaviour {
private ParticleSystem thisParticleSystem;
// Use this for initialization
void Start () {
thisParticleSystem = GetComponent<ParticleSystem>();
}
// Update is called once per frame
void Update() {
if (thisParticleSystem.isPlaying)
return;
Destroy (GameObject);
}
}
It can be because C# code for unity changed from 4 to 5? what should I change? The problem seems to be in the Update method.
There are couple of issues with this code.
First, you didn't mention to what exactly is it attached too? I assume it attached to the Particle System.
Secondly, use "gameObject", not "GameObject", since GameObject is the name of the class.
Third, I believe there's a much more efficient way to destroy the gameObject without checking every frame whether the particles system has finished or not, maybe set a small timer? or invoke the function with time?
Depending on how your event is set up would depend on the approach to checking if the particles are running. If you can setup a collider to when you walk in, you can trigger an event to know the particles are on. Upon exiting the collider, the particles will shut off.
I'm not 100% on the syntax of return in C# but seems like it should go after you destroy your game object. I think return works in a similar fashion as the break in that aspect.(Especially since you don't seem to be returning any values anyway why do you need it?)