Hi, I am creating a very simple fps multiplayer shooting game. I wanted to use prefab shooting instead of ray-cast. After setting up my shooting script i noticed that on the host side: the bullet spawns in the correct position with the correct rotation and moves in the correct direction, it also correctly damages other players, however on the client side there is an issue with the bullet spawning position. It only spawns at the height of the player e.g. if i look forward the bullet fires at the same height as the player, if i look up it wont bullet wont fire into the sky but fire from the height of the player in a straight-ward direction the same happen if i look down, it wont fire the bullet towards the ground. Here is the script i am using for player shooting, the code for shooting is in the cmdFire function:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
[RequireComponent(typeof(CharacterController))]
[AddComponentMenu("Control Script/FPS Input")]
public class PlayerController : NetworkBehaviour
{
// Varibles to control speed of player rotation
public float sensitivityHor = 5.0f;
public float sensitivityVert = 5.0f;
// Varibles to limit vertical rotation
public float minimumVert = -45.0f;
public float maximumVert = 45.0f;
private float _rotationX = 0;
// Varibles for player movement
public float speed = 7.5f;
public float gravity = -9.8f;
// Varibles for player health
[SyncVar]
public int currentHealth = maxHealth;
public const int maxHealth = 100;
public float healthBarValue;
// Reference varibles
private CharacterController _charController;
[SerializeField]
private Camera _camera;
[SyncVar]
private Color _colour;
[SerializeField] private GameObject bulletPrefab; // Exposes varible in inspector but can't be changed by other scripts
private GameObject _bullet;
// Use this for initialization
void Start ()
{
// Make sure that the player rotation is soley controlled by the mouse and not affected by the physics simulations
Rigidbody body = GetComponent<Rigidbody> ();
if (body != null)
{
body.freezeRotation = true;
}
// Hide the mouse curser at the centre of the screen
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
_charController = GetComponent<CharacterController> ();
SetColor (_colour);
}
void OnGUI()
{
int size = 12;
float posX = _camera.pixelWidth / 2 - size / 4;
float posY = _camera.pixelHeight / 2 - size / 2;
GUI.Label (new Rect (posX, posY, size, size), " * ");
posX = Screen.width / 2 - Screen.width / 4;
posY = Screen.height / 2 + (Screen.height/ 3 + Screen.height/9 );
GUI.Box (new Rect(posX, posY, healthBarValue, 20), "Health Bar" );
}
public override void OnStartClient()
{
// Applying colour changes on server side so that all player see new colour on this gameobject
if (isServer)
{
_colour = SelectColour();
}
}
// Update is called once per frame
void Update ()
{
if (!isLocalPlayer)
{
return;
}
if (Input.GetMouseButtonDown (0))
{
CmdFire ();
}
// Calling player control functions
Rotation ();
Movement ();
healthBarValue = (Screen.width/2) * ((float)currentHealth/(float)maxHealth);
}
private void Rotation()
{
// Horizontal rotation
transform.Rotate(0, Input.GetAxis ("Mouse X") * sensitivityHor, 0);
// Vertical rotation
_rotationX -= Input.GetAxis("Mouse Y") * sensitivityVert;
_rotationX = Mathf.Clamp (_rotationX, minimumVert, maximumVert); //Clamping vertical angle
_camera.transform.localEulerAngles = new Vector3 (_rotationX, 0, 0);
}
private void Movement()
{
// Caculating player movement from keyboard input
float deltaX = Input.GetAxis ("Horizontal") * speed;
float deltaZ = Input.GetAxis ("Vertical") * speed;
Vector3 movement = new Vector3 (deltaX, 0, deltaZ);
movement = Vector3.ClampMagnitude (movement, speed); // Limit diagonal movement to the same speed as movement along an axis
movement.y = gravity; // Applying gravity to player movement to make sure player stay on ground and doesn't fly
movement *= Time.deltaTime; // Time.deltaTime used so that movement is frame rate independent
movement = transform.TransformDirection (movement); // Transform the movement vector from local to global coordinates
_charController.Move (movement); // Tell the CharaterController to move by that vector
}
private Color SelectColour()
{
// Selecting random colour from list
List<Color> colours = new List<Color>{ Color.blue, Color.red, Color.yellow, Color.green};
return colours [Random.Range (0, colours.Count)];
}
private void SetColor(Color colour)
{
GetComponent<MeshRenderer> ().material.color = colour; // Changing this gameobjects colour
}
// This [Command] code is called on the client but run on the server
[Command]
void CmdFire()
{
if (_bullet == null && _camera != null)
{
// Spawning bullet
_bullet = Instantiate (bulletPrefab) as GameObject;
_bullet.transform.position = _camera.transform.TransformPoint(Vector3.forward * 1.5f); // Place bullet in front of the enemy and point in same direction
_bullet.transform.rotation = _camera.transform.rotation;
NetworkServer.Spawn (_bullet); // Spawn the bullet on the clients
}
}
public void TakeDamage(int amount)
{
// Check for "isServer", so that damage will only be applied on server
if (!isServer)
{
return;
}
currentHealth -= amount;
if (currentHealth <= 0)
{
currentHealth = 0;
}
}
}