Jump to content
Sign in to follow this  
Guest Victor Camacho

Problema para sincronizar armas

Recommended Posts

Guest Victor Camacho

Hola tengo un problema que no puedo solucionar, mi proyecto es un shooter TPS/FPS multijugador, puedo conectar a los jugadores y sincronizar movimiento y animaciones pero cuando creo las armas vienen los problemas. cuando inicio una partida todo bien crea a mi jugador y las armas en red. todo perfecto. al conectar un cliente a la partida en el servidor también parece todo bien las armas se generan y se equipan al cliente. pero del lado del cliente los jugadores que ya estaban allí aparecen pero las armas se quedan flotando y no se asignan al jugador.

mi primer script se encarga de instanciar las armas y asignarlas cuando se crea el jugador.

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

public class NetPlayerSetup : NetworkBehaviour {
    [SyncVar]
    public string playerNetID;

	[SerializeField]
    cameraViewMove playerCam;
	public GameObject primaryWeapon;
	public GameObject secundaryWeapon;

	//weaponManager wManager;
	ShooterController shooterController { get { return GetComponent<ShooterController>(); } }
	playerController pController { get { return GetComponent<playerController>(); } }
	ikController ikControl { get { return GetComponent<ikController>(); } }
	//aimingController aimControl;
	Animator anim;

	// Use this for initialization
	void Start () {
        if (isServer)
        {
            playerNetID = "Player" + Random.Range(1, 1000);
        }


		if (isLocalPlayer) {
			pController.enabled = true;
			ikControl.enabled = true;
			//aimControl.enabled = true;
			playerCam = GameObject.FindGameObjectWithTag ("PlayerCam").GetComponent<cameraViewMove> ();
			playerCam.setupPlayer(gameObject);
			shooterController.enabled = true;

			CmdInstantiateWeapons();


		} else {
			NetworkIkSync netIk = GetComponent<NetworkIkSync>();
			netIk.enabled = true;
		}

		Debug.Log("Net Player Inicializado");

		//finish
	}

	[Command]
	public void CmdInstantiateWeapons(){
		//GameObject primary = GameObject.Instantiate (primaryWeapon) as GameObject;
		//GameObject secundary = GameObject.Instantiate (secundaryWeapon) as GameObject;
		GameObject primary = Instantiate(primaryWeapon, primaryWeapon.transform.position, primaryWeapon.transform.rotation) as GameObject;
		GameObject secundary = Instantiate(secundaryWeapon, secundaryWeapon.transform.position, secundaryWeapon.transform.rotation) as GameObject;
		NetworkServer.Spawn(primary);
		NetworkServer.Spawn(secundary);
		RpcEquipWeapons(primary, secundary);
	}

	[ClientRpc]
	public void RpcEquipWeapons(GameObject prymary, GameObject secundary){
		shooterController.primaryWeapon = prymary;
		shooterController.secundaryWeapon = secundary;
        shooterController.unEquip();
        shooterController.equip(weaponGlobals.weaponSlot.primary);
	}

	public void playerDead(){
		pController.enabled = false;
		GetComponent<CharacterController>().enabled=false;
		shooterController.enabled=false;
		ikControl.enabled = false;
		//aimControl.enabled = false;
		anim.enabled = false;
	}

    void Update()
    {
            if (Input.GetKeyDown(KeyCode.I))
            {
                if (isLocalPlayer)
                {
                    interfaz.playerInfoText = playerNetID +" - "+ shooterController.primaryWeapon.GetComponent<arma>().armaNetID;
                    interfaz.instance.updatePlayerInfo();
                }
                CmdMessageLog(playerNetID + "- prymary: " + shooterController.primaryWeapon.GetComponent<arma>().armaNetID);
            }
    }
		
    [Command]
    public void CmdMessageLog(string s)
    {
        Debug.Log(s);
    }

}

y el escript donde se equipan las armas es el siguiente donde los parametros de primaryWeapon, secundaryWeapon y activeWeapon se quedan en null (solo el los jugadores que ya existian antes de entrar a la partida)

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

public class ShooterController : NetworkBehaviour {

	public GameObject bullet;
	public Transform target;
	public float smoothRotPlayer = 5f;
	public LayerMask aimMask;
	public Transform pointing; // apuntador
	public Transform pointingPivot; //eje o anclaje del apuntador/pointing (Shoulder/hombro)
	public Animator pointingAnimator;
	public GameObject primaryWeapon;
	public GameObject secundaryWeapon;
	public Transform primarySlot;
	public Transform secundarySlot;
	public weaponGlobals.weaponSlot currentSlot;
	public GameObject activeWeapon;

	public Transform leftHand;
	public Transform rightHand;

	[HideInInspector]
	public GameObject closerItem;
	public cameraViewMove playerCamera;
	public Animator playerAnimator { get { return GetComponent<Animator>(); } }

	arma miArma;

	Quaternion rotacion;//apuntar a target
	Quaternion desvio;//
	Quaternion rotPlayer;

	public  bool useDinamicIk;
	float ikValue = 1f;//valor dinamico para el ik

	CharacterController charControl;
    public bool startReady = false;
    public bool startClientReady = false;

	// Use this for initialization
	public override void OnStartClient() {
        playerCamera = GameObject.FindWithTag("PlayerCam").GetComponent<cameraViewMove>();

        //pooling
        PoolManager.instance.createPool(bullet, 10);

        //set
        charControl = GetComponent<CharacterController>();
        pointingAnimator = pointing.gameObject.GetComponent<Animator>();
        target = GameObject.FindGameObjectWithTag("LookPos").GetComponent<Transform>();// look pos mismo de las ik

        Debug.Log("ShooterController - starter");
        startClientReady = true;
    }

    /*
    public override void OnStartClient()
    {
        Debug.Log("ShooterController - starter client");
    }
    //*/

    // Update is called once per frame
    [ClientCallback]
	void Update () {

		//Debug.Log(rotacion.eulerAngles);
		Debug.DrawRay(pointing.position, pointing.forward * 10, Color.cyan);
		Debug.DrawRay(pointing.position, (target.position - pointing.position).normalized, Color.blue);

        if (!isLocalPlayer)
            return;

        if (miArma = activeWeapon.GetComponent<arma>()){
			interfaz.balasText = miArma.currentAmmo + " / " + miArma.ammo; 
		}
		TakeCloserItemEvent();
		equipPrimaryEvent();
		equipSecundaryEvent();
		isAimingEvent();
		aimingEvent();
		isShootingEvent();
		isReloadEvent();
		useIkEvent();
	
	}

	#region events
	public void TakeCloserItemEvent(){
		if(closerItem){
			Vector3 currentHeading = closerItem.transform.position - transform.position;
			float currentDistance = currentHeading.magnitude;
			if(currentDistance < 0.5f){
				arma wp = closerItem.GetComponent<arma>();
				interfaz.itemName = "[E] to use "+wp.nombre.ToString();

				if(Input.GetKeyDown("e")){
					if(wp.slotUsed == weaponGlobals.weaponSlot.primary){

						primaryWeapon.GetComponent<arma>().isItem();
						primaryWeapon.transform.parent = null;
						primaryWeapon = closerItem;

					}else{

						secundaryWeapon.GetComponent<arma>().isItem();
						secundaryWeapon.transform.parent = null;
						secundaryWeapon = closerItem;

					}
					//unEquip();
					activeWeapon = closerItem;
					//equipActive();
					closerItem = null;
					interfaz.itemName = "";
				}

			}else{
				interfaz.itemName = "";
			}
		}
	}

	public void equipPrimaryEvent(){
		if(Input.GetKeyDown("1")){
			unEquip();
            equip(weaponGlobals.weaponSlot.primary);
            CmdEquipOnNetwork(weaponGlobals.weaponSlot.primary);
        }
    }

	public void equipSecundaryEvent(){
		if(Input.GetKeyDown("2")){
			unEquip();
			equip(weaponGlobals.weaponSlot.secundary);
            CmdEquipOnNetwork(weaponGlobals.weaponSlot.secundary);
            
		}
	}

	public void isAimingEvent(){
		//direccion y ajusde de apuntado con movimiento suavisado
		if(Input.GetAxis("Fire2")>0.5f){
			playerAnimator.SetBool("focus", true);
			//Cursor.lockState = CursorLockMode.Locked;
		}else{
			playerAnimator.SetBool("focus", false);
			//Cursor.lockState = CursorLockMode.None;
		}
	}

	public void aimingEvent(){

		pointing.rotation = Quaternion.Slerp(pointing.transform.rotation, rotacion, miArma.movement * Time.deltaTime);
		//pointing.transform.position = Vector3.Lerp(pointing.transform.position, pointingPivot.position, miArma.movement);
		pointing.position = pointingPivot.position;
		Camera.main.transform.localRotation = Quaternion.Lerp(Camera.main.transform.localRotation, Quaternion.Euler(0,0,0), miArma.movement *Time.deltaTime);


		// rotacion de arma y objeto al apuntar o en si isFps de cameraViewMove es true
		if((playerAnimator.GetBool("focus") || playerCamera.isFps) && !playerAnimator.GetBool("running")){
			Debug.Log("is aiming");
			Ray ray = new Ray(pointing.transform.position, target.position - pointing.transform.position);
			RaycastHit hit;

			if(Physics.Raycast(ray, out hit, 0.5f, aimMask)){
				rotacion = transform.localRotation * Quaternion.Euler(45,-30,0);
			}else{
				rotacion = Quaternion.LookRotation(target.position - pointing.transform.position);
			}

			Quaternion rot = Quaternion.LookRotation(target.position - pointing.transform.position);
			rotPlayer = Quaternion.Euler(0,rot.eulerAngles.y,0);
			transform.rotation = Quaternion.Slerp(transform.rotation, rotPlayer, smoothRotPlayer * Time.deltaTime);
		}else{

			rotacion = transform.localRotation * Quaternion.Euler(45,-45,0);

		}
			
	}

	public void isShootingEvent(){
		if(miArma.fireType == weaponGlobals.fireType.full){
			if(Input.GetButton("Fire1")){//boton de disparo es presionado
				shootingHip();
			}
		}else{
			if(Input.GetButtonDown("Fire1")){
				shootingHip();
			}
		}
	}

	public void isReloadEvent(){
		if(Input.GetButtonDown("Reload")){
			miArma.reload();
		}

		if(Input.GetKeyDown(KeyCode.F)){
			miArma.ammo = miArma.maxAmmo;
		}
	}

	public void useIkEvent(){
		//usar iks cuando apunta
		if(playerAnimator.GetBool("focus")){

			//*
			ikValue += 3f * Time.deltaTime;
			if(ikValue>1f){
				ikValue = 1f;
			}
			//*/
		}else if(!playerAnimator.GetBool("focus")){
			//*
			ikValue -= 2f * Time.deltaTime;
			if(ikValue < 0f){
				ikValue = 0f;
			}//*/
		}
		if(useDinamicIk){
			GetComponent<ikController>().ikWeight = ikValue;
		}
	}
	#endregion

	#region equip
	public void equip(weaponGlobals.weaponSlot WeaponSlot){
        currentSlot = WeaponSlot;
        switch (currentSlot)
        {
            case weaponGlobals.weaponSlot.primary:
                activeWeapon = primaryWeapon;
                break;
            case weaponGlobals.weaponSlot.secundary:
                activeWeapon = secundaryWeapon;
                break;
        }

        miArma = activeWeapon.GetComponent<arma>();
		activeWeapon.transform.parent = rightHand;//emparentamos a la mano
		miArma.equip();//equipamos arma (ajustamos posicion y rotacion) => !!importante despues de emparentar con mano
		pointingAnimator.SetInteger("weaponIndex", miArma.animIndex);
		pointing.transform.localRotation = Quaternion.Euler(90,0,0);
        playerCamera.aimZoomPos = miArma.aimZoomPos;

		//Debug.Log("weaponManager - active Weapon equipado");
	}
	public void unEquip(){
		primaryWeapon.transform.parent = primarySlot;
		primaryWeapon.transform.localPosition = Vector3.zero;
		primaryWeapon.transform.localRotation = Quaternion.Euler(Vector3.zero);

		secundaryWeapon.transform.parent = secundarySlot;
		secundaryWeapon.transform.localPosition = Vector3.zero;
		secundaryWeapon.transform.localRotation = Quaternion.Euler(Vector3.zero);

		primaryWeapon.GetComponent<arma>().isNotItem();
		secundaryWeapon.GetComponent<arma>().isNotItem();
	}

    [Command]
    public void CmdEquipOnNetwork(weaponGlobals.weaponSlot weaponSlot)
    {
        RpcEquipOnAllClients(weaponSlot);
    }

    [ClientRpc]
    public void RpcEquipOnAllClients(weaponGlobals.weaponSlot weaponSlot)
    {
        //in localPlayer is already equiped. Not need equip again
        if (!isLocalPlayer)
        {
            unEquip();
            equip(weaponSlot);
        }
    }

	#endregion

	#region shooting
	public void shootingHip(){
		if(shoot()){// el arma disparo?
			float vHip = Random.Range(0f,miArma.angleHip);
			float hHip = Random.Range(-miArma.angleHip, miArma.angleHip);
			float bhip = Random.Range(miArma.backHip/2, miArma.backHip);

			desvio = Quaternion.Euler(pointing.transform.eulerAngles + new Vector3(-vHip/2, hHip/2, 0));
			pointing.transform.rotation = desvio;
			pointing.transform.position += pointing.transform.forward * -bhip;

			Camera.main.transform.Rotate(-vHip*miArma.camaraHip, hHip*miArma.camaraHip, 0);
		}
	}

	private bool shoot(){
		if(miArma.tiempo <= Time.time && miArma.currentAmmo>0){

			//RaycastHit hit;
			float randomAngle1 = Random.Range(-miArma.desvioBala/2, miArma.desvioBala/2); //rotate x angle
			float randomAngle2 = Random.Range(0 , 360); //rotate z angele
			//Ray ray = new Ray(miarma.barrel.position, miarma.barrel.eulerAngles + new Vector3(random1, 0, random2));

			//			if (Physics.Raycast(ray , out hit, 100f, mascara)){
			//				Quaternion angulo = Quaternion.FromToRotation(Vector3.zero, hit.normal);
			//				GameObject go = Instantiate(miarma.impact, hit.point, angulo) as GameObject;
			//				Destroy(go, 1f);
			//
			//			}

			GameObject particle = Instantiate(miArma.particulaShot, miArma.barrel.position, miArma.barrel.rotation) as GameObject;
			Destroy(particle, 1);
			GameObject poolBullet = PoolManager.instance.reuseObject(bullet, miArma.barrel.position, miArma.barrel.rotation);
			poolBullet.GetComponent<bala>().setHitCallback(playerHitCallback);
			poolBullet.GetComponent<bala>().damage = miArma.bulletDamage;
			poolBullet.transform.Rotate(0,0,randomAngle2);//first rotate z angle to change the up douwn perspective
			poolBullet.transform.Rotate(randomAngle1,0,0);//alter x angle to view more up down to itself perspective
			poolBullet.GetComponent<Rigidbody>().velocity = poolBullet.transform.forward*miArma.bulletVelocity;


			//CmdShoot(miarma.barrel.position, miarma.barrel.eulerAngles, miarma.desvioBala, miarma.bulletVelocity, miarma.bulletDamage);

			miArma.sonido.PlayOneShot(miArma.shotSound);
			//if(anim){
				//				anim.SetTrigger("shoot");
			//}
			miArma.tiempo = Time.time + miArma.fireRate;
			miArma.currentAmmo --;
			interfaz.balasText = miArma.currentAmmo + " / " + miArma.ammo;


			//instanciar cartuchos de balas disparadas
			switch(miArma.fireType){
			case weaponGlobals.fireType.bolt:
				//generer casquillo despues del bolt
				break;
			case weaponGlobals.fireType.pump_action:
				//generar casquillo despues del pump
				break;
			case weaponGlobals.fireType.revolver:
				//generar casquillos cuando regarga
				break;
			default:
				miArma.genCas();
				break;
			}
			return true;
		}else{
			return false;
		}
	}

	void playerHitCallback(GameObject target, float damage, bool isHeadshot){
		CmdMakeDamage(this.gameObject, target, damage, isHeadshot);
	}

	[Command]
	private void CmdMakeDamage(GameObject player, GameObject target, float damage, bool isHeadshot){
		target.GetComponent<vitality>().CmdDamageIt(player, damage, isHeadshot);
	}
	#endregion

}

alguna idea o hay alguna función que se ejecute en los jugadores que ya estaban conectados?.

Share this post


Link to post
Share on other sites

Si todo este código es tuyo, que no lo dudo, ya tienes un nivel.

Deberías acotar el problema. Flotando quieres decir que el transform del arma no se asigna, está en Vector.zero o en el quinto pino? Si es así, deberías colocar textos de Debug en la pantalla y entonces ver que transform tienen las armas en cada momento cuando se asignen o generar un log con los diferentes estados para poder hacer un seguimiento. Mirando el código así es una locura.

Share this post


Link to post
Share on other sites
Sign in to follow this  

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...