I'm just starting out please excuse vast ignorance.
I'm writing a c# script in unity as part of the essentials training. I'm doing the 3d audio module and I thought I'd try and get a little bit fancier than the scope of this particular lesson which is supposed to be having an object fly through a window in a pre-built scene and make a 3d sound as it moves.
I wanted to make the movement of the object conditional upon a player moving close to it in 3d space. I figured out how to trigger the movement of an object in a script with an if statement that changes the transform parameters of the object the script is attached to when a 'distanceFromObject' variable is < 2. It works, however the script runs in the update section of the script which runs once every frame. This means that the object's transform parameters are changed every frame as expected but of course stops doing so when the distance between the object that's moving and the player exceeds 2.
I see the mistake I've made because if the object moves away when the player gets close then it will inevitably eventually move far enough away that the distanceFromObject variable will grow bigger than 2 whereupon it stops and just hovers in place. I don't know how to fix it though.
I need the script to check the distance between the object and the player every frame so that it will trigger the instance the player gets close enough, and when they get close enough, I need the object to move away, however once it has been triggered to move, I need the object to continue moving, but the script to stop checking what the distance is anymore.
The script looks like this
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlyOff : MonoBehaviour
{
public Vector3 rotateChange;
public Vector3 positionChange;
public float distanceFromObject;
public GameObject character;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
distanceFromObject = Vector3.Distance(character.transform.position, this.gameObject.transform.position);
print (distanceFromObject);
if (distanceFromObject < 2)
{
transform.Rotate (rotateChange);
transform.position += positionChange;
}
}
}
Use flags instead of writing your logic in the if statement :
public class FlyOff : MonoBehaviour
{
// fields removed for more readability
// use a flag that's set to true/false
private bool isCloseEnough = false;
void Update()
{
distanceFromObject = Vector3.Distance(character.transform.position, this.gameObject.transform.position);
print (distanceFromObject);
// set the flag to true when player is close enough
if (distanceFromObject < 2)
{
isCloseEnough = true;
}
// even if the player gets far, the flag will remain true
if (isCloseEnough)
{
transform.Rotate (rotateChange);
transform.position += positionChange;
}
}
}
You can even apply the opposite logic to stop the object to move away when it has reach a certain distance :
if (distanceFromObject < 2)
{
isCloseEnough = true;
}
else if (distanceFromObject > SomeValue)
{
isCloseEnough = false;
}
If I understand correctly you could just add a bool flag and set it once you are close enough. Then you can start moving and skip further distance checks but keep moving forever.
private bool flyAway;
void Update()
{
if(!flyAway)
{
distanceFromObject = Vector3.Distance(character.transform.position, transform.position);
print (distanceFromObject);
if (distanceFromObject < 2)
{
flyAway = true;
}
}
else
{
transform.Rotate (rotateChange);
transform.position += positionChange;
}
}
In general: Avoid using print every frame! Even if you user doesn't see the log in a built app it is still causing overhead!