How can I raise the walls smoothly and close them with coroutine?

Viewed 49
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class PlaneSpawnObjects : MonoBehaviour
{
    public GameObject wallPrefab;
    public float raiseSpeed;
    public int sphereSize = 1;

    private List<Vector3> verticeList = new List<Vector3>();
    private List<Vector3> verticeListToShow = new List<Vector3>();
    private List<Color> CornerColors = new List<Color>() { Color.red, Color.blue, Color.yellow, Color.green };

    // Start is called before the first frame update
    void Start()
    {
        GetPlaneCornersPositions();

        StartCoroutine(RaiseWalls(raiseSpeed));
    }

    // Update is called once per frame
    void Update()
    {

    }

    public IEnumerator RaiseWalls(float RaiseSpeed)
    {
        for (int i = 0; i < verticeListToShow.Count; i++)
        {
            var wall = Instantiate(wallPrefab,
                new Vector3(verticeListToShow[i].x, verticeListToShow[i].y, verticeListToShow[i].z),
                Quaternion.identity);


            if (raiseSpeed > 0)
            {
                yield return new WaitForSeconds(RaiseSpeed);
            }
        }
    }

    private void GetPlaneCornersPositions()
    {
        verticeList= gameObject.GetComponent<MeshFilter>().sharedMesh.vertices.ToList();

        verticeListToShow.Add(transform.TransformPoint(verticeList[0]));
        verticeListToShow.Add(transform.TransformPoint(verticeList[10]));
        verticeListToShow.Add(transform.TransformPoint(verticeList[110]));
        verticeListToShow.Add(transform.TransformPoint(verticeList[120]));
    }

    private void OnDrawGizmos()
    {
        int b = 0;

        if (verticeList != null && verticeListToShow != null)
        {
            if (verticeList.Count > 0)
                for (int a = 0; a < verticeListToShow.Count; a++)
                {
                    Gizmos.color = CornerColors[b++];
                    Gizmos.DrawSphere(verticeListToShow[a], sphereSize);
                }
        }
    }
}

I Instantiate the walls prefab in the 4 corners in the RaiseWalls method and in that method depending on the RaiseSpeed I want the walls to scale each wall to both sides and when the walls on all 4 sides connected to stop the scaling. Not that the walls will scale into each other cut just to complete a square and maybe also to make the walls getting raise up on the Y at the same time. but the main goal is to close the walls with the coroutine.

I came with this solution so far . It's building two walls and I still not sure how to control the building speed in the Update.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Walls : MonoBehaviour
{
    public GameObject gameObjectToRaise;
    public float raiseAmount;
    public float raiseTotal = 50;
    public float speed = 2;
    public static bool raised = false;

    private List<GameObject> cubes;
    private GameObject go;

    public bool randomColor;
    public Color[] colorChoices;

    GameObject cube;
    GameObject cube1;

    // Use this for initialization

    void Start()
    {
        cube = CUBE.CreatePrimitive(CUBE.CubePivotPoint.UPLEFT);
        cube1 = CUBE.CreatePrimitive(CUBE.CubePivotPoint.UPRIGHT);
        cube1.transform.Rotate(0, 90, 0);
    }
    
    private void Update()
    {
        while (raiseAmount < raiseTotal)
        {
            raiseAmount += 1;
            cube.transform.localScale += new Vector3(raiseAmount, raiseAmount, 0);
            cube1.transform.localScale += new Vector3(raiseAmount, raiseAmount, 0);
        }
    }

    public class CUBE
    {
        public enum CubePivotPoint
        {
            MIDDLE, RIGHT, LEFT, UP, DOWN, FORWARD, BACK, UPLEFT,
            UPRIGHT, FORWARDUP, BACKUP
        }

        public static GameObject CreatePrimitive(CubePivotPoint pivot)
        {
            Vector3 cubePivot = createPivotPos(pivot);

            return createCubeWithPivotPoint(cubePivot);
        }

        public static GameObject CreatePrimitive(Vector3 pivot)
        {
            return createCubeWithPivotPoint(pivot);
        }

        private static Vector3 createPivotPos(CubePivotPoint pivot)
        {
            switch (pivot)
            {
                case CubePivotPoint.MIDDLE:
                    return new Vector3(0f, 0f, 0f);
                case CubePivotPoint.LEFT:
                    return new Vector3(0.5f, 0f, 0f);
                case CubePivotPoint.RIGHT:
                    return new Vector3(-0.5f, 0f, 0f);
                case CubePivotPoint.UP:
                    return new Vector3(0f, 0.5f, 0f);
                case CubePivotPoint.DOWN:
                    return new Vector3(0f, -0.5f, 0f);
                case CubePivotPoint.FORWARD:
                    return new Vector3(0f, 0f, 0.5f);
                case CubePivotPoint.BACK:
                    return new Vector3(0f, 0f, -0.5f);
                case CubePivotPoint.UPLEFT:
                    return new Vector3(0.5f, -0.5f, 0);
                case CubePivotPoint.UPRIGHT:
                    return new Vector3(-0.5f, -0.5f, 0);
                case CubePivotPoint.FORWARDUP:
                    return new Vector3(0.5f, -0.5f, -0.5f);
                case CubePivotPoint.BACKUP:
                    return new Vector3(0f, -0.5f, -0.5f);
                default:
                    return default(Vector3);
            }
        }

        private static GameObject createCubeWithPivotPoint(Vector3 pivot)
        {
            GameObject childCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            GameObject parentObject = new GameObject("CubeHolder");
            parentObject.transform.position = pivot;
            childCube.transform.SetParent(parentObject.transform);
            return parentObject;
        }
    }
}
1 Answers

For this to work, the walls have to be a cube and the length has to be one unit. The walls are a,b,c,d and ordered like this:

↑ b c
x a d
  z →

Put this in Update()

if (a.transform.scale < (b-a).magnitude + 0.2f)
{
    a.transform.scale.x += speed * time.deltaTime;
    a.transform.position.x += speed * time.deltaTime / 2 
}

if (b.transform.scale < (b-c).magnitude + 0.2f)
{
    b.transform.scale.z += speed * time.deltaTime;
    b.transform.position.z += speed * time.deltaTime / 2 
}

if (c.transform.scale < (d-c).magnitude + 0.2f)
{
    c.transform.scale.x += speed * time.deltaTime;
    c.transform.position.x -= speed * time.deltaTime / 2 
}

if (d.transform.scale < (d-a).magnitude + 0.2f)
{
    d.transform.scale.z += speed * time.deltaTime;
    d.transform.position.z -= speed * time.deltaTime / 2 
}

More advanced stuff takes way too long to write for you to be likely to get an answer here. Take this, play around with it and learn some more. You need to write quite a lot more code then you have to be able to perform more advanced stuff.

Related