Avoir la position d'un GameObject

Pour les scripts écrits en Javascript (UnityScript). :!: Obsolète :!:
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
Skyxo234
Messages : 9
Inscription : 02 Juil 2017 09:19

Avoir la position d'un GameObject

Message par Skyxo234 » 28 Août 2017 10:11

Bonjour,
Je suis depuis quelques temps sur un projet et voudrais avoir la position de mon zombie (GameObject). Je sais que l'on peut avoir la position du Transform mais j'ai juste besoin du GameObject en lui même. Merci de votre aide.

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

Re: Avoir la position d'un GameObject

Message par boubouk50 » 28 Août 2017 11:20

Salut Skybox234,

Alors le transform est le Component de transformation d'un gameObject. Il contient sa position, rotation et scale. Si un gameObject n'en a pas, alors il n'a ni position, ni rotation, ni scale. Si tu veux la position du PIVOT d'un gameObject alors tu dois récupérer son transform.
Si tu veux une position centrale du Mesh, alors là, il te faut récupérer le centre de la bounding box: Renderer.bounds
"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

Skyxo234
Messages : 9
Inscription : 02 Juil 2017 09:19

Re: Avoir la position d'un GameObject

Message par Skyxo234 » 28 Août 2017 12:48

Ah oui désolé, j'ai oublié les détails :
-Mon GameObject contient un Transform
-Mon code pour récupérer la position du transform sur la map est :
Distance = Vector3.Distance(Target.position, transform.position);
Distance qui est une variable qui donne la distance entre le joueur et le zombie
Target qui est la variable transform.

Ce que je voudrais faire, c'est passer Target en GameObject et toujours avoir la position du Transform.
Voici mon script : http://www.mediafire.com/file/q8rxx83xyxdsvwo/Cut.js

Code : Tout sélectionner

#pragma strict

var dammage : int = 0;

var Distance : float;
var attackRange : float = 1.5;

var isValide : boolean = false;

private var zombieScript : ZombieHealth[];

function Start () {

}

function Update () {

var Target : GameObject[] = GameObject.FindGameObjectsWithTag("Ennemi");
Distance = Vector3.Distance(Target.position, transform.position);

	if(Distance <= attackRange){
		isValide = true;
			}else{
		isValide = false;
}

	if(Input.GetButton("Fire1")){
		GetComponent.<Animator>().Play("Cut", 0, 0);
			if(isValide == true){
				//zombieHealth.Health -= dammage;
				var EnnemiObj : GameObject[] = GameObject.FindGameObjectsWithTag("Ennemi");
				zombieScript = new ZombieHealth[ EnnemiObj.Length ];
				for( var i :int = 0 ; i < EnnemiObj.Length; ++i ){
				zombieScript[i] = EnnemiObj[i].GetComponent(ZombieHealth);
				zombieScript[i].Health -= dammage;
				}
			Debug.Log("Knife Attack");
		}
	}
}
Merci de votre aide ^^.

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

Re: Avoir la position d'un GameObject

Message par boubouk50 » 28 Août 2017 13:47

Allez, un peu de décorticage:

Code : Tout sélectionner

#pragma strict

var dammage : int = 0;

var Distance : float;
var attackRange : float = 1.5;

var isValide : boolean = false;

private var zombieScript : ZombieHealth[];

function Start () {

}

function Update () {

var Target : GameObject[] = GameObject.FindGameObjectsWithTag("Ennemi");
Distance = Vector3.Distance(Target.position, transform.position);

	if(Distance <= attackRange){
		isValide = true;
			}else{
		isValide = false;
}

	if(Input.GetButton("Fire1")){
		GetComponent.<Animator>().Play("Cut", 0, 0);
			if(isValide == true){
				//zombieHealth.Health -= dammage;
				var EnnemiObj : GameObject[] = GameObject.FindGameObjectsWithTag("Ennemi");
				zombieScript = new ZombieHealth[ EnnemiObj.Length ];
				for( var i :int = 0 ; i < EnnemiObj.Length; ++i ){
				zombieScript[i] = EnnemiObj[i].GetComponent(ZombieHealth);
				zombieScript[i].Health -= dammage;
				}
			Debug.Log("Knife Attack");
		}
	}
}
Ce code, s'il était fonctionnel, serait à catégoriser dans la section Méga Bourrin. (Sections allant de Ultra bourrin à très réfléchi).
Pourquoi? -> Parce qu'à chaque Update () il recommence tout (pas de stockage) et en plus il fait tout (pas d'utilisation des avantages de la POO).
Je ne vais donc pas corriger ton code en l'état (ce serait un peu comme te passer une bouée alors que tu es dans des sables mouvants) mais plutôt t'expliquer un peu l'importance de la POO (que je t'invite du coup à aller étudier sur OpenClassroom par exemple.)
Dans ton cas, l'architecture du code est mauvaise c'est à dire que tu centralises tout en récupérant tout. Un des intérêts de la POO est justement que chaque objet puisse agir de son côté. De plus, créer et gérer un ennemi te permettra que tous les clones de celui-ci fonctionnent également sur le même principe (un changement sur la source permet la modification de tous).
Donc ici, ce n'est pas au joueur d'aller chercher tous les ennemis et de vérifier toutes les distances avec eux pour ensuite retrouver le bon pour l'attaquer, mais bien à chaque ennemi d'envoyer l'unique information utile: JE suis dans ton champ d'action.
Donc il te faut un script pour tes ennemis qui calcule la distance avec le joueur et envoie au joueur l'info voulue: son GameObject/Son Script de vie/etc.
Ainsi, le joueur n'aura qu'à traiter ses informations là. Ton joueur va donc stocker les ennemis dans le champs d'action et si tu fais une attaque à ce moment là, seuls ceux-ci seront affectés.
Il faut voir la programmation de façon moins centralisée, plus autonome: Quel objet fait quoi/quand/comment? et de façon plus événementiel: chercher une information demande de constamment vérifier alors qu'attendre un événement ne coûte strictement rien.
"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

Skyxo234
Messages : 9
Inscription : 02 Juil 2017 09:19

Re: Avoir la position d'un GameObject

Message par Skyxo234 » 28 Août 2017 13:59

Merci de ta réponse, je me permet de te corriger :
A la base, c'est un script pour un couteau que tu as dans ta main, tu peux attaquer les ennemis, comme un vrai couteau quoi ^^'.
Donc quand tu dis "pour ensuite retrouver le bon pour l'attaquer" ce n'est pas qu'un seul Ennemi que je veux tuer mais pouvoir tous les toucher..
C'est moi qui fait le code, et pour vous dire, je ne connais pas encore tous au JavaScript et me considère entre Débutant et Intermédiaire. Alors je fais comme je peux ^^'.

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

Re: Avoir la position d'un GameObject

Message par boubouk50 » 28 Août 2017 14:43

Oui, j'avais bien saisi ton code, avec l'utilisation des tableaux. Ça ne change rien justement.
Les ennemis vont indiquer à ton personnage s'ils sont à distance ou non. Ton personnage va donc savoir lesquels seront affectés lors d'un coup de couteau. C'est une liste d'ennemis touchables que ton personnage aura.

Tu pourrais également utiliser un système de Collider pour trouver les ennemis à distance et envoyer les points de dégâts aux ennemis touchés.

Sinon, je peux te proposer une solution un peu plus dans ton approche. Au lieu de tester tous les ennemis à distance, seulement le tester au moment d'un coup de couteau, c'est à dire inverser la condition.
Je ne sais pas faire de listes en javascript (ni même pas grand chose) donc je vais te laisser le soin d'aller chercher par toi-même.

Code : Tout sélectionner

#pragma strict

var dammage : int = 0;
var attackRange : float = 1.5;
var enemyList : //trouver la syntaxe pour une liste de GameObject;

function Start () {

}

function Update () {

	if(Input.GetButton("Fire1")){
		//Jouer l'animation
		GetComponent.<Animator>().Play("Cut", 0, 0);
		//Trouver les ennemis
		EnemiesAtRange ();
		//Pour chacun des ennemis de la liste, enlever de la vie
		var ZombieHealth : zombieScript;
		for ( //trouver la syntaxe pour passer chaque objet de la liste ){
			//Ici il faudrait créer une fonction de dammage dans le script ZombieHealth plutôt que d'accéder à la variable
			zombieScript = Enemies[i].GetComponent(ZombieHealth);
			zombieScript.Health -= dammage;
		}
		Debug.Log("Knife Attack");
	}
}

function EnemiesAtRange () {
	var targets : GameObject[] = GameObject.FindGameObjectsWithTag("Ennemi"); //Ici tu dois tout le temps chercher les zombies, ce serait bien mieux que ce soit les ennemis qui t'envoie l'information.
	for (var i :int = 0 ; i < targets.Length; i++ ){ //pour chaque ennemi, traiter la distance
		if ( Vector3.Distance(targets [i].position, transform.position) <= attackRange ) {
			//Ici récupérer le target (gameObject) et l'ajouter à ta liste d'ennemis enemyList
		}
	}
}
"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

Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

Re: Avoir la position d'un GameObject

Message par ZJP » 28 Août 2017 15:54

A ajouter : un test sur l'angle de vue. L'ennemi doit être non seulement à la bonne distance, mais aussi dans le champ visuel du joueur. Voir. ( C'est du C#)

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: Avoir la position d'un GameObject

Message par evereal » 28 Août 2017 16:04

Hello,

Pour répondre a ta toute première question, il faut bien que tu comprennes que tout GameObject possède un composant Transform contenant entre autre les données de sa position. Si tu veux la position d'un GameObject, tu dois t'adresser directement à son Transform, le GameObject lui ne possède pas ces infos, il ne sait même pas ce qu'est une position ^^.

Deuxièmement,
Distance = Vector3.Distance(Target.position, transform.position);
Si je regarde ton code, Target est un TABLEAU de GameObject, il n'existe pas de méthode Distance qui prend un tableau et un vector3 en paramètre.
D'ailleur je ne comprend pas la suite de ton explication : "Ce que je voudrais faire, c'est passer Target en GameObject et toujours avoir la position du Transform."
Je suppose que tu veux pouvoir examiner chaque élément de ton tableau, une simple boucle suffit

Code : Tout sélectionner

for( var i :int = 0 ; i < Target.Length; ++i ){
	distance = Vector3.Distance(Target[i].transform.position, transform.position);
	// do smthng with distance
	...
}
Ensuite il y a des erreurs de logique dans ton code.
si je suis le comportement après avoir cliquer sur "Fire1" :
tu joues une animation
tu vérifies si... il y a au moins une cible à portée ?
tu récupéré TOUT les ennemis dans un tableau1
tu créées un tableau2 vide de meme taille que le tableau1
pour chaque element de ton tableau1
tu place le composant dans le tableau2
et tu utilise cette reference pour diminuer la vie

le tableau2 est vraiment de l'utilisation mémoire inutile et il n'y a pas de tri entre tes cibles "valides" ou non

Finalement, je vais rejoindre Boubouk et te conseiller d'apprendre les bases de la programmation sur openclassroom, tu as de bonnes idées dans ton code mais il te manque les concepts de bases et surtout la logique de programmation.

Je vais quand même te mettre une potentiel correction (en c#, plus facile pour moi). Ça devrai te donner une idée du résultat attendu pour ce genre de problème.
Il n'y a pas de calcul de distance, pour moi il faudrait un collider trigger sur ton joueur, et de la on édite une liste en fonction de ce qui rentre et ce qui sort de cette zone.
(code écrit sur notepad donc il y a surement des erreurs)

Code : Tout sélectionner

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class Joueur : MonoBehaviour {
	[SerializeField] private int damage = 0;
	
	private List<ZombieScript> allZombies;
	private List<ZombieScript> targetedZombies;
	
	void Start() {
		targetedZombies = new List<ZombieScript>();
	}
	
	void Update() {		
		// Si on appuie sur Fire1 et qu'on a au moins une cible dans notre liste, on attaque
		if (Input.GetButton("Fire1") && targetedZombies.Count > 0)
			Attack();
	}
	
	// On joue l'animation et on inflige des dégats a tout les zombies ciblés.
	void Attack() {
		GetComponent.<Animator>().Play("Cut", 0, 0);
		for (int i = 0; i<targetedZombies ; i++) {
			targetedZombies.receiveDamage(damage);
		}
	}

	// Méthode pour ajouter un zombie a notre liste de cible
	public void addZombie(ZombieScript zombie) {
		targetedZombies.add(zombie);
	}
	
	// Méthode pour retirer un zombie de notre liste de cible
	public void removeZombie(ZombieScript zombieRef) {
		for (int i = 0; i<targetedZombies ; i++)
			if (zombieRef == targetedZombies[i]) {
				targetedZombies.Remove(i);
				return;
			}
		}
		return;
	}
	
	// Si un zombie entre dans ma zone de frappe, je l'ajoute a ma liste de cible
	void OnTriggerEnter(Collider other) {
		if (other.tag == "Zombie")
			addZombie(other.gameObject.getComponent<ZombieScript>());
	}
	
	// Si un zombie sort de ma zone de frappe, je le retire de ma liste de cible
	void OnTriggerExit(Collider other) {
		if (other.tag == "Zombie")
			removeZombie(other.gameObject.getComponent<ZombieScript>());
	}
}

Code : Tout sélectionner

using UnityEngine;

public class Zombie : MonoBehaviour {
	[SerializeField] private Joueur myPlayer;
	[SerializeField] private float health = 50f;
	
	void Start() {
		if (myPlayer == null)
			myPlayer = GameObject.FindGameObjectsWithTag("Respawn")
	}
	
	// si je meurt, je ne fais plus partie des cibles du joueur.
	void onDeath() {
		myplayer.removeZombie(this);
		GameObject.Destroy(this.gameObject);
	}
	
	public void receiveDamage(float amount) {
		health -= amount;
		if (health <=0)
			onDeath();
	}
}
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Verrouillé

Revenir vers « (Js) Javascript »