Script de récolte.

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
Nasatoe
Messages : 11
Inscription : 28 Déc 2015 01:26

Script de récolte.

Message par Nasatoe » 13 Juin 2016 14:18

Bonjour à tous !

J'essaie actuellement d'écrire un script de récolte de ressources. L'idée de mon script est simple: Si le joueur est proche d'un arbre alors il peut récolter. S'il s'éloigne la récolte s'interrompt et pendant tout le temps de la récolte un slider se rempli.
Voici mon code:

Code : Tout sélectionner

public class Bucheronnage : MonoBehaviour
{

    GameObject joueur;
    public ItemDatabase itemDataBase;
    public GameObject trunk;
    public GameObject sliderGO; //Pour afficher/Désaficher le slider
    public Slider slider;
    

    private float time = 0F;
    private float timer = 5F;
    private bool isDroping;
 
    // Use this for initialization
    void Start()
    {
       isDroping = false;
        joueur = GameObject.Find("Player");
        slider.value = 0;
        slider.enabled = false;
        sliderGO.SetActive(false);
    }

    // Update is called once per frame
    void Update()
    {
        if (getDistance() < 2.5F)
        {
           /* if (Input.GetKeyDown("b")) //Lance le droping
                isDroping = true;
            if (isDroping) // Drop en cours
            {*/
                sliderGO.SetActive(true);
                slider.enabled = true;
                time += 0.025F;
                slider.value = time * 100 / timer;
            //}            
        }        
        else // Joueur dans l'incapacité de drop. Au cas ou il s'éloigne pendant le drop.
        {
            isDroping = false;
            slider.value = 0;
            sliderGO.SetActive(false);
            isDroping = false;
        }
        if (slider.value == slider.maxValue) // Drop achevé
        {
            Destroy(gameObject);
            Instantiate(trunk, transform.position, transform.rotation); //instancie le tronc   
            sliderGO.SetActive(false);
            isDroping = false;
            slider.value = 0F;
            itemDataBase.SpawnItemStack(new ItemStack(itemDataBase.I<ItemWoodenLog>(), (int)Random.Range(1, 5)), new Vector3(transform.position.x + 2F,transform.position.y+1,transform.position.z + 2F)); //Instancie le drop à terre.
       }

    }
    float getDistance()
    {
        return Vector3.Distance(joueur.transform.position, transform.position);
    }

    void Filling()
    { }
        
}
Le souci c'est que le transform.position va récupérer les positions de tout les arbres qui portent le script donc il y en aura toujours un qui sera trop loin. Ce qui est drôle c'est que la valeur de mon slider va monter mais le slider ne s'affiche pas. Donc si j'attends le temps imparti, ma récolte se fait mais le slider ne se rempli / affiche pas.

Des idées pour faire en sorte de résoudre ce problème ?

Cordialement,
Nasatoe.
Dernière édition par Nasatoe le 14 Juin 2016 16:21, édité 1 fois.

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

Re: Trouver la distance minimale.

Message par boubouk50 » 13 Juin 2016 15:14

Ne serait-ce pas plus simple et plus judicieux de calculer la distance A PARTIR du joueur?
Dans ton explication, tous les arbres calculent la distance avec le joueur, même ceux qui sont trop loin -> Calculs inutiles.
Si c'est ton joueur qui calcule QUE les arbres à une certaine distance alors seulement ceux-ci seront actifs et calculés et donc récoltables. C'est à ton joueur de dire à tes arbres s'ils doivent calculer ou non, pas l'inverse.
"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

serial_mappeur
Messages : 11
Inscription : 06 Juin 2016 23:00

Re: Trouver la distance minimale.

Message par serial_mappeur » 13 Juin 2016 15:33

Salut,

Yep c'est pas bête ce que dit boubouk50.

Sinon si tu essayes de mettre une capsule collider qui sera l'enfant de ton joueur (avec is trigger activer).

Tu paramètres un truc du genre

Code : Tout sélectionner

void OnTriggerStay ()
	{
		et la tu entres tes conditions.
	}
Et une fois que ta capsule collider rentre en contacte avec un arbre, ça veux dire qu'il est a la bonne distance.

Mais je peux me tromper

Nasatoe
Messages : 11
Inscription : 28 Déc 2015 01:26

Re: Trouver la distance minimale.

Message par Nasatoe » 14 Juin 2016 04:21

Bonsoir !

Tout d'abord, merci de vos réponses.

@Serial_mappeur: Si je fais ça je reviens au même problème, il y aura toujours un collider avec lequel il n'y a pas d'intersection.. De plus j'ai essayé de mettre un attribut dans mon script afin de garder la position qui lui convenait mais Unity semble paralléliser ses calculs avec des Threads ce qui m'empêche d'utiliser mon astuce... :/

@Boubouk: Ton idée est intéressante, tu sais comment détecter si un préfab est présent dans une zone donnée ?

Cordialement,
Nasatoe.

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

Re: Trouver la distance minimale.

Message par boubouk50 » 14 Juin 2016 09:14

Nasatoe a écrit :@Serial_mappeur: Si je fais ça je reviens au même problème, il y aura toujours un collider avec lequel il n'y a pas d'intersection.
??? Je crois que t'as pas saisi l'idée.

C'est le but: limiter les collisions et les calculs et éviter de traiter une quantité d'infos inutiles. Avec les collisions, tu as les fonctions associées: OnTriggerEnter, OnTriggerStay, OnTriggerExit, OnCollisionEnter, OnCollisionStay, OnCollisionExit, qui te permettent de connaitre l'état de la collision avec les autres Colliders/Triggers, donc te permettent de gérer la récolte.

Ou alors je ne comprends pas tout? Quel est l'intérêt de s'informer sur un arbre s'il est trop loin?
"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

Arkas
Messages : 21
Inscription : 03 Juin 2016 16:51

Re: Trouver la distance minimale.

Message par Arkas » 14 Juin 2016 09:30

Salut ! Je suis aussi du même avis que Boubouk. L'utilisation de collider et de trigger semble appropriée.

Liens vers la doc : http://docs.unity3d.com/ScriptReference ... =ontrigger

Un exemple de code qui permettais de faire quelques chose de similaire à ce que tu souhaite obtenir :

Code : Tout sélectionner

 void OnTriggerEnter(Collider coll)
    {
        #region Point de Control
        //Stocke les informations sur le point de control et son proprietaire et indique que l'on est entrain de le capturer.
        if (coll.gameObject.tag == "Control")
        {
            isOnControlPoint = true;
            tmpZoneControl = coll.GetComponent<ZoneControler>(); //Mise en cache du point de control
            tmpZoneIdPlayerAuthority = tmpZoneControl.SyncIdPlayerAuthority;

            guiControler.SetTmpIdZone(tmpZoneIdPlayerAuthority);

            if (tmpZoneIdPlayerAuthority != netId.Value)
            {
                guiControler.InitTimerCast(timeToControl, 0.0f, "Capture"); //On lance un cast sur le GUI
            }
        }
        #endregion
        #region Arbre
        if (coll.gameObject.tag == "Arbre")
        {       
            tmpTree = coll.GetComponentInParent<Tree>();
           if (tmpTree.GetIdTree() == netId.Value) //Si le joueur possède la zone
            {
                guiControler.InitTimerCast(timeToCutWood, curTimeCutWood, "Couper"); //On lance la barre cast sur le GUI
                guiControler.SetWoodReward(10);
                treeOnTarget = true;
           }
        }
        #endregion
        #region Pierre
        if (coll.gameObject.tag == "Stone")
        {
            tmpStone = coll.GetComponentInParent<Stone>();
            if (tmpStone.GetIdStone() == netId.Value) //Si le joueur possède la zone
            {
                guiControler.InitTimerCast(timeToCutWood, curTimeCutStone, "Tailler"); //On lance la barre de cast sur le GUI
                guiControler.SetStoneReward(10);
                stoneOnTarget = true;
            }
        }
        #endregion
    }
Ce code est juste un exemple. Il y a du réseau, ce qui ne t'es pas utile vue que tu ne l'a pas mentionné. En revanche, tu peux voir que grâce au collision, on peux facilement détecter si le joueur est à porter d'un objet. C'est à toi de définir la zone couverte pas le collider.

La conditions qui vérifie si l'objet porte tel ou tel tag est hyper puissante. Avec ça tu peux tout faire ! (Savoir si le joueur nage, s'il est sur le sol, s'il reçoit un projectile, s'il peut utiliser un objet, s'il peut communiquer avec un PNJ, si un mob peut l'attaquer, etc )

Nasatoe
Messages : 11
Inscription : 28 Déc 2015 01:26

Re: Trouver la distance minimale.

Message par Nasatoe » 14 Juin 2016 16:20

Bonjour !

C'est moi qui avait mal saisis ton idée Boubouk50, désolé ^^

Encore merci pour vos réponses, le problème est (presque) résolu !
J'utilise des rayons que je vais envoyer à une certaine distance maximale devant moi pour détecter les intersections et le nom de l'intersection comme condition. sachant que mes arbres ont sur eux un script qui redéfini leur nom comme "Tree".

Sur des arbres que j'ai posé "main" tout marche parfaitement. Mais j'ai utilisé le pinceau de Unity pour une grande partie de ma map et lorsque mon rayon intersecte un de ces arbres, il me renvoie le nom "Terrain". Or si je détruit ce "Terrain" intercepté par le rayon.. cya mon terrain. Une idée pour pallier ce problème ? Est-ce que le fait que j'utilise GO.name et pas GO.tag peut poser des soucis ? A savoir que quand j'essayais d'utiliser .tag on me renvoyer "Untagged" et une erreur si j'essayais de les tager par script.

Merci du temps que vous m'accordez.
Cordialement,
Nasatoe.

EDIT: Je renomme le sujet afin qu'il colle mieux à mon problème.

Avatar de l’utilisateur
insecticide
Messages : 30
Inscription : 17 Jan 2012 16:55
Localisation : Belgique

Re: Script de récolte.

Message par insecticide » 20 Juin 2016 10:45

Si je ne dis pas de bêtise, les objets déposés via l'interface ne sont pas "Vivant", c'est pour cela que tu ne sais pas les détectés.
Ne me frappez pas, je suis novice ...

Répondre

Revenir vers « (C#) CSharp »