- Home /
Bearded Multi-Headed Instantiation Dragoon Question
If I wanted to: (sorry for the complicated question)
instantiate a sphere prefab with a name, a random position, and a random size
instantiate a button for it on a scroll view
on click of set button, make my only camera look at the sphere prefab I just instantiated
while also on click, travel to the instantiated sphere prefab
and end up at the same transform of the previous object,relative to the new one
I have conquered instantiating the sphere prefab with its random specifications. I can currently add a button prefab with the same sphere prefab name to an existing scroll view by the use of a list, a sphere prefab class, and a button prefab class. I would like to add a generic function to satisfy requirement 3, 4, and 5 in my button prefab onClick so it is linked to the new sphere prefab I have just instantiated. To make this all the more complicated I am instantiating 1000 of these sphere prefabs in a 3D environment at run time.
public GameObject mainCamera;
public float transitionSpeed;
public float startTime = 1.0f;
//the newSphere is the instantiated sphere prefab
public void SphereButtonClick(GameObject newSphere)
{
Transform newSphereTrans = newSphere.transform;
Vector3 sphereToZoomToPos = newSphereTrans.position;
float sphereToZoomToX = sphereToZoomToPos.x;
float sphereToZoomToY = sphereToZoomToPos.y;
float sphereoZoomToZ = sphereToZoomToPos.z;
Transform mainCameraTrans = mainCamera.transform;
mainCameraTrans.SetParent(newSphereTrans);
mainCameraTrans.LookAt(newSphereTrans);
float lerpXValue = Mathf.Lerp(0, sphereToZoomToX, (Time.time - startTime) * transitionSpeed);
float lerpYValue = Mathf.Lerp(0, sphereToZoomToY, (Time.time - startTime) * transitionSpeed);
float lerpZValue = Mathf.Lerp(0, sphereToZoomToZ, (Time.time - startTime) * transitionSpeed);
mainCameraTrans.position = new Vector3(lerpXValue, lerpYValue, lerpZValue);
}
This is my camera movement function but I can't get it to work. I have attempted to slide it into the onClick of the button prefab as both a separate class and as a part of another but when I bring up the class the function does not exist. Is my function for onClick not allowed to take in a GameObject? If not, how would I take my instantiated sphere prefab game object (which has its own sphere prefab class) (and is also in a list that displays on the aforementioned scroll view) and link it to the main camera through an also instantiated button onClick?
My Sphere Prefab Class:
public class SpherePrefab : MonoBehaviour
{
public GameObject sphereInScene;
public Text SphereName;
}
And my Button prefab Class:
public class ButtonPrefab : MonoBehaviour {
public Button button;
public Text sphereName;
}
Answer by Sonky108 · Jul 30, 2018 at 07:01 AM
First of all we can start with SphereFactory (singleton): public void SphereFactory: MonoBehaviour { public event Action SphereCreatedListeners;
public void CreateNew()
{
//Create Vector3 random position
//Create Vector3 random size
var newObject = Instantiate(prefab, position);
newObject.transform.localScale = randomScale;
SphereCreatedListeners?.Invoke(newObject); //Assuming you are using C# 6.0
}
}
Next, we can create ButtonFactory (singleton):
public void ButtonFactory: MonoBehaviour
{
public event Action<GameObject> SphereClickedListeners;
void Start()
{
SphereFactory.Instance.SphereCreatedListeners += OnSphereCreated;
}
private void OnSphereCreated(GameObject sphere)
{
var newButton = Instantiate(prefab, gridLayout);
newButton.onClick.AddListener(() => SphereAction(sphere));
}
private void SphereAction(GameObject sphere)
{
SphereClickedListeners?.Invoke(sphere); //C# 6.0
}
void OnDestroy()
{
SphereFactory.Instance.SphereCreatedListeners -= OnSphereCreated;
}
}
Finally CameraController basend on your code:
public void CameraController: MonoBehaviour
{
private Transform target;
void Start()
{
ButtonFactory.Instance.SphereClickedListeners += OnSphereClicked;
}
private void OnSphereClicked(GameObject sphere)
{
target = sphere.transform;
}
private void NavigateTo(GameObject target)
{
Vector3 sphereToZoomToPos = target.position;
float sphereToZoomToX = sphereToZoomToPos.x;
float sphereToZoomToY = sphereToZoomToPos.y;
float sphereoZoomToZ = sphereToZoomToPos.z;
Transform mainCameraTrans = mainCamera.transform;
mainCameraTrans.SetParent(newSphereTrans);
mainCameraTrans.LookAt(newSphereTrans);
float lerpXValue = Mathf.Lerp(0, sphereToZoomToX, (Time.time - startTime) * transitionSpeed * time.deltaTime);
float lerpYValue = Mathf.Lerp(0, sphereToZoomToY, (Time.time - startTime) * transitionSpeed * time.deltaTime);
float lerpZValue = Mathf.Lerp(0, sphereToZoomToZ, (Time.time - startTime) * transitionSpeed * time.deltaTime);
mainCameraTrans.position = new Vector3(lerpXValue, lerpYValue, lerpZValue);
}
void Update()
{
if(target == null) return;
NavigateTo(target);
if(HasArrived())
{
target = null;
}
}
private bool HasArrived()
{
return target != null && (target.position - mainCamera.position).magnitude <= 0.1f;
}
void OnDestroy()
{
ButtonFactory.Instance.SphereClickedListeners -= OnSphereClicked;
}
}
I have missed some fields, methods and basic singleton pattern, but I hope you get the point :) I don't like idea of having sphere action in button factory (it should be defined in sphere script, like OnButtonClickAction).
Thanks for taking the time. I will try and adapt the code you presented to my purposes and get back to you. A lot of good information there. Thanks again!
I hope you don't $$anonymous$$d if I ask a few questions about your answer; this is completely new to me. What exactly do these lines do or mean?
SphereCreatedListeners?.Invoke(newObject); SphereClickedListeners?.Invoke(sphere);
I am fairly sure I am working with C# in Visual Studio 2017.
Your answer
Follow this Question
Related Questions
Bullet Prefab not instantiating 1 Answer
[SOLVED] Only instantiating once 1 Answer
Buttons not showing up the first time the menu loads, but showing up on all menu openings after 2 Answers
Button then instanitates gameobject 1 Answer
Instantiate object with button and place another object with mouse click 2 Answers