Renard roux Je suis content de voir que ta motivation est solide et que tu apprends de ton côté grâce à des vidéos en surpassant ta difficulté en anglais. Excuse moi d'avoir douté de tes compétences mais j'ai préféré dans le doute te donner mon ressenti.
Sinon pour la suite de ton apprentissage je te conseille de te diriger vers les tutoriels officiels d'Unity qui sont de très bonne qualités et qui permettent de monter un petit jeu pour aborder de nombreux aspects de la création : https://unity3d.com/fr/learn/tutorials (Dans la partie 'Projets')
PS : Si tu t'intéresse à la création d'un menu c'est par là : https://unity3d.com/fr/learn/tutorials/topics/user-interface-ui (surtout le tutoriel 9. Creating a main menu)
Marco Tu as raison dans le sens où j'ai été peut être un peu violent. Sinon je pense que les débutants doivent bien sûr venir poser leurs colles ici, mais il ne faut pas que cela devienne une habitude de poser chaque petite question ici et se reposer sur l'expérience des autres. Je suis un grand adepte de l'autodidacte et je pense que cette pédagogie est la meilleur pour apprendre à programmer. Je me met au service des débutants tout comme toi, mais je ne deviens pas leur pilier, je ne suis qu'une aide, un petit support, leur support principal doit venir d'eux même.
sont codés en C#, et tous mes autres scripts en JS
Attention tu pars mal, un projet doit être soit en C# soit en Js, un mélange des deux mène à un joli bordel car ils ne peuvent interagir.
J’ai énormément de mal à comprendre la structure du C# malgré les tutos...
Pour ce que tu as besoin de savoir pour le moment, le C# a quasiment la même structure.
function void
var n : int; int n;
Sinon le reste à globalement la même syntax.
En poussant le langage tu découvriras qu'il possède d'autres subtilités inaccessibles au js mais tu n'y est pas encore.
J’arrive pas non plus à récupérer et à afficher la valeur de mon slider
Tu dois dans un script inclure la bibliothèqueusing UnityEngine.UI;
Ensuite tu déclare une variable de type "Slider"public Slider MySlider;
Tu l'assigne depuis l'inspecteur ou dans la fonction Start()
De la même façon tu créé une variable pour contenir ton FirstPersonControllerpublic FirstPersonController Controller;
Pour récupérer la valeur du slider :void Update()
{
float sliderValue = Slider.normalizedValue;
}
C'est donc dans la fonction update que tu peux ensuite changer la sensitivité.
De base tu ne peux pas accéder à la sensitivité puisque la variable est privée dans le script FirstPersonController.
Tu dois donc accéder à FirstPersonController.cs et changer[SerializeField] private MouseLook m_MouseLook;
en[SerializeField] public MouseLook m_MouseLook;
Pour avoir accès au type FirstPersonController tu dois avoir accès aux class importés par le character controller standard asset. Tu met donc au débutusing UnityStandardAssets.Characters.FirstPerson;
Maintenant tu peux changer la sensitivité en accédant àController.m_MouseLook.XSensitivity
Voici donc un résumé en code :
using UnityEngine.UI;
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
public class SensitivityManager : MonoBehaviour
{
public Slider MySlider;
public FirstPersonController Controller;
public float MaxSensitivity;
void Start()
{
//Assignation de MySlider et Controller
}
void Update()
{
float sliderValue = Slider.normalizedValue;
Controller.m_MouseLook.XSensitivity = sliderValue * MaxSensitivity;
Controller.m_MouseLook.YSensitivity = sliderValue * MaxSensitivity;
}
}
Question du jour bonjour.
Je suis toujours sur mon jeu de plateforme 2d et je me retrouve face a un probleme : comment detecter quel coté de mon box collider est en contact pour savoir si je suis sur un mur (wall jump) ou si je touche le sol (jump normal).
J'avais pensé a creer 4 trigger enfant sur mon perso (un trigger = un coté) mais ca marche tres moyen.
Une idée ? (Mon perso pourra subir des rotations)
Tu utilises un CharacterController ? Si oui :
https://docs.unity3d.com/ScriptReference/CharacterController-isGrounded.html
Sinon je sais pas.
Un characterController ? Connait pas, ca marche comment ?
Je te conseil de regarder un petit tuto en ligne. En gros c'est un composant qui implémente par défaut quelques trucs inutiles pour les personnages en 2D/3D qu'on joue.
https://docs.unity3d.com/Manual/class-CharacterController.html
Sinon tu peux envoyer un raycast à gauche, à droite et sous le persos d'une petite longueur, c'est économe en ressources et très efficace
https://docs.unity3d.com/ScriptReference/Physics.Raycast.html
Tu peux ainsi créer deux variables
IsGrounded et OverWall
Tu met le résultat du raycast vers le bas dans IsGrounded et celui des raycast vers les côtés dans OverWall, si IsGounded : OverWall = false
Ensuite tu laisse la magie opérer et tu as pas à galérer avec le character controller (pour moi c'est une source d'ennuis mieux vaut tout faire soi même).
J'ai essayé le character controller et clairement j'ai rien compris a son utilité ni comment ca marchait.
En effet faire un mini raycast etait une bonne idée, ca me fait un probleme en moins
Plop les gars,
Je cherche de l'aide pour ajouter une feature unity. Je vous explique je suis étudiant dans une formation JV qui recrute aussi des autodidactes. Malheureusement pour moi je n'ai jamais fais de prog (plutot un profil 3d) et je dois rajouter une feature a un projet de space shooter (https://unity3d.com/fr/learn/tutorials/projects/space-shooter/introduction).
J'ai donc choisis que je voulais faire un tir secondaire en clic droit, une sorte de lazer. j'ai créé un prefab avec mon projectile et la je bloque je ne sais pas du tout comment terminer ce projet...
Donc je voudrais savoir si l'un de vous peut me donner un cours particulier ou m'aider avec ça ?
https://unity3d.com/fr/learn/tutorials/projects/space-shooter/shooting-shots?playlist=17147void Update ()
{
if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
}
Dans ce script, tu captures l'évènement lorsque l'utilisateur appuie sur Fire1 (clique gauche par défaut), tu dois faire un else if ()
et capturer un clique droit, par exemple et effectuer quasiment le même code, en utilisant ton prefab.
Le 22 novembre 2016 à 17:54:20 TheRealMarco a écrit :
https://unity3d.com/fr/learn/tutorials/projects/space-shooter/shooting-shots?playlist=17147void Update () { if (Input.GetButton("Fire1") && Time.time > nextFire) { nextFire = Time.time + fireRate; Instantiate(shot, shotSpawn.position, shotSpawn.rotation); } }
Dans ce script, tu captures l'évènement lorsque l'utilisateur appuie sur Fire1 (clique gauche par défaut), tu dois faire un
else if ()
et capturer un clique droit, par exemple et effectuer quasiment le même code, en utilisant ton prefab.
Merci de ta réponse alors voila ou je suis (mon prof de level design m'a mis des commentaires en plus mais je suis toujours un peu perdu).
if (Input.GetButton ("Fire2"))
{
// ici le click droit est appuyé
if (_isSecondaryWeapon == true)
{
Instantiate(shot, SecondaryWeapon.position, _secondaryWeaponPrefab.rotation);
// et donc si mon arme secondaire n'est pas activée, je l'active
}
else
{
Instantiate (_isSecondaryWeapon == false);
// ici le click droit est relâché
// et donc si mon arme secondaire est activée, je la désactive
}
En gros je dois lui dire quand j’appuie sur le bouton droit le lazer s'active et quand je n’appuie pas il est sur off.
En plus je viens de penser que mon lazer dois détruire les astéroide, donc je dois lui dire... dans le script destroy by contact ?
Il faudrais aussi que j'ajoute une batterie a ce lazer, genre je peux tirer 5 seconde en cpontinue, il se coupe et j'attend 5 sec que la batterie se recharge... (optionnelle je voudrais déjà réussir a piger tout ca mais pour moi qui n'ai eu aucun cours de prog avant je galère un peu).
Tu as oubliée une accolade http://prntscr.com/davfk6
Merci j'ai rajouté l'accolade mais unity me fais des messages d'erreurs :
j'ai déclaré une variable pourtant, pour lui dire que mon lazer existe, le nom de mon prefab est bien SecondaryWeapon.
ligne 29 : public GameObject _secondaryWeaponPrefab = null;
Qu'est ce que j'ai raté ?
Le 23 novembre 2016 à 17:56:23 Gef8 a écrit :
ligne 29 : public GameObject _secondaryWeaponPrefab = null;Qu'est ce que j'ai raté ?
La variable qui n'existe pas n'est pas celle cité, mais _isSecondaryWeapon.
Il me semble qu'on ne voit pas la ligne 29, donc cest dur de t'aider, et tu as changé la ligne 134...
Je te conseil de te renseigner sur la notion de "portée des variables". En gros, une variable déclarée dans une méthode n'est accessible que dans celle-ci, pas depuis d'autres variables.
Je met mon script ici:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
public float xMin, xMax, zMin, zMax;
}
public class PlayerController : MonoBehaviour
{
public float speed;
[SerializeField]
private float _dodgeSpeed = 0;
public float tilt;
public Boundary boundary;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
//variables du tir secondaire
public GameObject _secondaryWeaponPrefab = null;
private float nextFire;
[SerializeField]
private GameController _gameController = null;
private uint _score = 0;
private ushort _scoreMultiplier = 1;
// double tir
private bool _isDoubleShotsActive = false;
[SerializeField]
private float _doubleShotsXOffset = 0.25f;
[SerializeField]
private float _doubleShotsDelay = 5.0f;
private float _doubleShotsTimerEnd = 0.0f;
// tir en diagonal
private bool _isDiagonalShotsActive = false;
[SerializeField]
private float _diagonalShotsAngle = 45.0f;
[SerializeField]
private float _diagonalShotsDelay = 7.0f;
private float _diagonalShotsTimerEnd = 0.0f;
// doubleur de cadence de tir
private bool _isFireRateDoublerActive = false;
[SerializeField]
private float _fireRateDoublerDelay = 10.0f;
private float _fireRateDoublerTimerEnd = 0.0f;
private bool _horizontalAxisWasNotZeroLastTime = false;
private float _horizontalAxisLastPressTime = 0.0f;
[SerializeField]
private float _doublePressMaxDelay = 0.25f;
private ushort _doublePressStep = 0;
private bool _isDodging = false;
private float _dodgeStartTime = 0.0f;
[SerializeField]
private float _dodgeDuration = 0.5f;
private float _horizontalMovementAtDodgeStart = 0.0f;
private bool _lastHorizontalAxisWasLeft = false;
private Health _health = null;
void Start ()
{
_score = 0;
_scoreMultiplier = 1;
_health = GetComponent<Health>();
DesactivateDoubleShots();
DesactivateDiagonalShots();
DesactivateFireRateDoubler();
UpdateLivesText();
}
void Update ()
{
float now = Time.time;
float usedNextFire = nextFire + ((_isFireRateDoublerActive) ? (fireRate * -0.75f) : 0.0f);
if (Input.GetButton ("Fire1") && now > usedNextFire)
{
nextFire = now + fireRate;
if (_isDoubleShotsActive == false)
{
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
else
{
Instantiate(shot,
new Vector3(shotSpawn.position.x + _doubleShotsXOffset, shotSpawn.position.y, shotSpawn.position.z),
shotSpawn.rotation);
Instantiate(shot,
new Vector3(shotSpawn.position.x - _doubleShotsXOffset, shotSpawn.position.y, shotSpawn.position.z),
shotSpawn.rotation);
}
if (_isDiagonalShotsActive)
{
Instantiate(shot, shotSpawn.position, Quaternion.Euler(0.0f,_diagonalShotsAngle,0.0f));
Instantiate(shot, shotSpawn.position, Quaternion.Euler(0.0f,-_diagonalShotsAngle,0.0f));
}
GetComponent<AudioSource>().Play ();
}
if (Input.GetButton ("Fire2"))
{
// ici le click droit est appuyé
if (_secondaryWeaponPrefab == true)
{
Instantiate(_secondaryWeaponPrefab, _secondaryWeaponPrefab.position, _secondaryWeaponPrefab.rotation);
// et donc si mon arme secondaire n'est pas activée, je l'active
}
}
else
{
Instantiate (_secondaryWeaponPrefab == false);
// ici le click droit est relâché
// et donc si mon arme secondaire est activée, je la désactive
}
// timers des pickups
if ( _isDoubleShotsActive && now > _doubleShotsTimerEnd )
{
DesactivateDoubleShots();
}
if ( _isDiagonalShotsActive && now > _diagonalShotsTimerEnd )
{
DesactivateDiagonalShots();
}
if ( _isFireRateDoublerActive && now > _fireRateDoublerTimerEnd )
{
DesactivateFireRateDoubler();
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
// now est la date actuelle
float now = Time.fixedTime;
if (_isDodging)
{
// je suis en train d'equiver
if (now > _dodgeStartTime + _dodgeDuration)
{
// la data actuelle est supérieure à :
// la date de commencement de l'esquive + sa durée
// donc j'arrête d'esquiver
_isDodging = false;
_dodgeStartTime = 0.0f;
_horizontalMovementAtDodgeStart = 0.0f;
_doublePressStep = 0;
}
}
if (!_isDodging)
{
if (moveHorizontal != 0.0f && !_horizontalAxisWasNotZeroLastTime)
{
if (_doublePressStep == 1 && now <= _horizontalAxisLastPressTime + _doublePressMaxDelay)
{
if ((moveHorizontal <= 0 && _lastHorizontalAxisWasLeft) || (moveHorizontal > 0 && !_lastHorizontalAxisWasLeft))
{
_isDodging = true;
_dodgeStartTime = now;
_horizontalMovementAtDodgeStart = (moveHorizontal < 0) ? -1.0f : 1.0f;
_doublePressStep = 2;
}
else
{
_doublePressStep = 0;
}
}
_horizontalAxisLastPressTime = now;
if (_doublePressStep == 0)
{
_doublePressStep = 1;
}
}
}
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
float horizontalSpeed = _isDodging ? _horizontalMovementAtDodgeStart * _dodgeSpeed : movement.x * speed;
GetComponent<Rigidbody>().velocity = new Vector3(horizontalSpeed, 0.0f, movement.z * speed);
GetComponent<Rigidbody>().position = new Vector3
(
Mathf.Clamp (GetComponent<Rigidbody>().position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp (GetComponent<Rigidbody>().position.z, boundary.zMin, boundary.zMax)
);
GetComponent<Rigidbody> ().rotation = Quaternion.Euler (0.0f, 0.0f, GetComponent<Rigidbody> ().velocity.x * -tilt);
// ici j'enregistre des infos pour le futur
if (moveHorizontal != 0.0f)
{
_horizontalAxisWasNotZeroLastTime = true;
_lastHorizontalAxisWasLeft = moveHorizontal < 0 ? true : false;
}
else
{
_horizontalAxisWasNotZeroLastTime = false;
}
}
public void PostDamage()
{
_scoreMultiplier = 1;
UpdateLivesText();
}
private void UpdateLivesText()
{
if (_gameController != null)
{
_gameController.UpdateLivesText(_health.GetHealthPoint());
}
}
public void GetPickup(PickupType type)
{
switch (type)
{
case PickupType.None:
default:
Debug.LogWarning("GetPickup: pickup non géré " + type);
break;
case PickupType.Life:
_health.IncreaseHealth();
UpdateLivesText();
break;
case PickupType.ScoreMultiplier:
_scoreMultiplier *= 2;
break;
case PickupType.DoubleShots:
ActivateAndResetDoubleShots();
break;
case PickupType.DiagonalShots:
ActivateAndResetDiagonalShots();
break;
case PickupType.FireRateDoubler:
ActivateAndResetFireRateDoubler();
break;
}
}
public void AddScore (int newScoreValue)
{
_score += (uint) (newScoreValue * _scoreMultiplier);
if (_gameController != null)
{
_gameController.UpdateScoreText(_score);
}
}
private void ActivateAndResetDoubleShots()
{
_isDoubleShotsActive = true;
_doubleShotsTimerEnd = Time.time + _doubleShotsDelay;
}
private void DesactivateDoubleShots()
{
if (_isDoubleShotsActive)
{
_isDoubleShotsActive = false;
_doubleShotsTimerEnd = 0.0f;
}
}
private void ActivateAndResetDiagonalShots()
{
_isDiagonalShotsActive = true;
_diagonalShotsTimerEnd = Time.time + _diagonalShotsDelay;
}
private void DesactivateDiagonalShots()
{
if (_isDiagonalShotsActive)
{
_isDiagonalShotsActive = false;
_diagonalShotsTimerEnd = 0.0f;
}
}
private void ActivateAndResetFireRateDoubler()
{
_isFireRateDoublerActive = true;
_fireRateDoublerTimerEnd = Time.time + _fireRateDoublerDelay;
}
private void DesactivateFireRateDoubler()
{
if (_isFireRateDoublerActive)
{
_isFireRateDoublerActive = false;
_fireRateDoublerTimerEnd = 0.0f;
}
}
private void OnTriggerEnter(Collider other)
{
if ( other.tag == "NMYBolt" )
{
_health.TakeDamage();
UpdateLivesText();
Destroy(other.gameObject);
}
}
}
Du coup j'ai bien mis partout mon secondaryWeapon écrit pareil à chaque moment, toutefois il me dit ceci:
La première erreur :
GameObject ne contient pas d'accesseurs "position".
C'est le transform du GameObject qui connait la position de ce dernier !
Donc je te conseil d'écrire :
_secondaryWeaponPrefab.transform.position
Même erreur pour rotation, tu as compris le principe.
L'erreur 3 te dit que tu ne donnes pas de position / rotation, ce qui sera corrigé en corrigeant les erreurs précédentes.
Pour la dernière erreur, je comprends pas ce que tu essaies de faire :Instantiate (_secondaryWeaponPrefab == false);
Tu appelles instantiate pour "créer" un objet dans ta scène.
Si tu veux détruire un objet, tu as une méthode Destroy, si c'est ce que tu cherches à faire._secondaryWeaponPrefab == false
L'opérateur '==' est fait pour comparer deux choses. Là tu compares une arme à faux. Ça ne peut pas être comparé, c'est comme si je te demande de comparer une poule à une base de données, tu n'as rien en commun pour les comparer.
J'imagine que c'est gameobject.transform.position et pas gameobject.position, je n'ai pas le temps de lire ton code maintenant mais au vu du message ça semble probable
Bonjour Gef8,
Si j'en reviens à votre première demande, vous souhaitez donc ajouter la possibilité de sélectionner une arme différente par l'appui sur le bouton droit de la souris, le bouton gauche de la souris étant utilisé pour réaliser le tir de l'arme en cours.
En langage naturel cela revient à dire :
Si Fire2
Si Fire1
Tir Avec Arme2
Autrement Si Fire1
Tir Avec Arme1
Vous remarquerez déjà que l'algo de votre code actuel dans votre Update() ne respecte pas cette condition...
En fait de façon simplifié voici ce qu'il devrait être :
private void Update ()
{
float now = Time.time;
float usedNextFire = nextFire + ((_isFireRateDoublerActive) ? (fireRate * -0.75f) : 0.0f);
bool isFire = now > usedNextFire;
if (isFire)
nextFire = now + fireRate;
if (Input.GetButton ("Fire2"))
if Input.GetButton ("Fire1") && isFire )
Fire(_secondaryWeaponPrefab );
else if Input.GetButton ("Fire1") && isFire )
Fire(shot);
}
// Création du tir
private Fire(GameObject prefab)
{
... // Instanciation des différents prefab en fonction des modes de tir
// Par exemple pour un mode de tir simple
if (! _isDoubleShotsActive )
Instantiate(prefab, shotSpawn.position, shotSpawn.rotation);
}
Bien entendu cette approche de la méthode Fire() tient compte du fait que chaque arme fonctionne de la même façon.
Il existe aussi plein d'autres choses à mentionner sur votre écriture mais cela dépasse certainement le sujet.
J'ai noté que vous êtes novice, c'est un très bon début malgré tout.
Bonne continuation.
Comment on modifie la taille d'un sprite selon le "monde" (un sprite de 0.5 case de hauteur par exemple) ?
J'ai essayé de modifier le bound.size du spriterenderer (qui est ouvert a l'ecriture) mais il veut pas, ca bug
Re Gef8,
Après relecture du code donné à la volée, il me semble avoir fait une erreur en ce qui concerne la prise en compte du temps de répétition.
Voici donc la correction à vérifier.
Le code en est d'ailleurs plus simple.
private void Update ()
{
float now = Time.time;
float usedNextFire = nextFire + ((_isFireRateDoublerActive) ? (fireRate * -0.75f) : 0.0f);
bool isFire =(now > usedNextFire) && Input.GetButton ("Fire1");
if (isFire)
nextFire = now + fireRate;
if (Input.GetButton ("Fire2") && isFire)
Fire(_secondaryWeaponPrefab );
else if (isFire )
Fire(shot);
}
Toutes mes excuses.