[DB-AL] Utilisation de "new" interdite par Unity [RESOLU]

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
micbost
Messages : 6
Inscription : 02 Août 2018 13:36

[DB-AL] Utilisation de "new" interdite par Unity [RESOLU]

Message par micbost » 02 Août 2018 14:50

Bonjour,

Depuis quelques jours, j'essaye de créer un jeu 2D sur Unity (plateforme/combat).
Pour utiliser divers bonus sur le temps (invincibilité, boost de puissance, pouvoirs etc...), j'utilise des timers. J'ai donc créé une classe Timer qui s'occupe de tout ça.
Dans cette classe, j'utilise le constructeur Timer suivant :

Code : Tout sélectionner

public Timer(float t) /* t>=0 */
{
        timeF = t;
        timeOut = (t==0);
        timerActive = false;
}
Autrement dit, mon Timer doit s'instancier avec un argument dans le constructeur (correspondant à une durée en secondes).

Voici donc mon problème : l'utilisation de "new" dans mon code Joueur (qui utilise la classe Timer) est refusée.
Voici la ligne en question :
public Timer timerBoost = new Timer(dureeBoost);
Qui affiche sur ma console :
You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all


J'ai regardé de nombreux forums et j'ai trouvé certaines solutions mais aucune ne correspond à ma situation :
Je ne peux pas enlever l'héritage à MonoBehaviour de ma classe Joueur.
Je ne peux pas non plus utiliser :
public Timer timerInvincible = gameObject.AddComponent<Timer>();
déjà parce que ça ne reconnaît pas gameObject mais aussi parce que ça marcherait pour un constructeur sans arguments, mais je dois placer dureeBoost en argument du constructeur Timer.

Voilà voilà, je ne sais pas si j'ai été très clair malgré mon très long post ^^' mais si vous pouviez répondre à ma question, ça serait vraiment très gentil de votre part :)
Dernière édition par micbost le 03 Août 2018 00:45, édité 1 fois.

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6222
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par boubouk50 » 02 Août 2018 14:58

Salut,
Es-tu bien sûr que ta class Timer doit hériter de Monobehaviour? C'est pas forcément utile.
Aussi, le classe Timer existe déjà, peut-être pourrais-tu utiliser celle-ci?
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par Autodidactelife » 02 Août 2018 15:31

Bonjour, comme dis plus haut l'erreur n'est pas le "new".
Tu nous montre une fonction et pas une classe dans ton message :/ (Timer.Timer() ?)
Timer est déjà pris comme dis plus haut il faut faire attention aux noms. Unity n'interdit rien, si tu utilises Visual Studio par exemple il n'est en rien lié avec Unity, il prend les class et les lits comme n'importe quel DLL ou script.

Dans un premier temps essaye de changer le nom de la class et de ta fonction d'entrée. C'est forcément pas loin l'erreur du new c'est toujours un soucis avec la class (une erreur dans la classe qui ici serait peut être le nom, souvent ça ne déclenche pas d'erreur mais ça peut l'afficher, même si dans les 2 cas ça ne marche pas ^^).

Cordialement
Dernière édition par Autodidactelife le 03 Août 2018 02:13, édité 1 fois.

micbost
Messages : 6
Inscription : 02 Août 2018 13:36

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par micbost » 02 Août 2018 17:13

Tout d'abord, merci de vos réponses (très rapides d'ailleurs), il se trouve que ma classe Timer n'avait pas besoin d'hériter de MonoBehaviour en effet (je pensais qu'il fallait l'enlever sur ma classe Joueur).
Si ce n'est pas trop demander, j'ai encore des problèmes avec les timers, voici ma classe TimerM au complet TimerM au complet (je l'ai appelé TimerM pour éviter la confusion avec Timer):

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimerM
{

/* timeF est le timer. timeI est son équivalent int (pour l'affichage UI). 
   timerActive permet d'activer ou désactiver le décompte du timer */
    
    public float timeF, memoryTimeF;
    public int timeI;
    public bool timerActive;

    public TimerM(float t) /* t>=0 */
    {
        timeF = t;
        memoryTimeF = t;
        timeI = (int)t;
        timerActive = false;
    }
	
	public void Update ()
    {
        if (timerActive)
        {
            timeF -= Time.deltaTime;
            if (timeF <= 0)
            {
                timerActive = false;
                timeF = memoryTimeF;
            }
            timeI = (int) timeF;
        }
    }

    public bool IsActive()
    {
        return timerActive;
    }

    public void LaunchTimer()
    {
        timerActive = true;
    }

    public void PauseTimer()
    {
        timerActive = false;
    }
}
L'idée est la suivante : j'initialise un timer inactif d'une certaine durée. J'active le timer grâce à LaunchTimer(), et celui-ci tombe à 0 via un décompte, et se remet automatiquement inactif à la durée initiale. La fonction IsActive() me rend donc false uniquement lors du décompte.

Et voici une partie de mon code Joueur :

Code : Tout sélectionner

bool isBoost = false; //passe à true dans l'utilisation de Boost(), et false à l'utilisation de Unboost()
public TimerM timerBoost = new TimerM(dureeBoost), timerCooldownBoost = new TimerM(dureecooldownBoost);
[...]
/* Boost */
        if (Input.GetKeyDown(KeyCode.C) && !isBoost && !timerCooldownBoost.IsActive())
        {
            Boost();
            timerBoost.LaunchTimer();
        }

        if (isBoost && !timerBoost.IsActive())
        {
            Unboost();
            timerCooldownBoost.LaunchTimer();
        }
En gros, l'idée est la suivante : j'ai une durée de boost et un cooldown (comme une capacité de jeu vidéo lambda).
Au début, mon timer de boost est "bloquée" à dureeBoost et le timer de cooldownBoost est bloqué à dureeCooldownBoost.
En appuyant sur C, je rentre dans le premier if, je reçois le boost et je débloque le timer de boost.
A la fin du timer de boost, celui-ci revient à sa durée initiale et est bloqué. timerBoost.isActive() devient false et je rentre donc dans le 2e if. Je perd donc le boost et je débloque le timer de cooldownBoost.
A la fin du timer de cooldownBoost, celui-ci revient à sa durée initiale et est bloqué. timerBoost.isActive() devient false et j'ai à nouveau accès au premier if (au moyen de la touche C).

Voilà, c'est sûrement pas très clair donc hésitez pas à demander des précisions. J'ai mis un peu de temps à répondre mais c'était pour expérimenter 2-3 trucs, là je répondrai plus vite ^^ et merci encore pour les débuts de réponses déjà apportés :)
.
 ! Message de : Max
Utilisez les balises code SVP
Merci de lire la Netiquette.

Avatar de l’utilisateur
Max
Messages : 8772
Inscription : 30 Juil 2011 13:57
Contact :

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par Max » 02 Août 2018 17:57

Bonsoir,
micbost a écrit :
02 Août 2018 17:13
Si ce n'est pas trop demander, j'ai encore des problèmes avec les timers, voici ma classe TimerM au complet
dans ton exposé des faits, du coup je n'ai pas trop compris quels était ces problèmes.
Dans ta classe TimerM, tu as une fonction Update, mais elle ne semble jamais appelée (du moins dans le morceau de code que tu fournis). Attention, qu'il n'y ai pas de confusion, ta classe ne dérivant pas de MonoBehaviour, c'est à toi de faire l'appel, genre timerBoost.Update(), sinon ton timer restera à sa valeur initiale.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

micbost
Messages : 6
Inscription : 02 Août 2018 13:36

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par micbost » 02 Août 2018 18:17

Désolé du double post, mais je pense avoir découvert d'où vient le problème (sans l'avoir pour autant résolu).

Après quelques test, j'ai découvert que la fonction Update() n'est pas appelé à chaque frame du jeu (comme c'est censé être le cas normalement). Je pense que c'est dû au fait que TimerM n'hérite pas de MonoBehaviour.
Mais en le faisant à nouveau hériter de MonoBehaviour, on retombe sur le problème initial : l'utilisation de new passe sur Visual Studio, mais pas sur Unity (qui m'affiche l'erreur que j'ai décrite plus haut).

micbost
Messages : 6
Inscription : 02 Août 2018 13:36

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par micbost » 02 Août 2018 18:28

Désolé, je n'avais pas vu le dernier message, mais la conclusion était bien la même ^^

Mais bon, j'ai finalement réussi grâce au dernier post qui m'a mis la puce à l'oreille : j'appelle la fonction Update (de TimerM) au début de la fonction Update (de Joueur). La deuxième étant automatique, elle rend la première automatique aussi.

Voilà, merci beaucoup pour votre précieuse aide :D

Avatar de l’utilisateur
Max
Messages : 8772
Inscription : 30 Juil 2011 13:57
Contact :

Re: [DB-AL] Utilisation de "new" interdite par Unity

Message par Max » 02 Août 2018 18:45

Si tu penses que c'est ok, passe le sujet en [RESOLU] (édition titre premier message)

Sinon, je pense que tu te prends un peu la tête avec ta classe TimerM, et de simples WaitForSeconds, feraient l'affaire ;)
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Autodidactelife
Messages : 47
Inscription : 21 Fév 2018 23:04
Localisation : France

Re: [DB-AL] Utilisation de "new" interdite par Unity [RESOLU]

Message par Autodidactelife » 03 Août 2018 02:05

Rooh, il à parler du waitforseconds avant moi :( (c'est le premier truc qui m'a sauter aux yeux en voyant le script ^^')

Très très utile le waitforseconds par exemple pour faire un timeout (si la personne fini pas le niveau dans X secondes il à perdu) ou encore un temps d'attente d'utilisation d'un objet ou d'un coup :)

Donc pour tes cooldown je te conseil un simple enum avec un waitforsecond et tu joue sur des bool ;)

Ex: le joueur lance le sort tu mets l'utilisation du sort en false, le waitforseconds le réactive et vla :3

Edit: Et visual studio ne détectait aucune erreur car simplement pour lui l'update était une fonction juste inutilisé dans le script actuel :)
Et Unity avait la même erreur que visual studio au départ c'est à dire une fonction prenant le nom de quelque chose existant :taré1:

Répondre

Revenir vers « (C#) CSharp »