I am rather new to UNET and hoping to learn. Not the most experienced with C# either.
Having troubles visualizing and understanding who owns what and who must run what. So here is my workings in pseudo code.
Server starts, spawns a vehicle which was pre placed in the scene.
Player Object (Actual player being capsule for now) spawns for the client when he joins.
Player walks up to vehicle and presses E (Raycast) to enter the “Vehicle” and runs the following function in a script “PlayerInteractions” which is attached to the player.
EnterVehicle();
{
Disable player collider
Disable player controlls if is local player
Disable player gravity
Enable player iskinematic
Move player to centre of vehicle (or seat later)
Parent player to vehicle
Enable vehicle controls for local player
}
Should I be running this on the server with Command? Do I need to use RpcClient? Will the changes to the player components sync to the other clients? I have tried various combinations and having mixed up results.
Am I approaching this completely wrong? This all works well in a single player environment.
Some pseudo code on the correct procedure / route would be immensely appreciated.
Hi Guys, just an update. It looks like I got most of it working somewhat. I have pasted the code below if anyone with more experience can tell me if I am doing this horribly wrong or am I on the right track? I can probably shorten this a bit without repeating code but this is rough coding for testing and learning.
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class PlayerInteractions : NetworkBehaviour
{
[SerializeField]
private Camera cam; //Camera for interactive Raycast
private Transform _interactiveRayHitTarget; //Transform of object that was hit with the interactive Raycast check.
public GameObject vehicle01; //List of vehicles that can spawn, maybe move this to another script later.
public string playerState = "OutsideVehicle";
void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
FireInteractiveRay();
}
}
void FireInteractiveRay()
{
Debug.DrawRay(cam.transform.position, cam.transform.forward * 3, Color.green, 0.5f);
RaycastHit _hit;
if (Physics.Raycast(cam.transform.position, cam.transform.forward, out _hit, 3))
{
//Debug.Log(_hit.collider.tag);
//if (_hit.collider.name == "CarSpawnPanel")
//{
//_interactiveRayHitTarget = _hit.transform.FindChild("SpawnTarget");
//CmdSpawnVehicle();
//}
if (_hit.collider.tag == "Vehicle" && playerState == "OutsideVehicle")
{
_interactiveRayHitTarget = _hit.transform;//Testing
CmdEnterVehicle(_hit.collider.gameObject);//Testing
}
}
else if (playerState == "InsideVehicle")
{
CmdExitVehicle(_interactiveRayHitTarget.gameObject);//Last ray hit the vehicle so it must still be correct.
}
}
[Command]
void CmdEnterVehicle(GameObject _targetVehicle)
{
_targetVehicle.GetComponent<NetworkIdentity>().AssignClientAuthority(connectionToClient); //Give authority over the vehicle so we can move it.
RpcEnterVehicle(_targetVehicle);
}
[ClientRpc]
void RpcEnterVehicle(GameObject _target)//Disable player controls, colliders etc.
{
GetComponent<CapsuleCollider>().enabled = false;
GetComponent<Rigidbody>().useGravity = false;
GetComponent<Rigidbody>().isKinematic = true;
if (isLocalPlayer) //Toggle state of player controlls and motor on local pc only.
{
GetComponent<PlayerController>().enabled = false;
GetComponent<PlayerMotor>().enabled = false;
_target.GetComponent<Vehicle_Controls>().enabled = true;
playerState = "InsideVehicle";//Set state
}
transform.parent = _target.transform;//Child player to vehicle
transform.position = _target.transform.position;//Move player inside vehicle
transform.rotation = _target.transform.rotation;//Rotate player to face forward in vehicle
GetComponent<NetworkTransform>().enabled = false;
GetComponent<NetworkTransformChild>().enabled = false;
}
[Command]
void CmdExitVehicle(GameObject _targetVehicle)
{
_targetVehicle.GetComponent<NetworkIdentity>().RemoveClientAuthority(connectionToClient); //Remove authority over the vehicle
RpcExitVehicle(_targetVehicle);
}
[ClientRpc]
void RpcExitVehicle(GameObject _target)//Enable player controls, colliders etc.
{
transform.position = transform.parent.TransformPoint(Vector3.left * 2);//Move player outside of vehicle
transform.parent = null;//Unchild player from vehicle
GetComponent<CapsuleCollider>().enabled = true;
GetComponent<Rigidbody>().useGravity = true;
GetComponent<Rigidbody>().isKinematic = false;
if (isLocalPlayer) //Toggle state of player controlls and motor on local pc only.
{
GetComponent<PlayerController>().enabled = true;
GetComponent<PlayerMotor>().enabled = true;
_target.GetComponent<Vehicle_Controls>().enabled = false;
playerState = "OutsideVehicle";//Set state
}
GetComponent<NetworkTransform>().enabled = true;
GetComponent<NetworkTransformChild>().enabled = true;
}
[Command]
void CmdSpawnVehicle()
{
GameObject vehicle = (GameObject)Instantiate(vehicle01, _interactiveRayHitTarget.position, _interactiveRayHitTarget.rotation);
NetworkServer.Spawn(vehicle);
}
}
Hi @ . Unfortunately I have not gotten to that stage to notice any lag or complications with RemoveClientAuthority yet. I might take a closer look and keep that in mind for you.