Search Unity

Using main.camera.ScreenToWorldPoint on client and host

Discussion in 'Multiplayer' started by willkillyaquick, Nov 30, 2017.

  1. willkillyaquick

    willkillyaquick

    Joined:
    Nov 17, 2017
    Posts:
    5
    Good Morning.

    I am having trouble trying to figure out how to send the actual client mouse click point that is clicked on in the world to fire a bullet in that direction. With the code below, when I click the client, the host spawns the bullet but the bullet heads directly left and the client bullet goes no where. If I click on the host screen, the bullet fires in the direction but just spawns and goes no where on the client.

    From all the google searching I have done, I am understanding that the if I click the client screen, the server main.camera is captured and not the clients main.camera. I've seen post on this but no solution was found. Here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine.Networking;
    4. using UnityEngine;
    5. using System;
    6.  
    7. public class PlayerMoveTest : NetworkBehaviour {
    8.  
    9.  
    10.     [Header("Items that Spawn")]
    11.     public GameObject bulletPrefab;
    12.     public Transform bulletSpawnPoint;
    13.     Vector3 aimPoint;
    14.     private float xDir;
    15.     private float yDir;
    16.  
    17.     void Update ()
    18.     {
    19.         if (!isLocalPlayer)
    20.         {
    21.             return;
    22.         }
    23.         xDir = Input.GetAxis("Horizontal") * Time.deltaTime * 5;
    24.         yDir = Input.GetAxis("Vertical") * Time.deltaTime * 5;
    25.         transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, 0, 0);
    26.         transform.Translate(xDir, yDir, 0);
    27.  
    28.         if (Input.GetKey(KeyCode.Mouse0))
    29.         {
    30.             aimPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    31.             aimPoint.z = 0;
    32.             CmdFire();
    33.         }
    34.     }
    35.  
    36.     [Command]
    37.     private void CmdFire()
    38.     {
    39.         GameObject bullet = (GameObject)Instantiate(bulletPrefab, bulletSpawnPoint.position, bulletSpawnPoint.rotation);
    40.      
    41.         bullet.transform.up = aimPoint - bullet.transform.position;
    42.         bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * 700.0f);
    43.      
    44.         //RpcClientFire();
    45.         NetworkServer.Spawn(bullet);
    46.         Destroy(bullet, 1.0f);
    47.     }
    48.  
    49.     [ClientRpc]
    50.    private void RpcClientFire()
    51.     {
    52.         //
    53.         aimPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    54.         aimPoint.z = 0;
    55.         GameObject bullet = (GameObject)Instantiate(bulletPrefab, bulletSpawnPoint.position, bulletSpawnPoint.rotation);
    56.         bullet.transform.up = aimPoint - bullet.transform.position;
    57.         bullet.GetComponent<Rigidbody2D>().AddForce(bullet.transform.up * 700.0f);
    58.         Destroy(bullet, 1.0f);
    59.     }
    60.  
    61.     public override void OnStartLocalPlayer()
    62.     {
    63.         GetComponent<SpriteRenderer>().color = Color.cyan;
    64.     }
    65.  
    66.     private void OnGUI()
    67.     {
    68.         GUI.TextField(new Rect(10, 10, 200, 20), aimPoint.ToString(), 25);
    69.     }
    70. }
    71.  
    Purpose of the code: Client or host clicks there screen, bullet fires in the direction of the clients click on the host and updates all the clients.
     
    Last edited: Nov 30, 2017
  2. willkillyaquick

    willkillyaquick

    Joined:
    Nov 17, 2017
    Posts:
    5
    So I figured out what was wrong. The first thing I did was pass aimPoint to CmdFire instead of using it as a global variable.
    Code (CSharp):
    1. private void CmdFire(Vector3 aimPointDir)
    Which means I needed to change

    Code (CSharp):
    1. bullet.transform.up = aimPointDir - bullet.transform.position;
    This fixed the issue where the Host would not fire at where my mouse was on the Clients, but the clients was still just spawning the bullet and it didn't more. Well, since I use a Tutorial to help me make this code, I realized it had made me turn the Net Send Rate to Zero (I am guessing it was relying on the client to do the physics?). Anyway, I bumped that up and now the bullets fire in the correct directions on the client and the host. :D
     
  3. Tuomas1337

    Tuomas1337

    Joined:
    Sep 13, 2019
    Posts:
    1
    Hey!

    Can you post the updated script?
     
  4. jasperli430

    jasperli430

    Joined:
    May 19, 2019
    Posts:
    1
    Hey, I guess I am facing the same issue now. Would you like to explain more about your solution? :D
     
  5. willkillyaquick

    willkillyaquick

    Joined:
    Nov 17, 2017
    Posts:
    5
    Wow, this was over 3 years ago. Basically the Function needs a Vector3 Input

    Code (CSharp):
    1. private void CmdFire()
    in code above changed to
    Code (CSharp):
    1. private void CmdFire(Vector3 aimPointDir)
    Then
    Code (CSharp):
    1. bullet.transform.up = aimPoint - bullet.transform.position;
    Within that function needs to be change to
    Code (CSharp):
    1. bullet.transform.up = aimPointDir - bullet.transform.position;
    Next time the Client inputs the Var in the Function, it will be sent over the network so the Host actually gets the correct value and not the local value on the host.