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
Related
Hi I'm new to coding games and using Unity, when I switch Scenes in unity the objects 100x and the saturation gets weird
Here is my current script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Game_End : MonoBehaviour
{
int Pins = 0;
void OnCollisionEnter(Collision collision)
{
Pins += 1;
}
// Update is called once per frame
void Update()
{
if (Pins == 4)
{
SceneManager.LoadScene("Level 2", LoadSceneMode.Additive);
}
}
}
Welcome to Unity! There are a few issues I can see, so I will try to explain each one. The main issue you are currently having is you are loading a scene on top of itself using the LoadSceneMode.Additive. It is loading the scene Level 2 on top of itself as long as Pins is equal to 4, which I am guessing is every frame.
I would instead put this check inside of the OnCollisionEnter as it should only be called once. Your other issue is you are not checking what you are colliding with. You might want to check the object you hit by tag. If you are unfamiliar with tags, you can look at the docs. Adding a tag to your game called Pins and adding it to all of your objects that are pins will help resolve what you are colliding with.
Now to solve the near infinite amount of scenes you are spawning. As I mentioned, it is because your conditional check is in Update, which in Unity is called every frame. With the condition you are currently checking for, if pins is not reset, it will keep loading your scene. As you are also using the Scene.Additive, it will load the new scene on your old scene, so the variable pins will not reset unless you collide with something else. I would recommend changing your code to this example:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Game_End : MonoBehaviour
{
int Pins = 0;
void OnCollisionEnter(Collision collision)
{
// we are only checking if the object we hit is tagged as 'Pins' to make sure we hit a pin
if(collision.gameObject.tag == "Pins")
{
// add to the pins
Pins += 1;
// destroy the pin we hit so the player can not hit it twice
Destroy(collision.gameObject);
// check our condition to load the new scene
if(Pins == 4)
{
SceneManager.LoadScene("Level 2");
}
}
}
}
Now that you are only checking if the collision is with an object tagged as Pin, the counter will only go up when you collect a pin. By adding the Destroy, you assure that each pin will only increase the count by 1. And finally, by putting your level check inside of this function, it will only check your condition when it increases the count. My one question is, do you want to use LoadSceneMode.Additive? It loads a scene directly over your current scene. I believe you'd want to load the scene normally so it loads your new scene. Would you mind clarifying how you want to load the new scene a bit more? In my example snippet I removed the additive as I believe you do not want to use it. The docs Unity has for LoadScene use it, so I assume you got it from there.
If you do not understand any of what I said, feel free to ask any questions in the comments. I can tweak the answer as needed to help you understand.
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'm a student and I'm doing a 2D platform game as a project but my programming skills are so bad(That's why I'm trying to do the code by myself) but I'm stuck on that and I don't really have an idea about whats going on. Let me explain.
I've got my Player GameObject with his script playerBehaviour actually working and a BoxCollider2D marked as a Trigger
This Player, also tagged as Player, it's inside a Trigger that belongs the the GameObject LiveZone, who has the DeathZone script below.
using UnityEngine;
using System.Collections;
public class DeathZone : MonoBehaviour {
public PlayerBehaviour playerBehaviour;
void OnTriggerExit2D (Collider2D other) {
if (other.tag == "Player") {
playerBehaviour.respawn = true;
Debug.Log ("Respawn");
}
Debug.Log ("Exit Collider");
}
}
I also tried to do it in a most common way, setting the limits of the "LiveZone" with some triggers to delimitate the area with "DeathZoneTriggers"(that's why the script was called DeathZone at first). But I had the same problem with the OnTriggerEnter2D ().
It looks like it doesn't want to detect my Player leaving or entering this area, as you can see I also called some Debugs, but are not working neither.
To organize information you may also need(or not):
2 GameObjects with Triggers
"Player", who has to exit the zone and "AliveZone", who should detect who's leaving.
Player is tagged as "Player", AliveZone has no tag(don't know if that would mean something)
Any idea?
God I found what was wrong, I set a layer that was ignoring the deafault ones, so it wasn't interacting with that deathzone collider ._.
At least I finally found what was wrong with it, thx anyways for those who read it up and tried to think about a solution! :)
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?)
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.