- Home /
Uneven object Instantiation
I want to instantiate one cylinder in continuity with another cylinder at the end. In this manner, it follows a rate of continuous instantiation that will create a tunnel eventually (On the basis of what I imagined). Also, the tunnel will be moving in the back to the direction of instantiation (If there would be touch the tunnel should start moving and instantiating at the same time). See the code:
public class Tunnel : MonoBehaviour
{
public float speed = 3;
public Transform tunnel;
public Transform endTunnel;
// Start is called before the first frame update
private void Start()
{
InvokeRepeating("movetunnel", 0, 0.6f); // calls the movetunnel to instantiate cylinder in the end.
}
private void Update()
{
if (Input.touchCount > 0) // if players touches the screen.
{
tunnel.Translate(Vector3.down * Time.deltaTime * speed); // translates tunnel
//Transform clone = Instantiate(endTunnel, new Vector3(0.4f, 0.24f, 7.2f), endTunnel.rotation);
}
}
// Update is called once per frame
void movetunnel(){
if (Input.touchCount > 0) // if player touches the screen.
{
Transform clone = Instantiate(endTunnel, new Vector3(0.4f,0.24f,7.2f), endTunnel.rotation); // cylinder instantiation at the end of end cylinder.
clone.transform.parent = transform;
}
}
}
But this only resulted in the uneven instantiation. See the screenshot : Problem
For eg : if I touch and hold it instantiates desirably but if I touch after taking a pause of some seconds. It creates some gap between the end cylinder and the newly instantiated cylinder. Somebody, please help me :(
It's a little hard to understand what you are trying to do but it seems to me like you want to: 1 - $$anonymous$$ove all the tunnels when the user is touching the screen. 2 - Add new tunnel segments to the end as it is moving past . What seems a little strange is that you are not using the position of the previous tunnel to deter$$anonymous$$e if a new one has been created. It seems like you check every 0.6 seconds if the user is touching the screen and add the tunnel if so, regardless of where the other tunnels are.
So, I'm thinking that the real problem is that tunnels are instantiated on top of each other which leads to a gap for$$anonymous$$g when the next tunnel is created.
It would be better if you, in the Update() method check if the tunnel has moved down far enough for a new segment to be added. If you move the instantiation to the Update() method the Start() and movetunnel() methods can be removed.
You got it right. What I want to do is to make a chain of cylinders that are moving. I am trying to instantiate those cylinders and make perfect chains and move them everything by some ti$$anonymous$$g. Well, I got what you are saying I will move instantiation into update method (I was scared to do it before because I thought that it will be called at each frame which will make it more harder to control) but now I know what to do. You will take all credit for this if it runs perfectly.
You mentioned using the position of the previous tunnel. How can I get the previous tunnel segment transform ? as the previous tunnel segment updates after the instantiation of the new tunnel segment.
Ok, I got this, transform of newly instantiated tunnel segment will become the end tunnel transform.
Answer by Tomashu · Jul 01, 2019 at 07:11 PM
Ok, so from what I gather the following code is more or less what you want. Add the component to an empty game object that acts as the spawn point and attach your tunnel prefab to the Segment field of that object.
On start it will create the first segment at the spawn point (you can adjust the position and rotation to fit what you want). It also stores the height of the spawned object and the original spawn point, to use when adding more segments.
Each frame it will check if the user is touching the screen and move the parent object down. If the last segment added has moved more than its height a new segment is added. Note that this is supposed to be directly next to the previous but due to rounding issues there can be glitches - it could be a good idea to use a model that overlaps a little.
using UnityEngine;
public class Tunnel : MonoBehaviour
{
public float Speed = 2.0f;
public GameObject Segment;
private GameObject _lastSegment;
private Vector3 _origin;
private float _height;
void Start()
{
// Save the start position
_origin = transform.position;
// Create the first segment
_lastSegment = Instantiate(Segment, _origin, transform.rotation, transform);
// Save the height of the segment
_height = _lastSegment.GetComponent<Renderer>().bounds.size.y;
}
void Update()
{
if (Input.touchCount > 0)
{
// Move everything down if the user touches the screen
transform.Translate(Vector3.down * Time.deltaTime * Speed);
// If the last segment has fallen its own height then add a new segment
if (_origin.y - _lastSegment.transform.position.y >= _height)
{
var newPosition = _lastSegment.transform.position + new Vector3(0.0f, _height, 0.0f);
_lastSegment = Instantiate(Segment, newPosition, transform.rotation, transform);
}
}
}
}
However, I must add that this is not a very good solution. The stack of object will continue to grow indefinitely...
Your answer
![](https://koobas.hobune.stream/wayback/20220612204101im_/https://answers.unity.com/themes/thub/images/avi.jpg)