Hi, I am making a sign that moves up and down above a player’s head while the player is in a zone that pops the sign over their head. My problem is that every time I try to get the sign to move in its local space, it keeps returning to the same position that I have specified in my Update() function - which is an offset from the player’s current position. What should I change/use in my code to make this happen?
Ok, I finally got it figured out. It feels like there has to be some better way to do this with Unity, but this is the only working way I figured out to get a sign bouncing over the player’s head as they moved around inside a zone.
This is the full source in case anyone else wants to figure out how to do something similar.
using UnityEngine;
using System.Collections;
public class TriggerForest : MonoBehaviour {
//private variables
private bool playerInBounds;
private bool bCreated;
private GameObject signObj; //displays the text
private GameObject floatTextObj; //displays instructions to interact
private static float initDuration = 0.8f; //controls duration that sign moves in a direction until switching
private static float duration = initDuration;
private static float speed = 0.5f; //controls speed that sign moves
private Vector3 move = new Vector3(0.0f, 0.0f, 0.5f); //controls direction that sign moves in
private bool bDone = false;
//public variables
public GameObject player;
public GameObject playerPosition; //always center on the player
public GameObject forestSign;
public GameObject floatText;
public Vector3 signOffset = new Vector3(0.0f, 0.5f, 3.0f); //set the default offset for displaying sign above player
public Vector3 fTextOffset = new Vector3(0.0f, 0.5f, -1.5f);
// Use this for initialization
void Start () {
}
//check if player is insider trigger
void OnTriggerEnter(Collider other) {
if (other.gameObject.tag == "Player") {
playerInBounds = true;
//Debug.Log(playerInBounds); //test
Debug.Log ("Entering forest.");
}
}
void OnTriggerExit(Collider other) {
if (other.gameObject.tag == "Player") {
playerInBounds = false;
//Destroy (other.gameObject); //test
Debug.Log ("Leaving forest.");
}
}
// Update is called once per frame
void Update () {
//alternative way to reference player
//var player = GameObject.FindWithTag("Player");
if (playerInBounds) {
//check if user pressed the key to enter level (using e for now)
//GetKeyDown occurs only once per press, compared to GetKey which continues to occur as long as button is pressed
if(Input.GetKeyDown(KeyCode.E)) {
//reference documentation for the line below: http://docs.unity3d.com/ScriptReference/Application.LoadLevel.html
//switch the scene to forest level
Application.LoadLevel("testSceneLoad");
}
//ensures we do not continue making objects; also init run once things for sign here
if(!bCreated) {
//create objects from prefabs
signObj = (GameObject) Instantiate(forestSign, transform.position, transform.rotation);
floatTextObj = (GameObject) Instantiate(floatText, transform.position, transform.rotation);
//set the intial position of sign
signObj.transform.position = player.transform.position + signOffset;
//parent the sign to the player's position; this updates its position automatically
signObj.transform.parent = playerPosition.transform;
bCreated = true;
}
/* THE SIGN */
//update position of sign
//moves sign down
if(!bDone) {
if(duration > 0.0f) {
signObj.transform.Translate(move * speed * Time.deltaTime, Space.Self);
duration -= Time.deltaTime;
if(duration <= 0.001f) {
duration = initDuration;
bDone = true;
}
}
}
//moves sign up
if(bDone) {
if(duration > 0.0f) {
signObj.transform.Translate(-move * speed * Time.deltaTime, Space.Self);
duration -= Time.deltaTime;
if(duration <= 0.001f) {
duration = initDuration;
bDone = false;
}
}
}
//update rotation of sign
var newRot = transform.rotation.eulerAngles;
newRot.x = 0.0f; newRot.y = 180.0f; newRot.z = 0.0f;
signObj.transform.rotation = Quaternion.Euler(newRot); //this sits the sign upright
/* THE FLOATING TEXT */
//update position of floating text
floatTextObj.transform.position = player.transform.position + fTextOffset;
//update rotation of floating text
var newRot2 = transform.rotation.eulerAngles;
newRot2.x = 90.0f; newRot2.y = 0.0f; newRot2.z = 0.0f;
floatTextObj.transform.rotation = Quaternion.Euler(newRot2); //this sits the text upright
}
else {
Destroy(signObj);
Destroy (floatTextObj);
bCreated = false;
}
}
}
Is there a reason your not just parenting it to your player?
– Fanttum