création de battiment basée sur systeme de grille

Questions à propos du scripting. Hors Shader, GUI, Audio et Mobile.
Avatar de l’utilisateur
mel68
Messages : 827
Inscription : 04 Fév 2012 14:57

création de battiment basée sur systeme de grille

Message par mel68 » 12 Oct 2014 11:13

Salut, voila, ce que je cherche a faire est dans le titre ^^, j'ai bien avancé et la base est presque finit, mais je me hurte a 2 problèmes :

bon dabord voilà les scripts :

grid Manager :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class gridManager : MonoBehaviour {
	public bool isBuilding = false;

	void Update () {

		if(isBuilding == true)
		{
			gameObject.renderer.enabled = true;
		}

		else
			gameObject.renderer.enabled = false;

		if(Input.GetKeyDown(KeyCode.B) && isBuilding == false)
		{
			isBuilding = true;
		}

		else if(Input.GetKeyDown(KeyCode.B) && isBuilding == true)
		{
			isBuilding = false;
		}
	
	}
}
buildingPlacement :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class buildingPlacement : MonoBehaviour {

	public GameObject placingCase;
	gridManager grid;

	GameObject oldCase = null;
	GameObject currentCase = null;

	public GameObject building;
	public Transform buildingInstance;

	public LayerMask layer = -1;

	void Start()
	{
		grid = GetComponent<gridManager>();

		for(int x = 0; x <= 100; x += 4)
		{
			for(int z = 0; z <= 100; z += 4)
			{
				Instantiate(placingCase, new Vector3(x, 0.5f, z), Quaternion.Euler(90, 0, 0));
			}
		}
	}

	void Update()
	{

		RaycastHit hit;
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

		if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer))
		{

			if(oldCase != null)
				oldCase.renderer.material.color = Color.green;

			currentCase = hit.transform.gameObject;

			currentCase.renderer.material.color = Color.red;
			oldCase = currentCase;
		}

		if(Input.GetKeyDown(KeyCode.B))
		{
			buildingInstance = ((GameObject)Instantiate(buildingInstance)).transform;
		}

		if(grid.isBuilding == true)
		{
			buildingInstance.position = currentCase.transform.position;
		}

		else if(grid.isBuilding == false && buildingInstance != null)
			Destroy (buildingInstance);
	}

}

et voilà mes 2 erreurs :
NullReferenceException: Object reference not set to an instance of an object
buildingPlacement.Update () (at Assets/scripts/buildingPlacement.cs:53)
qui correspond a cette ligne :

Code : Tout sélectionner

if(grid.isBuilding == true)
		{
			buildingInstance.position = currentCase.transform.position;
		}
et la seconde erreur :
InvalidCastException: Cannot cast from source type to destination type.
buildingPlacement.Update () (at Assets/scripts/buildingPlacement.cs:50)
qui correspond a cette ligne :

Code : Tout sélectionner

buildingInstance = ((GameObject)Instantiate(buildingInstance)).transform;
la premiere erreur il doit y avoir un probleme de référence quelque part mais je ne comprend pas ou :roll: , j'ai tjrs fait comme ça pour les GetComponents

Ensuite pour la deuxieme erreur je ne comprend pas, j'ai meme vérifier dans un tuto, et le gars mettait exactement la meme ligne pour instancier son objet...

https://www.youtube.com/watch?v=OuqThz4Zc9c (a la minute 12.37)

voilà, pas grand chose d'autre a rajouter je croit ^^, si besoin est demandez moi.

Merci d'avance :)
Bonjour bonjour, je tien juste a vous avertir promptement que ce message ne sert totalement a rien

Avatar de l’utilisateur
artemisart
Messages : 1893
Inscription : 21 Juin 2011 19:51
Localisation : Centre
Contact :

Re: création de battiment basée sur systeme de grille

Message par artemisart » 12 Oct 2014 11:45

Salut,

Dans tes variables remplace Transform buildingInstance par GameObject buildingInstance (au fait buildingInstance = Instantiate (buildingInstance) c'est un peu strange mais pourquoi pas, souvent on a 2 variables séparés, une pour les instances et une autre pour le prefab/GO de base).
Pour la nullref, buildingInstance ou currentCase ne sont pas assignés.

Avatar de l’utilisateur
mel68
Messages : 827
Inscription : 04 Fév 2012 14:57

Re: création de battiment basée sur systeme de grille

Message par mel68 » 12 Oct 2014 12:17

Merci de tes réponses, du coup j'ai essayer ce que tu m'a dit :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class buildingPlacement : MonoBehaviour {

	public GameObject placingCase;
	gridManager grid;

	GameObject oldCase = null;
	GameObject currentCase = null;

	public GameObject building;
	public GameObject holoBuild;
	GameObject buildingInstance;

	public LayerMask layer = -1;

	void Start()
	{
		grid = GetComponent<gridManager>();

		for(int x = 0; x <= 100; x += 4)
		{
			for(int z = 0; z <= 100; z += 4)
			{
				Instantiate(placingCase, new Vector3(x, 0.5f, z), Quaternion.Euler(90, 0, 0));
			}
		}
	}

	void Update()
	{

		RaycastHit hit;
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

		if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer))
		{

			if(oldCase != null)
				oldCase.renderer.material.color = Color.green;

			currentCase = hit.transform.gameObject;

			currentCase.renderer.material.color = Color.red;
			oldCase = currentCase;
		}

		if(Input.GetKeyDown(KeyCode.B))
		{
			buildingInstance = Instantiate(holoBuild, currentCase.transform.position, Quaternion.identity);
		}

		if(grid.isBuilding == true)
		{
			buildingInstance.transform.position = currentCase.transform.position;
		}

		else if(grid.isBuilding == false && buildingInstance != null)
			Destroy (buildingInstance);
	}

}
en fait j'avait déja essayer comme ça, avec la variable en GameObject, et j'avait cette erreur :
Assets/scripts/buildingPlacement.cs(51,25): error CS0266: Cannot implicitly convert type `UnityEngine.Object' to `UnityEngine.GameObject'. An explicit conversion exists (are you missing a cast?)

et là ca me refait la meme, sur la doc du Instantiate c'est pareil, ils utilisent que des Transforms ou des Rigidbody, mais pas de GameObject :/
Bonjour bonjour, je tien juste a vous avertir promptement que ce message ne sert totalement a rien

Avatar de l’utilisateur
artemisart
Messages : 1893
Inscription : 21 Juin 2011 19:51
Localisation : Centre
Contact :

Re: création de battiment basée sur systeme de grille

Message par artemisart » 12 Oct 2014 14:54

Il faut toujours que tu cast en fait, avec (GameObject)Instantiate... ou Instantiate... as GameObject (en attendant le jour où UT implémentera tout avec des génériques ^^).

Avatar de l’utilisateur
mel68
Messages : 827
Inscription : 04 Fév 2012 14:57

Re: création de battiment basée sur systeme de grille

Message par mel68 » 12 Oct 2014 15:42

haaaa daccord, merci ^^

bon, ca progresse, mtn quand j'appuie sur B ma grid apparait et mon batiment suit ma sourit sur la grid, mais, quand je rappui sur B pour faire disparaitre la gride, mon batiment s'instancie a l'endroit de ma sourit, et un autre apparait et suit ma sourit, alors que ma grid disparait bien.. et j'ai toujours cette fameuse erreur null référence exeption, alors que toutes mes variables sont bien remplies ><

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class buildingPlacement : MonoBehaviour {

	public GameObject placingCase;
	gridManager grid;

	GameObject oldCase = null;
	GameObject currentCase = null;

	public GameObject building;
	public GameObject holoBuild;
	GameObject buildingInstance;

	public LayerMask layer = -1;

	void Start()
	{
		grid = GetComponent<gridManager>();

		for(int x = 0; x <= 100; x += 4)
		{
			for(int z = 0; z <= 100; z += 4)
			{
				Instantiate(placingCase, new Vector3(x, 0.5f, z), Quaternion.Euler(90, 0, 0));
			}
		}
	}

	void Update()
	{

		RaycastHit hit;
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

		if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer))
		{

			if(oldCase != null)
				oldCase.renderer.material.color = Color.green;

			currentCase = hit.transform.gameObject;

			currentCase.renderer.material.color = Color.red;
			oldCase = currentCase;
		}

		if(Input.GetKeyDown(KeyCode.B))
		{
			buildingInstance = ((GameObject)Instantiate(holoBuild, currentCase.transform.position, Quaternion.identity));
		}

			buildingInstance.transform.position = currentCase.transform.position;

		if(buildingInstance && grid.isBuilding == false)
		{
			Destroy(buildingInstance);
		}

	}

}
Bonjour bonjour, je tien juste a vous avertir promptement que ce message ne sert totalement a rien

Avatar de l’utilisateur
mel68
Messages : 827
Inscription : 04 Fév 2012 14:57

Re: création de battiment basée sur systeme de grille

Message par mel68 » 14 Oct 2014 20:13

Je me permet de Up parce que j'ai fait quelques progrès, mais il reste toujours des problèmes que je ne comprend pas..

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class buildingPlacement : MonoBehaviour {

	public GameObject placingCase;
	gridManager grid;

	GameObject oldCase = null;
	GameObject currentCase = null;

	public GameObject building;
	public GameObject holoBuild;
	GameObject buildingInstance;

	public LayerMask layer = -1;

	void Start()
	{
		grid = placingCase.GetComponent<gridManager>();

		for(int x = 0; x <= 100; x += 4)
		{
			for(int z = 0; z <= 100; z += 4)
			{
				Instantiate(placingCase, new Vector3(x, 0.5f, z), Quaternion.Euler(90, 0, 0));
			}
		}
	}

	void Update()
	{

		print(grid.isBuilding);

		RaycastHit hit;
		Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

		if(Physics.Raycast(ray, out hit, Mathf.Infinity, layer))
		{

			if(oldCase != null)
				oldCase.renderer.material.color = Color.green;

			currentCase = hit.transform.gameObject;

			currentCase.renderer.material.color = Color.red;
			oldCase = currentCase;
		}

		if(Input.GetKeyDown(KeyCode.B) && grid.isBuilding == true)
		{
			grid.isBuilding = false;
			buildingInstance = ((GameObject)Instantiate(holoBuild, currentCase.transform.position, Quaternion.identity));
		}

		if(Input.GetKeyDown(KeyCode.B) && grid.isBuilding == false)
			grid.isBuilding = true;

		if(buildingInstance)
			buildingInstance.transform.position = currentCase.transform.position;

		if(buildingInstance && grid.isBuilding == false)
		{
			Destroy(buildingInstance);
		}

	}

}
gridManager.cs :

Code : Tout sélectionner

using UnityEngine;
using System.Collections;

public class gridManager : MonoBehaviour {
	public bool isBuilding = false;

	void Start()
	{
		isBuilding = false;
	}

	void Update () {

		if(isBuilding == true)
		{
			gameObject.renderer.enabled = true;
		}

		else
			gameObject.renderer.enabled = false;
	
	}
}

bon, le bon points c'est que j'ai plus une seule erreur.

Par contre ca ne marche pas exactement comme je le voudrait.. je m'explique :

Quand je start, isBuilding est bien a false, ça pas de probs, mais, quand je press b , mon Instantiate marche tres bien, mais isBuilding ne passe pas a true, et quand je continue d'appuyer sur b, mes buildingInstances reste a leur position et un nouveau apparait et suit ma sourit, je doit avouer que je suit perdu, tout me semble pourtant correct..


merci d'avance
Bonjour bonjour, je tien juste a vous avertir promptement que ce message ne sert totalement a rien

Répondre

Revenir vers « Scripting »