Hi I have a question about mirror.
I have made a mariokart like game. it works almost perfectly I only have one problem I cant seem to fix.
when I shoot a weapon on the server it works perfectly. On the client it also works when I'm standing still. but when I do it on the client while driving it spawns behind the cart because of syncing or something. How can I fix this?
this is the code
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && hasItem)
{
hasItem = false;
_icon.sprite = null;
CmdFireWeapon();
}
}
[Command]
private void CmdFireWeapon()
{
GameObject item = Instantiate(tempItem, weaponSpawner.position, weaponSpawner.rotation);
NetworkServer.Spawn(item);
}
Related
I am developing a VR game in Unity (2020.3.15f2) using the XR Interaction Toolkit package (1.0.0-pre.5) for my Oculus Quest 2. At this stage in my development, I am trying to recognize presses to the trigger and grip buttons on the controllers respectively in order to animate some 3D hand models. Here's the script I've written to accomplish this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public class HandPresence : MonoBehaviour {
public InputDeviceCharacteristics controllerCharacteristics;
public GameObject handModelPrefab;
private InputDevice targetDevice;
private GameObject spawnedHandModel;
private Animator handAnimator;
void Start() {
TryInitialize();
}
void TryInitialize() {
List<InputDevice> devices = new List<InputDevice>();
InputDevices.GetDevicesWithCharacteristics(controllerCharacteristics, devices);
if (devices.Count > 0) {
targetDevice = devices[0];
spawnedHandModel = Instantiate(handModelPrefab, transform);
handAnimator = spawnedHandModel.GetComponent<Animator>();
}
}
void UpdateHandAnimation() {
if (targetDevice.TryGetFeatureValue(CommonUsages.trigger, out float triggerValue)) {
handAnimator.SetFloat("Trigger", triggerValue);
} else {
handAnimator.SetFloat("Trigger", 0);
}
if (targetDevice.TryGetFeatureValue(CommonUsages.grip, out float gripValue)) {
handAnimator.SetFloat("Grip", gripValue);
} else {
handAnimator.SetFloat("Grip", 0);
}
}
void Update()
{
if (!targetDevice.isValid) {
TryInitialize();
} else {
spawnedHandModel.SetActive(true);
UpdateHandAnimation();
}
}
}
The issue I'm experiencing is that the values of both triggerValue and gripValue are always 0. The value of targetDevice looks fine. I also tried using triggerButton, gripButton, primaryButton, etc. and they are always 0/false as well. The hand models show up just fine and their movement is in sync with the movement of the controllers, but they just don't seem to want to register any button presses.
I've been stuck on this one for hours and would very much appreciate any insight, thank you!
Is your project setup with the (new) Input System? I have no problem detecting there trigger and grip values.
Also make sure the targetDevice actually uses trigger and grip features, maybe it is another device such as the HMD.
Hi Guys I am converting a single player Sudoko game into a multiplayer game (right now 2 players) using Photon in Unity.
The basic logic of the Sudoku game is that there are 300 puzzle data already loaded in it. A random number between 1 to 300 is picked up and the corresponding puzzle is loaded.
But the problem I am facing is even though I have made sure that the same number is getting picked up for both the client and the master server, different puzzles are getting loaded.
So basically I script called MultiManager attached to the MultiManager GameObject in the Sudoku screen.The script looks something like this.
void Start()
{
PV = GetComponent<PhotonView>();
if (PhotonNetwork.IsMasterClient)
{
puzzleIndex = Random.Range(0, 300);
PV.RPC("RPC_PuzzleIndex", RpcTarget.Others, puzzleIndex);
}
gameManager = FindObjectOfType(typeof(GameManager)) as GameManager;
gameManager.PlayNewGame("easy");
}
[PunRPC]
void RPC_PuzzleIndex(int puzzleIndexNUmber)
{
puzzleIndex = puzzleIndexNUmber;
}
So in the GameManager script you have these functions:
public void PlayNewGame(string groupId)
{
// Get the PuzzleGroupData for the given groupId
for (int i = 0; i < puzzleGroups.Count; i++)
{
PuzzleGroupData puzzleGroupData = puzzleGroups[i];
if (groupId == puzzleGroupData.groupId)
{
PlayNewGame(puzzleGroupData);
return;
}
}
}
private void PlayNewGame(PuzzleGroupData puzzleGroupData)
{
// Get a puzzle that has not yet been played by the user
PuzzleData puzzleData = puzzleGroupData.GetPuzzle();
// Play the game using the new puzzle data
PlayGame(puzzleData);
}
And in the PuzzleGroupData class you have this function :
public PuzzleData GetPuzzle()
{
return new PuzzleData(puzzleFiles[MultiManager.puzzleIndex], shiftAmount, groupId);
}
I don't quite get as to whats wrong which is happening. I tried to use other variations like keeping that random number outside of the condition inside of PhotonNetwork.isMasterClient and all, but doesn't work.
If anyone can help it would be great. By the way this Sudoku game was purchased and I am trying to convert it to a mutliPlayer game
Since the master is usually the first one in a room so also the first one getting Start called I think what happens is that your other clients are simply not connected yet when the RPC is called.
Further it might also happen (actually pretty likely) that Start is called before the RPC has the chance to be received.
I would rather actually wait until you have the value and do
void Start()
{
PV = GetComponent<PhotonView>();
if (PhotonNetwork.IsMasterClient)
{
PV.RPC(name of(RPC_PuzzleIndex), RpcTarget.AllBuffered, Random.Range(0, 300));
}
}
[PunRPC]
void RPC_PuzzleIndex(int puzzleIndexNUmber)
{
puzzleIndex = puzzleIndexNUmber;
gameManager = FindObjectOfType(typeof(GameManager)) as GameManager;
gameManager.PlayNewGame("easy");
}
This way
the RpcTarget.AllBuffered makes sure that also clients joining later will receive the call
there is no way you start a game without receiving the random value first
For my game you need to complete a mini-game to unlock abilities. But I atually have no clue how to do it cause the value gets resetted to false whenever I load the main-level.
Code playerMovement:
static bool FistAttackEnabled;
void Update ()
{
if (FistAttackEnabled == true)
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Attack");
PlayerMovement.SetFloat("Attacking", 1f);
HitArea.SetActive(true);
}
}
}
Code miniGame:
void Start()
{
FistAttackEnabled = Player.GetComponent<Player_Movement>().FistAttackEnabledPortable;
}
void Update()
{
if (SheepsAmountGuess == NeededAni)
{
FistAttackEnabled = true;
}
}
But this doesnt work. I tried making a portable bool (FistAttackEnabledStatic = FistAttackEnabled) Because you cant transport static bool value's across scripts, but this also didn't work. Does anyone have a clue how to do it?
PS: The code is bigger but it doesn't have anything to do with the attack.
Each time the scene is loaded the scripts are reloaded, so variables will go to their "default" state
You can avoid the destruction of the gameObject by usign DontDestroyOnLoad(this.gameObject);
Since the GameObject wont be deleted each time you reload the scene a new copy will be created to solve that you should use a singleton(look for it you will find information easyly)
Both things will solve the problem temporaly but once you close the game everything will go to the original state. You should use some method to save the progress, PlayerPrefs is a really easy way to do it.
I started my game dev journey a few weeks ago and I am enjoying it, but sometimes it can get frustrating when things do not work.
I wrote a very basic code for particle system, if we press space then particle should play. The problem is that its not playing, when I hit play it doesn't work for some reason. When I click the particle in the scene then it works and it also works when I check on the play on awake
The Code:
[SerializeField] ParticleSystem engineBoostParticle;
[SerializeField] ParticleSystem sideEngineParticles;
void Start()
{
}
void Update()
{
ThrustingInput();
}
void ThrustingInput()
{
if (Input.GetKey(KeyCode.Space))
{
if (!engineBoostParticle.isPlaying)
{
engineBoostParticle.Play();
}
}
else
{
AS.Stop();
engineBoostParticle.Stop();
}
}
You want to check engineBoostParticle.isEmitting as well as isPlaying in your if statement.
It's possible that your system is playing, but not emitting (because the loop is over), so make sure the particle system loops properly as well.
Working on a Unity hybrid VR (cardboard) /2D app. The cardboard side of it works fine. I am having trouble with the 2D/VR switching.
When I am in 2D mode, reticle does not move, although screen taps register. So the app seems unaware of the gyro.
I feel like I am missing something fundamental here. I have a GvrEventSystem prefab that has both an EventSystem and GvrPointerInputModule components.
What obvious thing am I over-looking?
ETA:
I have been asked to add relevant code. Here is the code for 2D-VR switching on-the-fly. This code executes w/out error, and the app switches between VR and 2D mode every 3 seconds:
readonly string NONE_STRING = "";
readonly string CARDBOARD_STRING = "cardboard";
void Start()
{
Invoke("GoPhone", 3.0f);
}
void GoPhone()
{
SetVREnabled(false);
Invoke("GoVR", 3.0f);
}
void GoVR()
{
SetVREnabled(true);
Invoke("GoPhone", 3.0f);
}
void SetVREnabled(bool isEnabled)
{
if (isEnabled)
{
StartCoroutine(LoadDevice(CARDBOARD_STRING));
}
else
{
StartCoroutine(LoadDevice(NONE_STRING));
}
}
IEnumerator LoadDevice(string newDevice)
{
if (String.Compare(XRSettings.loadedDeviceName, newDevice, true) != 0)
{
XRSettings.LoadDeviceByName(newDevice);
yield return null;
if (!XRSettings.loadedDeviceName.Equals(NONE_STRING))
XRSettings.enabled = true;
}
}
Although I feel like my problem is a configuration problem, and not a code problem. In the editor, which does not support VR mode, the app behaves in 2D mode as expected.
Also ETA:
JIC
User error! I did not follow the "Magic Window" instructions as detailed at https://developers.google.com/vr/develop/unity/guides/magic-window... let my folly be a warning to future generations!