Movement Script Affecting Other Player's Movement
Hey all,
...
In a game where four players should move independently around a circle, if right movement for one character and left movement for another character happen at the same time, they move in the same direction, rather than around the circle in the proper way.
...
We have WASD and the arrow keys for movement in this scenario, and they seem to be mapped properly through input manager. However, the problem still persists.
...
I feel one of our variables is affecting the movement in a way we are not understanding.
...
Any help would be greatly appreciated. Thanks!
...
NOTE: The script for this player's movement is identical to the other player's scripts, where the only difference is the action key. (WASD, arrow keys, J and L for right/left, and [4] and [6] for right/left)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Player controller and behavior
/// </summary>
public class Player2Script : MonoBehaviour
{
/// <summary>
/// 1 - The speed of the ship
/// </summary>
// 2 - Store the movement and the component
private Vector2 movement2;
private Rigidbody2D rigidbodyComponent;
float timeCounter = 0;
void Update()
{
// 3 - Retrieve axis information
//timeCounter += Time.deltaTime;
if (Input.GetKey("j"))
{
RotateLeft();
}
if (Input.GetKey("l"))
{
RotateRight();
}
}
void FixedUpdate()
{
// 5 - Get the component and store the reference
if (rigidbodyComponent == null) rigidbodyComponent = GetComponent<Rigidbody2D>();
// 6 - Move the game object
rigidbodyComponent.velocity = movement2;
}
void RotateLeft()
{
timeCounter += Input.GetAxis("Horizontal") * Time.deltaTime * 4; // multiply all this with some speed variable (* speed);
float x = Mathf.Cos(timeCounter) * 4;
float y = Mathf.Sin(timeCounter) * 4;
float z = 0;
transform.position = new Vector3(x, y, z);
transform.Rotate(Vector3.forward * -4);
}
void RotateRight()
{
timeCounter += Input.GetAxis("Horizontal") * Time.deltaTime * 4; // multiply all this with some speed variable (* speed);
float x = Mathf.Cos(timeCounter) * 4;
float y = Mathf.Sin(timeCounter) * 4;
float z = 0;
transform.position = new Vector3(x, y, z);
transform.Rotate(Vector3.forward * 4);
}
}
Answer by streeetwalker · Mar 26, 2020 at 10:10 AM
@shimbobular, You are doing two kinds of 'rotation' so perhaps the issue seems confusing. The player object 'revolves' around the circle's center, and also 'rotates' about the center of it's own axis.
The rotate code is correctly aligned with the apparent intent: rotate right 4, rotate left -4.
but the problem is the revolve code: You have the exact same code for both left and right revolve motion based on horizontal input. Therefore all the players will revolve in exactly the same direction around the circle no matter which way they rotate.
Yep, the "rotate" code is basically redundant, since we implemented a workaround which perpetually points the player object towards the center of the play area. The "revolve" is what we're having an issue with.
How would we go about changing the code so players can revolve around the circle independent of each other? $$anonymous$$ovement works perfectly fine during one player's input, left goes left and right goes right. However, when a different player tries moving, they will match the other player's direction. Additionally, if two players begin moving opposite directions at the exact same time, they'll both get caught in a strange action where they slowly drift towards eachother. Any pointers would be appreciated.
@aagro350 , this line of code is the problem:
Input.GetAxis("Horizontal")
It looks like the code uses the same controller input for all players. Each player has their own controller?
You've only shown player 2's example, so If you are already handling multiple controllers uniquely in the code then it's not working. Either way, you'll have to google around for how to handle multiple controllers.
BTW, Rather than have a unique script for each player, you can create a public variable the identifies the player (eg. int playerID ) and then use that to index each controller, and for the keyboard input I think you could offset the ID and convert it into the keycodes for each player - there should be a way to do that. That way every player object could have exactly the same script.
I can easily see how they revolve in the same direction, but I cannot see how they would revolve in opposite directions. Do you have any forces anywhere else the act on the player objects?
@aagro350, Oh wait, I just spotted this: you should not both apply forces to a rigidbody and also set transforms directly (you're setting the rigidbody.velocity in FixedUpdate). You'll get weird behavior - which may have something to do with the strange revolving in opposite directions.
You need to choose one method of controlling motion and rotation over the other.
Because you want the players to revolve around the center of a circle, it's easy to calculate the transform position. If you want to stick with that method, then set the player to Is Kinematic and set the position directly in FixedUpdate.
If you want to use the Rigidbody, then make sure Is Kinematic is off (it must be if you are apply a velocity in FixedUpdate). Then for the rotation you'll need to apply either a torque force or angularVelocity, and for the revolve behavior you'll have to calculate the tangent of the circle and apply a force in that direction. (to do that, I think you'd have to calculate the current position on the circle anyway - just not set the transform.position directly.)
Note, do not change the velocity or angularVelocity of a Rigidbody on a regular, frame-by-frame basis. You should only set those for 1 shot, immediate changes, like if you bounce off something, or you want apply an instantaneous change. If you apply them continuously you'll get unpredictable Rigidbody behavior.
Your answer
Follow this Question
Related Questions
UNET Multiplayer Vehicle Movement sync issues 0 Answers
Sync movements Photon 0 Answers
Unity 2D networking movement syncing help 0 Answers
Multy Player both players are moving 0 Answers
Problems syncing players in multiplayer 0 Answers