Spawn Player at Specific location With Unet - c#

I am trying to spawn 2 Players (host and client) at 2 different locations.
I have no idea how to do this because the player are automatically spawned by the network manager.
I have tried the following but failed horribly :(.
[Command]
void CmdSpawn()
{
var go = (GameObject)Instantiate(
gameObject,
transform.position + new Vector3(0,1,0),
Quaternion.identity);
NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
}
How Can I Spawn Player object at a specific location?

NetworkManager already supports spawn positions.
Just add GameObjects where you want players to spawn and give them the NetworkStartPosition component. NetworkManager will automatically detect the start positions and automatically use them according to your setting of "Player Spawn Method" either "Random" (one spawn position is randomly chosen for every player) or "Round Robin" (player #0 spawns at first position, player #1 at second and so forth).

Is there any problems with changing position in a script for player object? For example you could try adding following script on your player object:
void Start () {
if (isServer) // host runs
{
transform.position = new Vector3(0,0,0);
}
else if (isClient) // client runs
{
transform.position = new Vector3(10,0,10);
}
}

i was facing a similar problem, here is the solution in this thread, read til the end.
http://forum.unity3d.com/threads/which-function-to-override.391076/

Make a GameObject and attach a NetworkStartPosition to it. Then, place it somewhere. If you want more than 1 spawn point, you can CTRL+D that object. Then, go to NetworkManager and select Round Robin for spawning first to first, second to second etc. select Random for random spawn points.

Related

C#: Unity Photon doesn't add physics to the second connection

I am trying to make a multiplayer air hockey game in Unity, but encountered some problems. When the first user creates the room, the hockey puck is spawned along with the first player's mallet (the object you hit the puck with). When the second player connects to the Photon server, their mallet is spawned.
The issue is when the second player hits the puck with his mallet, the Rigidbody physics don't work on the puck. The puck slides right along the mallet, but doesn't bounce off the mallet.
I am new to Unity, so I don't know what part of the code to post. But this is the code where I spawn the items:
private void Start() {
Vector2 puckPosition = new Vector2(0,0);
Vector2 randPos = new Vector2(Random.Range(minX, maxX), Random.Range(minY, maxY));
if(CreateAndJoinRooms.intHold == 0) { // If the user created the room, the result is 0
PhotonNetwork.Instantiate(puckPrefab.name, puckPosition, Quaternion.identity);
}
PhotonNetwork.Instantiate(playerPrefab.name, randPos, Quaternion.identity);
}
Mallet Prefab:
Puck Prefab:
You probably need to add a RigidBodyView component
It sounds like the problem is with Photons object ownership. According to the images, the puck prefabs Ownership Transfer = Fixed, which means it will never change. So it's is spawned and controlled by player 1 (as the Master Client), and player 1 is responsible for moving/controlling it.
In this case, Player 1 spawns the puck, player 2 strikes it and affects its Rigidbody2D, but then the next PhotonView Transform & Rigidbody2D updates are received, which set the location & velocity according to player 1s view, ignoring player 2s impact.
A some possible solutions:
Setup a Photon RPC or Photon Event that Player 2 calls to let the Master Client know an impact has happened and to adjust the physics.
Change the OwnerShip Transfer to Take Over, and when a collision is detected have the colliding player take ownership of the puck.

Unity - multiplayer game using mirror

enter image description hereI'm using mirror for local server between multiply gamePlayers.
I have a problem sync non players objects.
I want each Player to have a button to be able to rool two dices and that the player on host will be able to see what client do and apposite. I'm still confused , don't know when to use [Command] and [ClientRpc]
btw, I create my dices like that, and called this on the method OnStartServer():
GameObject newPrize = Instantiate(prizePrefab.gameObject, spawnPosition, Quaternion.identity);
// add this game object to all clients
NetworkServer.Spawn(newPrize);
Thank you so much!

How do I make my enemies spawn randomly between 4 different Vector3 positions?

I am currently creating a game where the player is on a square platform and I want the enemies to spawn randomly from the four edges of the platform. So far I am able to make my enemies spawn randomly from one edge, but don't know how to make them spawn from all four. I imagine it would work with a Vector3 array? But I am struggling to get this right. Please help!
My spawn code so far:
void SpawnRandomEnemy()
{
if(!playerControllerScript.gameOver && !playerControllerScript.hasFreezePowerup)
{
int enemyIndex = Random.Range(0, enemyPrefabs.Length);
Vector3 spawnPos = new Vector3(Random.Range(-spawnRange, spawnRange), 0, spawnPosZ);
Instantiate(enemyPrefabs[enemyIndex], spawnPos, enemyPrefabs[enemyIndex].transform.rotation);
}
}
The easiest thing you could go for is placing 4 empty gameobjects to serve as spawners at each of the 4 sides of the square. Place them in an array consisting of gameobjects (similar to what you've done with the enemyPrefabs array).
Then you would pick 1 of them randomly just like picking the enemy index:
int spawnIndex = Random.Range(0, spawnPoints.Length);
Then you could take the position of that spawn point.
Vector3 spawnPos = spawnPoints[spawnIndex].transform.position;
Then you can edit that spawn position in many ways you would like. For example, you can set Y to be equal to 0 (or whatever fits your needs), you can add some offset to the X position of the gameobject (so that they do not spawn everytime at the same position). You can basically do that for either X, Y, Z - you just have to play around with it until it really starts acting as a randomly set spawner (just be careful with the offsets so that your enemies do not spawn out of the square).
spawnPos.X = spawnPos.X + someOffset;
You will have to generate the offset randomly, too - just like the things above.

Lan Multiplayer Scene Change

I am new to unity and currently trying to make a LAN multiplayer RPG game.
FYI, I have followed the official unity lan multiplayer guide and everything went well.
https://unity3d.com/learn/tutorials/topics/multiplayer-networking/introduction-simple-multiplayer-example
So far I got the players to load in and they are able to move. I wrote the following code below (under the void update routine) so that when the player is moving, it will randomize a number between 1 & 50 every 1 second and if the number is 25, we have randomly "encountered an enemy". When any player encounters an enemy I made it so everyone on the network goes to the "battle scene".
if (Input.GetKey("up") || Input.GetKey("down") || Input.GetKey("left") || Input.GetKey("right"))
{
if (Time.time > NextActionTime)
{
NextActionTime = Time.time + Period;
EnemyEncounter = Random.Range(1, 50);
if (EnemyEncounter == 25)
{
NetworkManager.singleton.ServerChangeScene("Scene2");
}
}
}
The code above works fine but I am not sure how, instead of loading everyone, to load only certain players into the battle scene.
For example:
Players enter a name before Hosting/Finding LAN game
Player 1 = Joe
Player 2 = Bob
Player 3 = Billy
Player 4 = Jim
On a preset label/text that loads the text in it saying "Joe,Billy". Now when ANY player finds an encounter, I want to ONLY load the players name "Joe" and "Billy" to the next scene while the others do not.
Is this possible? Any kind of help will be greatly appreciated.
Thanks All
I was trying different ideas and I got 2 different approaches:
1-As I already tell on the comments, try to nest lobbyManagers
2-"Fake" the scene split on lobbys
1.Nested Lobbys
Concept:
First Scene, MainLobby, 4 players enter, and go to the second scene
Second Scene, MainGame+SecondLobby, there are 4 players that comes from the first scene, but now 2 of them wants to go the third scene, so they use the SecondLobby to matchmake again.
Third Scene, SecondGame.
This is the best aproach I think if we are talking about performance, but it's elaborate cause:
-Actual Unity NetworkLobby uses singleton pattern, so you need to code the singleton parts again.
-LobbyManagers are builded with the DontDestroyOnLoad, so you were charging another lobby on your next scene.
-I don't really know if you can go back from third scene to second one :S
2.Fake Scenes
Well, welcome to "dirty tricks", the second concept is to:
First Scene, MainLobby, 4 players enter, and go to the second scene
Second Scene, MainGame, there are 4 players that comes from the first scene, but now 2 of them wants to go the third scene.
Third Scene, SecondGame.
But instead of "matchmake" again, what we do is to add the scene as an additive scene, but on different coordenates, and move the 2 players that wants to battle on the thirdScene. So the players will think that they are on different scene, but they aren't they are just being move. Thinks to get in mind:
-Maybe you don't really need to use the additive scene, just build on the same scene, on different coordenates. (https://docs.unity3d.com/ScriptReference/SceneManagement.LoadSceneMode.Additive.html)
-Think that they still be 4 networked players on the same scene, so maybe you want to "disable" some networkMessages, to only affect certain players on certain "scenes". (https://docs.unity3d.com/ScriptReference/Networking.NetworkClient.Send.html)
But if you achieve some other approach let me know, it really gives interesting game design stuff! :D

How to make one more try function in a Unity game

I don't know how can I do it. You lose a game, if gameobject falls down and collides with the collider. I want to add a function that asks to the player if he wants another try, if yes it will reverse some time so the gameobject that fall down will be back on the screen and the user is allowed to play once again. Is there some sort of time function/method to do this?
Hope you understand.
void OnCollisionEnter2D(Collision2D col) {
if(col.gameObject.tag=="Collider") {
Vector2 checkpoint = new Vector2(transform.position.x, transform.position.y +5)
}
}
void Reset(){
this.transform.position = checkpoint;
}
I created a child object for that collider. And I moved the child to where I wanted the player to live when I collided with the collider.
Void OnCollisionEnter2D(Collision2D col)
{
if(col.gameobject.tag=="die")
{
checkpoint = col.transform.GetChil(0).position;
}
}
void Reset(){
Player.transform.position = checkpoint;
}
Your error is because you are missing the new keyword before Vector2
When using C# you need to use the new keyword in front of all
constructors. Constructors are like functions that are used to create
new objects (or scructs). They always have the same name as the type
of object you are creating.
So you should write
Vector2 checkpoint = new Vector2(transform.position.x, transform.position.y +5)
instead of:
Vector2 checkpoint = Vector2(transform.position.x, transform.position.y +5)
Edit: Now you edited your question without the error, and since you are still trying to find a method that moves back in time what happened in Unity, I can tell you that that thing doesn't exist. However you can implement it yourself. I would recommend you something like this:
If it is a platform 2D game, like Mario Bros style, you can place in
your scene a sequence of trigger that are activated when the player
go through them.
Then you can have a boolean array with a length n equal to the
number of triggers, and then a matrix nx2 ( number of triggers x
coordinates of each trigger [x,y] ).
Initially all the elements in the array has a false value, and
every time a trigger is activated the correcponding element in the
array changes to true.
When the player dies, it checks all elements in the array, until it
reaches the last true element (this would be the last triggered
activated).
With the index form the previous step you access the matrix of
triggers and you extract both elements (x and y coordinate). Then you
use that value in:
Using your script:
Vector2 checkpoint = new Vector2(xCoordinate, yCoordinate);
There is no in built function to reverse time in unity, this would require unity to record all events up until that point.
But given your example, what you could do is create a 'checkpoint' where the scene is set up in a certain way and objects are in specific positions. Like in Mario where you fall down, it plays some music to show you failed then it puts Mario back in a certain position. Just have a function that changes the player position to the checkpoint position. The same applies to any other gameobject you need to reset.
public void Reset()
{
player.position = checkpoint.position;
}

Categories