【问题标题】:How can I raise the walls smoothly and close them with coroutine?如何顺利升起墙壁并用协程关闭它们?
【发布时间】:2021-08-15 06:25:28
【问题描述】:
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);
                }
        }
    }
}

我在 RaiseWalls 方法中实例化 4 个角的墙壁预制件,并在该方法中根据 RaiseSpeed 我希望墙壁将每个墙壁缩放到两侧,并且当所有 4 个侧面的墙壁连接以停止缩放时。并不是说墙壁会相互缩放,只是为了完成一个正方形,也可能是为了让墙壁同时在 Y 轴上升起。但主要目标是用协程关闭墙壁。

到目前为止,我提供了这个解决方案。 它正在建造两堵墙,我仍然不确定如何在更新中控制建造速度。

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;
        }
    }
}

【问题讨论】:

  • 协程在这种情况下的性能较低(因为你真的只需要每帧移动一次墙壁,如果你移动它比每帧一次更平滑,播放器不会受益,因为图像,好吧,每帧只绘制一次,所以不要做协程,在Update/FixedUpdate中做),如果你对此很满意,我可以看看我是否能给你一个答案
  • @ChristophEckinger np 如果您能回答,请更新。
  • @ChristophEckinger 用我迄今为止的尝试更新了我的问题。

标签: c# unity3d


【解决方案1】:

为此,墙壁必须是立方体,长度必须是一个单位。墙壁是 a,b,c,d,排列顺序如下:

↑ b c
x a d
  z →

把这个放到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 
}

更高级的东西要花很长时间才能写出来,你很可能在这里得到答案。拿这个,玩弄它并学习更多。您需要编写更多代码,然后才能执行更高级的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-01
    • 2021-06-20
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多