Je travaille sur un jeu multijoueur local et je rencontre un problème avec les input et les contrôleurs du joueur.
J'ai deux scène :
1°) Les joueurs appuient sur un bouton de leur contrôleur (clavier+souris ou manette) pour apparaître à l'écran. Et ils choisissent une équipe avec laquelle jouer. Il y a 4 équipes parmi lesquelles choisir. Et lorsque tous les joueurs sont prêts, une deuxième scène est chargée.
2°) Les joueurs apparaissent à des positions différentes par rapport à leur équipe dans cette seconde scène.
Si le premier joueur est contrôlé par le clavier+souris et le second est contrôlé par une manette de jeu dans la première scène, après le chargement de la deuxième scène, le joueur 1 est toujours contrôlé par le clavier et le joueur 2 est toujours contrôlé par la manette de jeu.
Essayons maintenant si le clavier n'est PAS ce qui contrôle le joueur 1 :
a) Dans la première scène, si le joueur 1 est contrôlé par une manette de jeu et le deuxième joueur par le clavier, lorsque la deuxième scène est chargée, le premier joueur est désormais contrôlé par le clavier et le deuxième joueur est désormais contrôlé par la manette de jeu. .
Et dans le composant "Player Input", je peux effectivement voir que désormais le clavier contrôle le joueur 1 et le joystick contrôle le joueur 2. Alors que dans la scène de sélection d'équipe, c'était l'inverse.
Le joueurs 1 contrôle le personnage du joueur 2 et inversement
b) Si dans la première scène, le joueur 1 est contrôlé par une manette de jeu et le deuxième joueur est contrôlé par une deuxième manette de jeu. Une fois la deuxième scène chargée, le premier joueur peut être contrôlé par la première manette de jeu mais le deuxième joueur ne bouge pas du tout. Parce que dans son composant Player Input, je vois que le joueur 2 attend une saisie au clavier (mais comme aucun clavier n'a été utilisé dans la scène 1, si j'appuie sur mon clavier, le joueur 2 ne bouge pas. Il attend donc l'input d'un clavier inexistant ...
c) Si j'utilise le clavier pour le joueur 1, une première manette pour le joueur 2 et une deuxième manette pour le joueur 3, tout fonctionne très bien.
d) Si j'utilise une première manette pour le joueur 1, le clavier pour le joueur 2 et une deuxième manette pour le joueur 3, encore une fois le clavier reprend le contrôle du joueur 1 et la première manette permet de contrôler le joueur 2 mais la deuxième manette contrôle bien le joueur 3.
Je ne sais pas si c'est mon script qui a conduit à ce problème ou s'il y a quelque chose que je ne saisi pas bien dans le fonctionnement de Unity alors voici mes scripts :
PlayerConfigurationManager.cs est appelé à chaque fois qu'un joueur rejoint (en appuyant sur un bouton du contrôleur) dans la première scène (où les joueurs doivent choisir une équipe) et la fonction "HandlePlayerJoin" est utilisée.
Code : Tout sélectionner
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using System.Linq;
using TMPro;
using UnityEngine.SceneManagement;
using UnityEngine;
public class PlayerConfigurationManager : MonoBehaviour
{
private List<PlayerConfiguration> _playerConfigs;
[SerializeField] private int _maxPlayer = 4;
[SerializeField] private int _minPlayer = 2;
[SerializeField] private TextMeshProUGUI _textNumberOfPlayer;
[SerializeField] private TextMeshProUGUI _textNumberOfJoinedPlayer;
public static PlayerConfigurationManager Instance { get; private set; }
private void Awake()
{
if (Instance != null)
{
Debug.Log("SINGLETON : Trying to create another instance of singleton!");
}
else
{
Instance = this;
_playerConfigs = new List<PlayerConfiguration>();
}
}
public void SetPlayerColor (int index, Material color)
{
_playerConfigs[index].PlayerMaterial = color;
}
public void SetTeam(int index, int teamNumber)
{
_playerConfigs[index].Team = teamNumber;
}
public void ReadyPlayer(int index)
{
_playerConfigs[index].IsReady = true;
if (_playerConfigs.Count >= _minPlayer && _playerConfigs.All(p => p.IsReady == true))
{
SceneManager.LoadScene("TopDownScene");
}
}
public void UnreadyPlayer(int index)
{
_playerConfigs[index].IsReady = false;
}
public void HandlePlayerJoin(UnityEngine.InputSystem.PlayerInput pi)
{
if(!_playerConfigs.Any(p => p.PlayerIndex == pi.playerIndex))
{
pi.transform.SetParent(transform);
_playerConfigs.Add( new PlayerConfiguration(pi));
_textNumberOfPlayer.GetComponent<PlayerNumberReadyTextScript>().SetPlayerCount(_playerConfigs.Count);
_textNumberOfJoinedPlayer.GetComponent<TextToJoinScript>().SetJoinedPlayerCount(_playerConfigs.Count);
}
}
public List<PlayerConfiguration> GetPlayerConfigs()
{
return _playerConfigs;
}
private void Update()
{
}
}
public class PlayerConfiguration
{
public PlayerConfiguration(UnityEngine.InputSystem.PlayerInput pi)
{
PlayerIndex = pi.playerIndex;
Input = pi;
}
public UnityEngine.InputSystem.PlayerInput Input { get; set; }
public int PlayerIndex { get; set; }
public bool IsReady { get; set; }
public Material PlayerMaterial { get; set; }
public int Team { get; set; }
}
Code : Tout sélectionner
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class InitializeLevel : MonoBehaviour
{
[SerializeField] private Transform[] _playerSpawns;
private int _offSet1 = 0;
private int _offSet2 = 0;
private int _offSet3 = 0;
private int _offSet4 = 0;
private Vector3 _OffSetVector = new Vector3(3.0f, 0f, 0f);
[SerializeField] private GameObject _playerPrefab;
// Start is called before the first frame update
void Start()
{
var playerConfigs = PlayerConfigurationManager.Instance.GetPlayerConfigs().ToArray();
for (int i = 0; i < playerConfigs.Length; i++)
{
Debug.Log("Player Index : " + playerConfigs[i].PlayerIndex + "is from Team : " + playerConfigs[i].Team);
switch (playerConfigs[i].Team)
{
case 1:
_offSet1++;
var player1 = Instantiate(_playerPrefab, _playerSpawns[playerConfigs[i].Team-1].position + _offSet1 * _OffSetVector, Quaternion.identity, gameObject.transform);
player1.GetComponent<PlayerInputHandler>().InitializePlayer(playerConfigs[i]);
break;
case 2:
_offSet2++;
var player2 = Instantiate(_playerPrefab, _playerSpawns[playerConfigs[i].Team-1].position + _offSet2 * _OffSetVector, Quaternion.identity, gameObject.transform);
player2.GetComponent<PlayerInputHandler>().InitializePlayer(playerConfigs[i]);
break;
case 3:
_offSet3++;
var player3 = Instantiate(_playerPrefab, _playerSpawns[playerConfigs[i].Team-1].position + _offSet3 * _OffSetVector, Quaternion.identity, gameObject.transform);
player3.GetComponent<PlayerInputHandler>().InitializePlayer(playerConfigs[i]);
break;
case 4:
_offSet4++;
var player4 = Instantiate(_playerPrefab, _playerSpawns[playerConfigs[i].Team-1].position + _offSet4 * _OffSetVector, Quaternion.identity, gameObject.transform);
player4.GetComponent<PlayerInputHandler>().InitializePlayer(playerConfigs[i]);
break;
}
}
}
}
Code : Tout sélectionner
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerInputHandler : MonoBehaviour
{
private PlayerConfiguration _playerConfig;
private CharacterStateMachine _characterStateMachine;
[SerializeField] private GameObject _playerMesh;
private Player_Input _controls;
private void Awake()
{
_characterStateMachine = GetComponent<CharacterStateMachine>();
_controls = new Player_Input();
}
public void InitializePlayer(PlayerConfiguration pc)
{
_playerConfig = pc;
_playerMesh.GetComponentInChildren<Renderer>().material = pc.PlayerMaterial;
_playerConfig.Input.onActionTriggered += Input_OnActionTriggered;
}
private void Input_OnActionTriggered(InputAction.CallbackContext obj)
{
if (obj.action.name == _controls.CharaControls.Move.name)
{
OnMove(obj);
}
}
public void OnMove(InputAction.CallbackContext context)
{
if (_characterStateMachine != null)
{
_characterStateMachine.OnMovementInput(context);
}
}
}
![Dan.San :)](./images/smilies/1.gif)
Quelqu'un peut-il m'aider à comprendre s'il vous plaît ? Pourquoi, Unity inverse les contrôleurs ?