0
\$\begingroup\$

I am quite new to the Unity community, but I can code in C#. I am testing Unity networking using a standard FPS. I am stuck while testing out multiplayer shooting, not using raycasts. The host can shoot wherever he wants, but other players can only shoot along the Y axis (left and right).

Video describing my problem

The way I handle rotations, the body only rotates left and right, and then I rotate the camera up and down; I don't want the body to rotate in that direction. I instantiate a bullet in front of my mesh and add velocity to its rigid body in the direction the camera is facing.

Why are my players only shooting in left or right direction?


Here's my code for shooting:

using UnityEngine;
using UnityEngine.Networking;

public class Shoot : NetworkBehaviour
{
    public GameObject bulletPrefab;
    public float bulletSpeed = 30f;
    public float bulletDecay = 1f;
    public float bulletY = 0;
    public Camera cam;

    void Update()
    {
        if (!isLocalPlayer)
        {
            return;
        }

        if (Input.GetButtonDown("Fire1"))
        {
            CmdFire();
        }
    }

    [Command]
    void CmdFire()
    {
        var bullet = (GameObject)Instantiate(bulletPrefab,
        new Vector3(cam.transform.position.x, cam.transform.position.y + bulletY, 
            cam.transform.position.z) + cam.transform.forward, Quaternion.identity);

        // local
        bullet.GetComponent<Rigidbody>().velocity = cam.transform.forward * bulletSpeed;
        // net
        NetworkServer.Spawn(bullet);

        Destroy(bullet, bulletDecay);
    }
}

Here's the movement script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class PlayerMove : NetworkBehaviour
{
    public Camera cam; // This object has been set via the inspector
    public GameObject bulletPrefab;
    public GameObject mesh;
    public float spawnX = 0, spawnY = 0;
    public float bulletSpeed = 30f;
    public float bulletDecay = 1f;
    public float bulletY = 0;
    public float moveSpeed = 0.1f;
    public float jumpForce = 1;
    public float rotateSpeed = 1.5f;
    public Vector3 v3Rotate;
    public float rotaceMin = -90, rotaceMax = 90;

    float distToGround;
    bool canJump = true;

    void Start()
    {
        // localplayer start
        if (isLocalPlayer)
        {
            distToGround = GetComponent<Collider>().bounds.extents.y;
            cam.transform.localEulerAngles = v3Rotate;
            return;
        }

        // turn off multiplayer cam and AuLi
        cam.enabled = false;
        cam.GetComponent<AudioListener>().enabled = false;
    }

    void Awake()
    {
        this.name = "Player";
    }

    void Update()
    {
        if (!isLocalPlayer)
        {
            return;
        }

        // get axis
        var x = Input.GetAxis("Horizontal");
        var z = Input.GetAxis("Vertical");

        // rotate left right
        var rotateLR = Input.GetAxis("Mouse X") * rotateSpeed;

        // rotate up down
        v3Rotate.x -= Input.GetAxis("Mouse Y") * rotateSpeed;

        //rotate calculate limit up down
        v3Rotate.x = Mathf.Clamp(v3Rotate.x, rotaceMin, rotaceMax);
        cam.transform.localEulerAngles = v3Rotate;

        // move
        var inputModifyFactor = (x != 0.0f && z != 0.0f)? .7071f : 1.0f;
        x *= inputModifyFactor;
        z *= inputModifyFactor;
        transform.Translate(x*moveSpeed,0,z*moveSpeed);

        // calculate rotation left right
        transform.Rotate(new Vector3(0, rotateLR, 0));

        if (Input.GetButtonDown("Fire1"))
        {
            Cursor.lockState = CursorLockMode.Locked;
        }

        if (Input.GetButtonDown("Jump"))
        {
            //if(IsGrounded())
            if (canJump)
            {
                GetComponent<Rigidbody>()
                    .AddForce(0, jumpForce, 0, ForceMode.VelocityChange);
                canJump = false;
            }
            else
            {
                // make sure he is grounded
                if (IsGrounded())
                {
                    canJump = true;
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            Cursor.lockState = CursorLockMode.Confined;
        }
    }

    public override void OnStartLocalPlayer()
    {
        // turn off local mesh of player
        this.GetComponentInChildren<MeshRenderer>().enabled = false;
    }    

    public bool IsGrounded()
    {
        return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
    }

    void OnTriggerEnter()
    {
        canJump = true;
    }
}
\$\endgroup\$
11
  • 2
    \$\begingroup\$ Please provide us with some way to see the issue happening if possible. In your case a short video or gif would be perfect, or, if you're comfortable with it, even an sscce :) \$\endgroup\$
    – dot_Sp0T
    Commented Jun 5, 2017 at 7:52
  • 1
    \$\begingroup\$ No problem I will do it now! Just a sec \$\endgroup\$ Commented Jun 5, 2017 at 15:07
  • 3
    \$\begingroup\$ I've removed your request for users to not edit your question. Editing questions to improve them is a core part of this site, and the original phrasing had some clarity issues. Occasionally we'll get an incorrect edit, but these can be rolled back and improved as they're found, and are not a cause for forbidding all edits. \$\endgroup\$
    – DMGregory
    Commented Jun 5, 2017 at 16:56
  • 2
    \$\begingroup\$ Unfortunately your use of terminology in the current phrasing is unconventional, and likely to confuse users trying to answer your question. For instance "Why are my players only shooting along the Y axis?" - shooting along the Y axis in Unity means shooting directly up or down. This is in fact the opposite of the problem demonstrated in your video, where players can't shoot upward or downward, only outward toward the horizon. Leaving it this way, you might get answers to a different problem than the one you actually need to solve, or confuse users to the point that they don't answer at all. \$\endgroup\$
    – DMGregory
    Commented Jun 5, 2017 at 17:14
  • 4
    \$\begingroup\$ Rotation around the Y axis is not the same as shooting along the Y axis. Please trust me on this - take a look at my rep count and past posts if you have any doubts that I might have expertise that could be useful to you here. Going by your use of "rollbacking" as opposed to "rolling back," I'm guessing English may not be your first language. Putting your pride aside and letting other users who are native or proficient speakers help you phrase a clear question is an important step toward getting good answers. \$\endgroup\$
    – DMGregory
    Commented Jun 5, 2017 at 18:30

1 Answer 1

1
\$\begingroup\$

So after few days I was thinking maybe I did nothing wrong so I started looking into other posibilities than "mistake in the code". It felt like the player shoot script doesnt know about that camera rotation. So I tried to add NetworkTransformChild to a Player prefab and targeted the camera of the prefab and it worked...

I am not sure if it is not too much of an overkill trying to send so many transform data just for one prefab but I guess we will see later. If anyone see any problem with this solution like network overflow or something please let me know!

I will play with it now and see if I can for example send only X axis rotation.

NetworkTransforChild solution

Thank you all for so much help and good edits on my question.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .