Client disconnects after changing name but host does not? - unity3d

So i am new to Mirror and i made this to learn a bit,it changes name of the host normally but when i try it on a client he just disconnects,and without any errors.I have setup many debug.log statements to see where is the problem and it seems that is not even executing as a client,it just stops before it was called.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using TMPro;
using System;`
public class PlayerMovement : NetworkBehaviour
{
public float speed;
float x, y;
Rigidbody2D rb;
Animator animator;
public TMP_InputField tmpf;
public TMP_Text nameText;
[SyncVar(hook = nameof(DisplayName))]
public string _name = "00";
void DisplayName(string oldName, string newName)
{
nameText.text = newName;
}
void Start()
{
if (!isLocalPlayer) return;
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
tmpf = GameObject.Find("NameIF").GetComponent<TMP_InputField>();
//tmpf.onValueChanged.AddListener(delegate { CmdChangeName(); });
}
void Update()
{
if (!isLocalPlayer) return;
x = Input.GetAxis("Horizontal");
y = Input.GetAxis("Vertical");
rb.velocity = new Vector2(x * speed, y * speed);
animator.SetFloat("horizontal", x);
animator.SetFloat("vertical", y);
if (Input.GetKeyDown(KeyCode.KeypadEnter))
{
CmdChangeName();
}
}
[Command]
public void CmdChangeName()
{
_name = tmpf.text;
}
How to fix this,i have client authority checked and i need to use commands if i want hooks and syncVar to work.

Related

how to spawn a prefab with filled object fields from scene

The game is working correctly and there arent any other issues apart from the fact that the public fields from the players scripts that are supposed to be filled with game objects from the scene arent filled and im not sure how to do that.
heres an example from one of the scripts: image
and heres what it should look like: image
the joystick area from the second image is from the scene, not an asset: image
here is the code im using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovePlayer : MonoBehaviour
{
public MovementJoystick movementJoystick;
public int playerSpeed;
private Rigidbody2D rb;
bool facingRight = true;
public Animator animator;
public float interval;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
playerSpeed = 7;
interval = 10;
}
// Update is called once per frame
void FixedUpdate()
{
if (movementJoystick.joystickVec.y != 0)
{
rb.velocity = new Vector2(movementJoystick.joystickVec.x * playerSpeed, movementJoystick.joystickVec.y * playerSpeed);
animator.SetFloat("speed", Mathf.Abs(movementJoystick.joystickVec.x));
}
else
{
rb.velocity = Vector2.zero;
animator.SetFloat("speed", Mathf.Abs(0));
}
if (movementJoystick.joystickVec.x < 0 && !facingRight)
{
Flip();
}
if (movementJoystick.joystickVec.x > 0 && facingRight)
{
Flip();
}
}
void Update()
{
if (playerSpeed == 14 && interval > 0)
{
interval -= Time.deltaTime;
}
else
{
playerSpeed = 7;
interval = 10;
}
}
void Flip()
{
transform.Rotate(0f, 180f, 0f);
facingRight = !facingRight;
}
public void SpeedControl(int newplayerSpeed)
{
playerSpeed = newplayerSpeed;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class MovementJoystick : MonoBehaviour
{
public GameObject joystick;
public GameObject joystickBG;
public Vector2 joystickVec;
private Vector2 joystickTouchPos;
private Vector2 joystickOriginalPos;
private float joystickRadius;
// Start is called before the first frame update
void Start()
{
joystickOriginalPos = joystickBG.transform.position;
joystickRadius = joystickBG.GetComponent<RectTransform>().sizeDelta.y / 2;
}
public void PointerDown()
{
joystick.transform.position = Input.mousePosition;
joystickBG.transform.position = Input.mousePosition;
joystickTouchPos = Input.mousePosition;
}
public void Drag(BaseEventData baseEventData)
{
PointerEventData pointerEventData = baseEventData as PointerEventData;
Vector2 dragPos = pointerEventData.position;
joystickVec = (dragPos - joystickTouchPos).normalized;
float joystickDist = Vector2.Distance(dragPos, joystickTouchPos);
if (joystickDist < joystickRadius)
{
joystick.transform.position = joystickTouchPos + joystickVec * joystickDist;
}
else
{
joystick.transform.position = joystickTouchPos + joystickVec * joystickRadius;
}
}
public void PointerUp()
{
joystickVec = Vector2.zero;
joystick.transform.position = joystickOriginalPos;
joystickBG.transform.position = joystickOriginalPos;
}
}
this is how to instantiate the player using photon servers (what i am using)
public GameObject playerToSpawn;
PhotonNetwork.Instantiate(playerToSpawn.name, spawnPoint.position, Quaternion.identity);
There are also 2 buttons i need you to fix: a Shoot button and a Hit button (those are the names). Here is the code for them:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShootButton : MonoBehaviour
{
//i made this script for the button incase you may
have
needed it
}
Here is the shooting script attached to the player:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Weapon : MonoBehaviour
{
public Transform firePoint;
public GameObject bulletPrefab;
public Button ShootButton;
void Start()
{
ShootButton.onClick.AddListener(ShootButtonTrue);
}
void ShootButtonTrue()
{
Shoot();
}
void Shoot()
{
Instantiate(bulletPrefab, firePoint.position,
firePoint.rotation);
}
}
Here is the hitting script attached to the Hit button
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HitButton : MonoBehaviour
{
}
And here is the Player Combat script using for hitting:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerCombat : MonoBehaviour
{
public Animator animator;
public Button AttackButton;
public Transform attackPoint;
public float attackRange = 0.5f;
public LayerMask enemyLayers;
void Start()
{
AttackButton.onClick.AddListener(AttackButtonTrue);
}
void AttackButtonTrue()
{
Attack();
}
void Attack()
{
animator.SetTrigger("Attack");
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);
foreach(Collider2D enemy in hitEnemies)
{
Debug.Log("u hit someone :O");
enemy.GetComponent<Health>().TakeDamage(15);
}
}
void OnDrawGizmosSelected()
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackRange);
}
}
if you need any other pieces of code just ask
thanks in advance, i will mark the answer as an answer if its a good answer
There are multiple ways to achieve this. For example, you can make your joystick singleton and assign that to the player upon spawn. If you have multiple joysticks in the scene, you can group them under the same parent object and make that parent singleton.
Assuming you only have one joystick in the scene, add this into your joystick class:
public static MovementJoystick Instance { get; private set; }
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
In your player class, add this:
void OnEnable()
{
if( movemaneJoystick == null)
{
movementJoystick = MovementJoystick.Instance;
}
}

XRBaseInteractable does not contain a definition for OnSelectEntering

I am tring to follow this tutorial https://www.youtube.com/watch?v=gmaAK_BXC4c to make a vr gun but I am getting an the following error:
'XRBaseInteractable' does not contain a definition for 'onSelectEntering' and no accessible extension method 'onSelectEntering' accepting a first argument of type 'XRBaseInteractable' could be found (are you missing a using directive or an assembly reference?) [Assembly-CSharp]csharp(CS1061)
for the following lines :
socketInteractor.onSelectEntering.AddListener(AddMagazine);
socketInteractor.onSelectExiting.AddListener(RemoveMagazine);
Here is my code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
[AddComponentMenu("Nokobot/Modern Guns/Simple Shoot")]
public class SimpleShoot : MonoBehaviour
{
[Header("Prefab Refrences")]
public GameObject bulletPrefab;
public GameObject casingPrefab;
public GameObject muzzleFlashPrefab;
[Header("Location Refrences")]
[SerializeField] private Animator gunAnimator;
[SerializeField] private Transform barrelLocation;
[SerializeField] private Transform casingExitLocation;
[Header("Settings")]
[Tooltip("Specify time to destory the casing object")] [SerializeField] private float destroyTimer = 2f;
[Tooltip("Bullet Speed")] [SerializeField] private float shotPower = 500f;
[Tooltip("Casing Ejection Speed")] [SerializeField] private float ejectPower = 150f;
public AudioSource source;
public AudioClip fireSound;
public AudioClip reload;
public Magazine magazine;
public AudioClip noAmmo;
public XRBaseInteractable socketInteractor;
public void AddMagazine(XRBaseInteractable interactable)
{
magazine = interactable.GetComponent<Magazine>();
source.PlayOneShot(reload);
}
public void RemoveMagazine(XRBaseInteractable interactable)
{
magazine = null;
}
public void Slide()
{
}
void Start()
{
if (barrelLocation == null)
barrelLocation = transform;
if (gunAnimator == null)
gunAnimator = GetComponentInChildren<Animator>();
socketInteractor.onSelectEntering.AddListener(AddMagazine);
socketInteractor.onSelectExiting.AddListener(RemoveMagazine);
}
public void PullTheTrigger()
{
if(magazine && magazine.numberOfBullet > 0)
{
gunAnimator.SetTrigger("Fire");
}
else
{
source.PlayOneShot(noAmmo);
}
}
//This function creates the bullet behavior
void Shoot()
{
magazine.numberOfBullet--;
source.PlayOneShot(fireSound);
if (muzzleFlashPrefab)
{
//Create the muzzle flash
GameObject tempFlash;
tempFlash = Instantiate(muzzleFlashPrefab, barrelLocation.position, barrelLocation.rotation);
//Destroy the muzzle flash effect
Destroy(tempFlash, destroyTimer);
}
//cancels if there's no bullet prefeb
if (!bulletPrefab)
{ return; }
// Create a bullet and add force on it in direction of the barrel
Instantiate(bulletPrefab, barrelLocation.position, barrelLocation.rotation).GetComponent<Rigidbody>().AddForce(barrelLocation.forward * shotPower);
}
//This function creates a casing at the ejection slot
void CasingRelease()
{
//Cancels function if ejection slot hasn't been set or there's no casing
if (!casingExitLocation || !casingPrefab)
{ return; }
//Create the casing
GameObject tempCasing;
tempCasing = Instantiate(casingPrefab, casingExitLocation.position, casingExitLocation.rotation) as GameObject;
//Add force on casing to push it out
tempCasing.GetComponent<Rigidbody>().AddExplosionForce(Random.Range(ejectPower * 0.7f, ejectPower), (casingExitLocation.position - casingExitLocation.right * 0.3f - casingExitLocation.up * 0.6f), 1f);
//Add torque to make casing spin in random direction
tempCasing.GetComponent<Rigidbody>().AddTorque(new Vector3(0, Random.Range(100f, 500f), Random.Range(100f, 1000f)), ForceMode.Impulse);
//Destroy casing after X seconds
Destroy(tempCasing, destroyTimer);
}
}

Swapping Two GameObjects on Keypress

When I press Space, the player and the dummy are supposed to swap places. This doesn't just happen once, it needs to happen everytime I press the Space bar so they can swap back and forth. However, sometimes it works and sometimes it doesn't. When it doesn't work, the dummy teleports to the player and then the player teleports inside of the dummy (as that is where its last position is). This just kind of pushes the player about.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSwap : MonoBehaviour
{
public GameObject player;
public GameObject dummy;
public GameObject cameraAnchor;
public Transform playerLastPos;
public Transform dummyLastPos;
public bool haveSwapped;
public bool canSwap;
public float swapRadius;
public LayerMask dummyInRadius;
// Update is called once per frame
void Update()
{
canSwap = Physics.CheckSphere(player.transform.position, swapRadius, dummyInRadius);
SwapTransforms();
if (canSwap)
{
if (Input.GetKeyDown(KeyCode.Space))
{
haveSwapped = !haveSwapped;
Swapping();
}
}
else
{
Debug.Log("Can't Swap");
}
cameraAnchor.transform.position = player.transform.position;
}
public void SwapTransforms()
{
if (haveSwapped)
{
dummyLastPos.position = player.transform.position;
playerLastPos.position = dummy.transform.position;
}
else
{
dummyLastPos.position = dummy.transform.position;
playerLastPos.position = player.transform.position;
}
}
public void Swapping()
{
if (haveSwapped)
{
player.transform.position = dummyLastPos.position;
dummy.transform.position = playerLastPos.position;
}
else
{
player.transform.position = playerLastPos.position;
dummy.transform.position = dummyLastPos.position;
}
}
public void OnDrawGizmos()
{
Gizmos.color = Color.white;
Gizmos.DrawWireSphere(player.transform.position, swapRadius);
}
}
I've solved it. After cleaning up most of the code and realsing I had to turn off movement and the character controller on the player (Link:Unity Answers), I came up with this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSwap : MonoBehaviour
{
public ThirdPersonMovement playerMove;
public GameObject player;
public GameObject dummy;
public GameObject cameraAnchor;
public Transform playerLastPos;
public Transform dummyLastPos;
public bool canSwap;
public float swapRadius;
public LayerMask dummyInRadius;
// Update is called once per frame
void Update()
{
canSwap = Physics.CheckSphere(player.transform.position, swapRadius, dummyInRadius);
if (canSwap)
{
if (Input.GetKeyDown(KeyCode.Space))
{
playerMove.canMove = false;
player.GetComponent<CharacterController>().enabled = false;
SetTransforms();
}
}
else
{
Debug.Log("Can't Swap");
}
cameraAnchor.transform.position = player.transform.position;
}
public void SetTransforms()
{
dummyLastPos.position = dummy.transform.position;
playerLastPos.position = player.transform.position;
Debug.Log("Set Transforms");
Swapping();
}
public void Swapping()
{
player.transform.position = dummyLastPos.position;
dummy.transform.position = playerLastPos.position;
dummy.transform.rotation = player.transform.rotation;
Debug.Log("Swap");
playerMove.canMove = true;
player.GetComponent<CharacterController>().enabled = true;
}
public void OnDrawGizmos()
{
Gizmos.color = Color.white;
Gizmos.DrawWireSphere(player.transform.position, swapRadius);
}
}

Player can still move after death when dying while pressing directional keys

I am currently learning unity using c# and I made the following code using someones tutorial but I think the tutorial I am currently using as a reference is not giving me much info about this current bug. I already added a bool called dead which I placed on FixedUpdate() and Update() to check whether to accept input or not. It works well if I die without pressing directional keys like dying while attacking and dying while idle... I want to know what is wrong with my code. I would be very happy for some hints. Here is my c# code.
PlayerManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
Rigidbody rb;
public float x, y, ms = 3;
Animator animator;
public Collider weaponCollider;
public PlayerUIManager playerUIManager;
public int maxHp = 100;
public int hp;
bool dead;
// Start is called before the first frame update
void Start()
{
hp = maxHp;
ms = 3;
playerUIManager.Init(this);
rb = GetComponent<Rigidbody>();
animator = GetComponent<Animator>();
DisableWeaponCollider();
}
void Update()
{
if (dead) return;
x = Input.GetAxisRaw("Horizontal");
y = Input.GetAxisRaw("Vertical");
if(Input.GetKeyDown(KeyCode.Space))
{
animator.SetTrigger("Attack");
}
}
void GetDamage(int damage)
{
hp -= damage;
if (hp <= 0)
{
hp = 0;
dead = true;
animator.SetTrigger("Die");
}
playerUIManager.UpdateHp(hp);
}
private void FixedUpdate()
{
if (dead) return;
Debug.Log("fixed updating");
Vector3 velocity = new Vector3(x, 0, y) * 0.29f;
Vector3 direction = transform.position + velocity;
transform.LookAt(direction);
rb.velocity = velocity;
animator.SetFloat("Speed", rb.velocity.magnitude);
}
private void OnTriggerEnter(Collider other)
{
if (dead) return;
Damager damager = other.GetComponent<Damager>();
if (damager != null)
{
animator.SetTrigger("DamageReceive");
GetDamage(damager.damage);
}
}
public void EnableWeaponCollider()
{
weaponCollider.enabled = true;
}
public void DisableWeaponCollider()
{
weaponCollider.enabled = false;
}
}
DieBehavior.cs (for my die animation)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DieBehavior : StateMachineBehaviour
{
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.GetComponent<PlayerManager>().ms = 0;
}
//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{}
//override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{}
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{}
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{}
}
The issue comes from because rb.velocity is still set.
So you need to reset velocity together when you set dead flag.
if (hp <= 0)
{
hp = 0;
dead = true;
animator.SetTrigger("Die");
// Please add this
rb.velocity = Vector3.zero;
}
Rigidbody.velocity doesn't work once. It means once you set velocity, the GameObject moves until you reset velocity.
Rigidbody.velocity represents the rate of change of Rigidbody position.

Why isn't the new values for the variable not taking affect in void update in unity?

I was trying to get an object to change direction when it hits another object but for some reason when it hits an object, the original object stands still.
using UnityEngine;
using System.Collections;
public class playerController : MonoBehaviour {
public float c =0;
public float a =0;
public float d =1;
private Rigidbody rb;
void Start ()
{
rb = GetComponent<Rigidbody>();
}
void OnTriggerEnter(Collider other) {
a = 0;
c = -1;
d = 0;
}
void fixedUpdate ()
{
transform.Translate (c*1f, a*1f, d*1f);
}
}
Just try "FixedUpdate" instead of "fixedUpdate".