Recently I tried making a multiplayer game and I have some problems. After I click "Play" in the menu and I get placed in the multiplayer scene, I see myself falling through the ground, and when I check the "Scene" tab in unity my character is standing where it should be and responds to my movements (as a player, all I can see is the infinite nothing around me but I can still look around, move, etc). When another player connects, he is bugged into the ground (and I can see the shadow from the other player that is hosting and plays directly from unity) and I can't move at all.
Code :
So in the main menu scene, I have this :
NetworkController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NetworkController : MonoBehaviourPunCallbacks
{
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster () {
Debug.Log("coonnected to " + PhotonNetwork.CloudRegion + " server !");
}
void Update()
{
}
}
QuickStartLobbyController script:
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartLobbyController : MonoBehaviourPunCallbacks
{
[SerializeField] GameObject quickStartButton;
[SerializeField] float roomSize;
public override void OnConnectedToMaster () {
PhotonNetwork.AutomaticallySyncScene = true;
quickStartButton.SetActive(true);
}
public void QuickStart () {
quickStartButton.SetActive(false);
PhotonNetwork.JoinRandomRoom();
Debug.Log("Quick Start!");
}
public override void OnJoinRandomFailed (short returnCode, string message) {
Debug.Log("Failed to join a room");
CreateRoom();
}
public void CreateRoom () {
Debug.Log("creating room");
int randomRoomNumber = Random.Range(0, 10000);
RoomOptions roomOps = new RoomOptions() { IsVisible = true, IsOpen = true, MaxPlayers = (byte)
roomSize };
PhotonNetwork.CreateRoom("Room" + randomRoomNumber, roomOps);
Debug.Log(randomRoomNumber);
}
public override void OnCreateRoomFailed (short returnCode, string message) {
Debug.Log("failed to create a room");
CreateRoom();
}
}
QuickStartRoomController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomController : MonoBehaviourPunCallbacks
{
[SerializeField] int multiplayerSceneIndex;
public override void OnEnable () {
PhotonNetwork.AddCallbackTarget(this);
}
public override void OnDisable () {
PhotonNetwork.RemoveCallbackTarget(this);
}
public override void OnJoinedRoom () {
Debug.Log("joined room");
StartGame();
}
private void StartGame () {
if ( PhotonNetwork.IsMasterClient ) {
Debug.Log("Starting game");
PhotonNetwork.LoadLevel(multiplayerSceneIndex);
}
}
}
And now, the multiplayer scene where players should see each other:
The player has those :
The script inside GameSetup:
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class GameSetupController : MonoBehaviour
{
void Start()
{
CreatePlayer();
}
private void CreatePlayer () {
Debug.Log("Creating Player");
PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "player"), Vector3.zero,
Quaternion.identity);
}
}
EDIT: so here you can see exactly how it looks like. When I play from the editor's window I can move around even if I can't see it, but with the client, I cannot do basically anything in-game. I think it might be a problem with the GameSetup code or with the part that syncs all the players with the server
EDIT2: posted the playerController script :
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour, IPunObservable {
[SerializeField] Transform camera;
[SerializeField] float sens = 3.5f;
[SerializeField] float walkSpeed = 6.0f;
[SerializeField] [Range(0.0f, 0.5f)] float smooth = 0.3f;
[SerializeField] [Range(0.0f, 0.5f)] float smoothMouse = 0.3f;
[SerializeField] float gravity = -13.0f;
[SerializeField] float slopeForce = 6;
[SerializeField] float slopeForceRayLenght = 1.5f;
[SerializeField] float runSpeed = 10;
[SerializeField] float runBuildUp = 4;
[SerializeField] float jumpForce = 10;
[SerializeField] KeyCode jumpk;
[SerializeField] KeyCode runk;
[SerializeField] bool cursorLock = true;
public Rigidbody rb;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask grndMask;
public bool isGrounded;
float cameraPitch = 0.0f;
float velocityY = 0.0f;
float speed;
Vector2 currentDir = Vector2.zero;
Vector2 currentDirVelocity = Vector2.zero;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
CharacterController controller;
PhotonView photonView;
private void Awake () {
photonView = GetComponent<PhotonView>();
photonView.ObservedComponents.Add(this);
if ( !photonView.IsMine ) {
enabled = false;
}
}
void Start () {
speed = walkSpeed;
controller = GetComponent<CharacterController>();
if ( cursorLock ) {
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
// Update is called once per frame
void Update () {
UpdateMouseLook();
UpdateMovement();
Jump();
}
void UpdateMouseLook () {
Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse
X"),Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, mouseDelta,ref
currentMouseDeltaVelocity, smoothMouse);
cameraPitch -= currentMouseDelta.y * sens;
cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
camera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * sens);
}
void SetSpeed () {
if ( Input.GetKey(runk) ) {
speed = Mathf.Lerp(speed, runSpeed, Time.deltaTime * runBuildUp);
} else {
speed = Mathf.Lerp(speed, walkSpeed, Time.deltaTime * runBuildUp);
}
}
void Jump () {
isGrounded = Physics.CheckSphere(groundCheck.position,
groundDistance,grndMask);
if ( isGrounded && Input.GetKeyDown(jumpk) ) {
Debug.Log("jumping");
velocityY = Mathf.Sqrt(jumpForce * -2f * gravity);
controller.Move(Vector3.up * velocityY * Time.deltaTime);
}
}
public bool OnSlope () {
RaycastHit hit;
if ( Physics.Raycast(transform.position, Vector3.down, out hit,
controller.height / 2 * slopeForceRayLenght) ) {
if ( hit.normal != Vector3.up ) {
return true;
}
}
return false;
}
void UpdateMovement () {
Vector2 inputDir = new Vector2(Input.GetAxisRaw("Horizontal"),
Input.GetAxisRaw("Vertical"));
inputDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, inputDir, ref
currentDirVelocity, smooth);
if ( controller.isGrounded ) {
velocityY = 0.0f;
}
velocityY += gravity * Time.deltaTime;
Vector3 velocity = (transform.forward * currentDir.y + transform.right *
currentDir.x) * speed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
if ( (inputDir.x != 0 || inputDir.y != 0) && OnSlope() ) {
controller.Move(Vector3.down * controller.height / 2 * slopeForce *
Time.deltaTime);
}
SetSpeed();
}
void IPunObservable.OnPhotonSerializeView (PhotonStream stream,
PhotonMessageInfo info) {
if ( stream.IsWriting ) {
// We own this player: send the others our data
stream.SendNext(transform.position); //position of the character
stream.SendNext(transform.rotation); //rotation of the character
} else {
// Network player, receive data
Vector3 syncPosition = (Vector3) stream.ReceiveNext();
Quaternion syncRotation = (Quaternion) stream.ReceiveNext();
}
}
}
EDIT3: I found out something! When I enter the game from the master, I still need to drag myself up a bit in the editor and I will stop falling and I can play the game, but when the 2nd player connects, My camera is set to his (in all this time I can move my character and see this through the 2nd player's camera), and when he leaves all go back to normal on the master player. However, with the 2nd player, I can't move and I get an error that says:5. Btw the 2nd player is the session from the standalone (the built game) and the first player is a session from the unity editor
Related
This is a screenshot of the Input settings in the editor there is no crouch and no left shift to make the player moving faster.
This is my script name character controller. attached to the FPSController(Player).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterController : MonoBehaviour
{
public float moveSpeed = 10.0f;
public float jumpForce = 2.0f;
void Start()
{
}
// Update is called once per frame
void Update ()
{
float translatioin = Input.GetAxis("Vertical") * moveSpeed;
float straffe = Input.GetAxis("Horizontal") * moveSpeed;
translatioin *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translatioin);
if (Input.GetKeyDown("escape"))
{
Cursor.lockState = CursorLockMode.None;
}
transform.Translate(0, jumpForce * Input.GetAxis("Jump") * Time.deltaTime, 0);
}
}
I want to add crouch and left shift for faster moving.
This script is only for controlling the mouse looking around and lock state of the mouse cursor attached to the main camera(Player child).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class camMouseLook : MonoBehaviour
{
Vector2 mouseLook;
Vector2 smoothV;
public float sensitivity = 5.0f;
public float smoothing = 2.0f;
public bool mouseDown = false;
public bool cursorLock = false;
public HandleMouseCursor handleMouseCursor;
GameObject character;
// Use this for initialization
void Start ()
{
if(cursorLock == false)
{
Cursor.lockState = CursorLockMode.None;
handleMouseCursor.setMouse();
}
else
{
Cursor.lockState = CursorLockMode.Locked;
}
character = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButton(0) && mouseDown == true)
{
MouseLook();
}
else
{
if (mouseDown == false)
{
MouseLook();
}
}
}
private void MouseLook()
{
if (cursorLock == false)
{
Cursor.lockState = CursorLockMode.None;
handleMouseCursor.setMouse();
}
else
{
Cursor.lockState = CursorLockMode.Locked;
}
var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);
transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
}
}
You can change speed of your movement in your CharacterController script.
Just create a variable for crouch speed and multiplay it to your translation vector.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterController : MonoBehaviour
{
public float moveSpeed = 10.0f;
public float crouchSpeed = 20;
public float jumpForce = 2.0f;
void Start()
{
}
// Update is called once per frame
void Update ()
{
float finalMoveSpeed = moveSpeed;
// you can add more IF statements for more actions like walking, running, jumping,...
if(Input.GetKey(KeyCode.KeyCode.LeftShift))
finalMoveSpeed = crouchSpeed ;
float translatioin = Input.GetAxis("Vertical") * finalMoveSpeed ;
float straffe = Input.GetAxis("Horizontal") * finalMoveSpeed ;
translatioin *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translatioin);
if (Input.GetKeyDown("escape"))
{
Cursor.lockState = CursorLockMode.None;
}
transform.Translate(0, jumpForce * Input.GetAxis("Jump") * Time.deltaTime, 0);
}
}
Please check the code. Once the player moves the fixed distance once, he doesn't move again even when the space input is given.
How Do I make it such that I can keep moving the player after the player has been moved once?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementPC : MonoBehaviour
{
[Header ("Move Settings")]
private Vector3 StartingPosition, EndingPosition;
public float moveDistance = 30f;
public float LerpTime = 1f;
private float CurrentLerpTime = 0;
public bool movePressed = false;
private void Start()
{
StartingPosition = transform.position;
EndingPosition = transform.position + Vector3.forward * moveDistance;
}
void Update()
{
if (Input.GetKeyDown("space"))
{
movePressed = true;
Debug.Log("dash pressed");
}
if (movePressed == true)
{
CurrentLerpTime += Time.unscaledDeltaTime;
if (CurrentLerpTime >= LerpTime)
{
CurrentLerpTime = LerpTime;
}
float LerpPercentage = CurrentLerpTime / LerpTime;
transform.position = Vector3.Lerp(StartingPosition, EndingPosition, LerpPercentage);
}
}
Any Help would be appreciated. Thanks for your time.
The issue is you are not resetting the variables that control the start/end positions of the movement. The Start() method is called when the object is added to the level, or Play is pressed and that is currently the only method that resets those values. Therefore if you want those values reset you need to determine when the movement has finished, something like:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementPC : MonoBehaviour
{
[Header ("Move Settings")]
private Vector3 StartingPosition, EndingPosition;
public float moveDistance = 30f;
public float LerpTime = 1f;
private float CurrentLerpTime = 0;
private void Start()
{
ResetPositions();
}
void Update()
{
if (Input.GetKeyDown("space"))
{
CurrentLerpTime += Time.unscaledDeltaTime;
if (CurrentLerpTime >= LerpTime)
{
ResetPositions();
return;
}
float LerpPercentage = CurrentLerpTime / LerpTime;
transform.position = Vector3.Lerp(StartingPosition, EndingPosition, LerpPercentage);
}
}
void ResetPositions()
{
StartingPosition = transform.position;
EndingPosition = transform.position + Vector3.forward * moveDistance;
CurrentLerpTime = 0;
}
I started making a 2D game in Unity and I have a problem with my player. I add 2 buttons for left and right and jump just tapping the display . When I start the game just the buttons left and right works and the jump don't . I added from another script something for jump and now when I start the game the player goes automatically at right and don't respect the buttons action. (but jumping works) this is the 2 codes that I joined them :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public float moveSpeed = 300;
public GameObject character;
private Rigidbody2D characterBody;
private float ScreenWidth;
void Start()
{
ScreenWidth = Screen.width;
characterBody = character.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
int i = 0;
while (i < Input.touchCount)
{
if (Input.GetTouch(i).position.x > ScreenWidth / 2)
{
RunCharacter(1.0f);
}
if (Input.GetTouch(i).position.x < ScreenWidth / 2)
{
RunCharacter(-1.0f);
}
++i;
}
}
void FixedUpdate()
{
#if UNITY_EDITOR
RunCharacter(Input.GetAxis("Horizontal"));
}
private void RunCharacter(float horizontalInput)
{
characterBody.AddForce(new Vector2(horizontalInput * moveSpeed * Time.deltaTime, 0));
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move2d : MonoBehaviour
{
public float playerSpeed; //allows us to be able to change speed in Unity
public Vector2 jumpHeight;
public bool isDead = false;
private Rigidbody2D rb2d;
private Score gm;
// Use this for initialization
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
gm = GameObject.FindGameObjectWithTag("gameMaster").GetComponent<Score>();
}
// Update is called once per frame
void Update()
{
if (isDead) { return; }
transform.Translate(playerSpeed * Time.deltaTime, 0f, 0f); //makes player run
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space)) //makes player jump
{
GetComponent<Rigidbody2D>().AddForce(jumpHeight, ForceMode2D.Impulse);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("ground")) // this will return true if the collision gameobject has ground tag on it.
{
isDead = true;
rb2d.velocity = Vector2.zero;
GameController.Instance.Die();
}
}
void OnTriggerEnter2D(Collider2D col)
{
if( col.CompareTag("coin"))
{
Destroy(col.gameObject);
gm.score += 1;
}
}
}
If you know a better script please help
Try adding #endif for the #if UNITY_EDITOR
This is my code does anyone know or can anyone spot why my projectile remains stationary once it's spawned in? the projectile is the prefab shell thanks for your help in advance.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab,
fireTransform.position,
fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.velocity = 15.0f * fireTransform.forward;
Debug.Log("velocity");
}
}
}
It is also generally discouraged to set the velocity of a rigidbody, but you can use the Rigidbody.AddForce() method to add force to a rigidbody. When you just want add force at the start, you can set the force mode in the function to impulse, like this rb.AddForce(Vector3.forward, ForceMode2D.Impulse);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
public float bulletSpeed;
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab, fireTransform.position, fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.AddForce(15f * transform.forward, ForceMode.Impulse);
Debug.Log("velocity");
}
}
}
Hope this helps!
I am trying to make my enemy object turn and start moving towards my player object when the player comes within a certain vicinity.
For the turning I have been testing the transform.LookAt() function although it isn't returning the desired results as when the player is too close to the enemy object the enemy starts to tilt backwards and I only want my enemy to be able to rotate along the y axis, thanks in advance.
using UnityEngine;
using System.Collections;
public class EnemyController : MonoBehaviour {
public Transform visionPoint;
private PlayerController player;
public Transform Player;
public float visionAngle = 30f;
public float visionDistance = 10f;
public float moveSpeed = 2f;
public float chaseDistance = 3f;
private Vector3? lastKnownPlayerPosition;
// Use this for initialization
void Start () {
player = GameObject.FindObjectOfType<PlayerController> ();
}
// Update is called once per frame
void Update () {
// Not giving the desired results
transform.LookAt(Player);
}
void FixedUpdate () {
}
void Look () {
Vector3 deltaToPlayer = player.transform.position - visionPoint.position;
Vector3 directionToPlayer = deltaToPlayer.normalized;
float dot = Vector3.Dot (transform.forward, directionToPlayer);
if (dot < 0) {
return;
}
float distanceToPlayer = directionToPlayer.magnitude;
if (distanceToPlayer > visionDistance)
{
return;
}
float angle = Vector3.Angle (transform.forward, directionToPlayer);
if(angle > visionAngle)
{
return;
}
RaycastHit hit;
if(Physics.Raycast(transform.position, directionToPlayer, out hit, visionDistance))
{
if (hit.collider.gameObject == player.gameObject)
{
lastKnownPlayerPosition = player.transform.position;
}
}
}
}
change the look at target:
void Update () {
Vector3 lookAt = Player.position;
lookAt.y = transform.position.y;
transform.LookAt(lookAt);
}
this way the look at target will be on the same height as your object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnemyMovement : MonoBehaviour
{
public Transform Player;
public float MoveSpeed = 4;
int MaxDist = 10;
int MinDist = 5;
void Update()
{
transform.LookAt(Player);
if (Vector3.Distance(transform.position, Player.position) >= MinDist)
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
if (Vector3.Distance(transform.position, Player.position) <= MaxDist)
{
// Put what do you want to happen here
}
}
}
}