Jump to content
UnitySpain
Sign in to follow this  
Abramelin

sistema de notas, combinar raycast y collision?

Recommended Posts

Estoy intentando modificar un sistema de notas de un tutorial para adaptarlo a tercera persona, lo que quiero hacer es sustituir el raycast solo cuando third este activo, por colision al tag "Note", o la funcion OnTriggerStay o OnCollisionStay... pero si con js me lio, con c# ya me resulta jodidisimo... Bueno esto es lo que tengo puesto en el player, he probado a aumentar el raycast en third (sin exito) y no se como sustituir el raycast por alguna de las funciones que he comentado. El script este seria el del player para ambos estados (fist y third), el de la nota ya lo tengo resuelto.

La funcion CheckForNote esta dividida en 2 partes:

en la parte if first ActiveSelf... no hay problema y se ve la nota al acercarte y pulsar el boton

en la parte if third ActiveSelf... es donde quiero sustituir el raycast por colision o por ontriggerenter, pero no se como hacerlo.

 

using UnityEngine;
using System.Collections;

public class PickupNote : MonoBehaviour {
	
	//Maximum Distance you Can Pick Up A Book
	public float maxDistance = 1.5F;
	public GameObject first;
	public GameObject third;
	//Your Custom GUI Skin with the Margins, Padding, Align, And Texture all up to you 
	private GUISkin mySkin;
	//Are we currently reading a note?
	private bool readingNote = false;
	//The text of the note we last read
	private string noteText;
	
	
	void Start () {
		//Start the input check loop
		StartCoroutine ( CheckForInput () );
	}
	
	private IEnumerator CheckForInput () {
		//Keep Updating
		while (true) {
		//If the 'E' was pressed and not reading a note check for a note, else stop reading
		if (Input.GetButtonDown("accion")) {
			if (!readingNote)
			CheckForNote ();
			else 
			readingNote = false;
			}	
			//Wait One Frame Before Continuing Loop
			yield return null;
		}
	}
	private void CheckForNote () {
		if (first.activeSelf == true) {
		//A ray from the center of the screen
		maxDistance = 2.3f;
		Ray ray = Camera.main.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0));
		RaycastHit data;
		//Did we hit something?
		if (Physics.Raycast (ray, out data, maxDistance)) {
		//Was the object we hit a note?
		if (data.transform.name == "Note") {
		//Get text of note, destroy the note, and set reading to true
		noteText = data.transform.GetComponent <Note> ().Text;
		mySkin = data.transform.GetComponent <Note> ().mycustomSkin;
		readingNote = true;
			}
			
		}
}
//HASTA AQUI TODO BIEN, ESTA ES LA PARTE DONDE EL RAYCAST PODRIA SUSTITUIRLO POR ONTRIGGERSTAY?¿QUE FUNCION SERIA MAS ADECUADA???
			if (third.activeSelf == true) {

			maxDistance = 5000f; //pense que aumentando la distancia leeria la nota 
			Ray ray = Camera.main.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0));
			RaycastHit data;
			
						
			if (Physics.Raycast (ray, out data, maxDistance)) {
				
								
			if (data.transform.name == "Note") {
					
										
			noteText = data.transform.GetComponent <Note> ().Text;
			mySkin = data.transform.GetComponent <Note> ().mycustomSkin;
					
			readingNote = true;
					
				}
				
			}
		}
}
		
// A PARTIR DE AQUI TODO BIEN	
	void OnGUI () {
		if (mySkin)
			GUI.skin = mySkin;
		//Are we reading a note? If so draw it.
		if (readingNote) {
			//Draw the note on screen, Set And Change the GUI Style To Make the Text Appear The Way you Like (Even on an image background like paper)
			GUI.Box (new Rect (Screen.width / 4F, Screen.height / 16F, Screen.width / 2F, Screen.height * 0.75F), noteText);
		}
	}
	
}

 

Edited by Abramelin

Share this post


Link to post
Share on other sites

Si quieres utilizar la funcion OnTriggerStay, utiliza una variable temporizador en el GameObject que muestra el mensaje:

Este sería el script que muestra el mensaje mediante una variable temporizador de 1 segundo o menos:

using UnityEngine;
using System.Collections;

public class ScriptMensaje : MonoBehaviour {

	[HideInInspector]
	public float tiempoMensaje = 0f;

	void Update(){

		if(this.tiempoMensaje > 0f) this.tiempoMensaje -= Time.deltaTime;

	}

	void OnGUI(){

		if(this.tiempoMensaje > 0f) GUILayout.Label("Mensaje");

	}

}

 

Y este sería el script del Player que activa el mensaje mediante el evento OnTriggerStay(debe tener el componente Rigidbody para activar dicho evento) asignando un valor de 1 segundo(puedes cambiarlo por uno menor) a la variable tiempoMensaje del ScriptMensaje:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]
public class ScriptPlayer : MonoBehaviour {

	void OnTriggerStay(Collider other) {

		ScriptMensaje script = other.GetComponent<ScriptMensaje>();
		if(script != null) script.tiempoMensaje = 1f;
		
	}

}

 

Share this post


Link to post
Share on other sites

La parte de la nota la tengo resuelta, y el codigo del player que he puesto funciona bien excepto la parte: if third activeself.... todo lo demas funciona bien. He intentado cambiar el raycast por OnTriggerStay pero me da errores, algo he puesto mal. Voy a poner solo la parte del codigo que me da problemas.

if (third.activeSelf == true) {
	Collider data;
	void OnTriggerStay(Collider other) {
				
			
		if (data.transform.name == "Note") {
					
										
		noteText = data.transform.GetComponent <Note> ().Text;
		mySkin = data.transform.GetComponent <Note> ().mycustomSkin;
					
		readingNote = true;			
		}			
	}
}

 

¿puede ser por usar la funcion OntriggerStay dentro de la funcion CheckForNote? (ver codigo inicial, la parte del raycast "if first active..." funciona perfectamente) ¿como podria ponerlo con collider? he usado tambien:

if(hit.collider.gameObject.tag == "Note")

... Tampoco se muy bien como declarar la variable data, porque creo que.como lo he puesto no es correcto. *En la parte del codigo "if first activeSelf..." data esta declarada como Raycast, he probado a declararla como Collider pero supongo que no tiene sentido.

 

Edited by Abramelin

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...