如何在不更改位置的情况下向特定的楼梯组添加更多楼梯?

时间:2018-11-26 06:34:59

标签: c# unity3d

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

public class GenerateStairs: MonoBehaviour
{
    [Header("Stairs Prefb")]
    public GameObject stairsPrefab;
    [Space(5)]
    [Header("Platforms")]
    public bool addPlatforms = false;
    public GameObject platformsPrefab;
    [Space(5)]
    [Header("Settings")]
    [Range(0,5)]
    public float delay = 3;
    [Range(5,100)]
    public int stairsNumber = 5;
    public Vector3 stairsStartPosition;
    public Vector3 stairSize;
    public Vector3 stairsSize;
    public float stepWidthFactor = 1f;

    private Vector3 stairsPosition;
    private int oldStairsNumber;
    private MoveStairs moveObjects;

    // Use this for initialization
    void Start()
    {
        oldStairsNumber = stairsNumber;
        moveObjects = gameObject.GetComponent<MoveStairs>();
        StartCoroutine(BuildStairs(moveObjects));
    }

    // Update is called once per frame
    void Update()
    {
        if(oldStairsNumber < stairsNumber)
        {
            AddStairs();
        }

        oldStairsNumber = stairsNumber;
    }

    private IEnumerator BuildStairs(MoveStairs moveObjects)
    {
        for (int i = 1; i <= stairsNumber; i++)
        {
            stairsPosition = new Vector3(
                    stairsStartPosition.x,
                    stairsStartPosition.y + (i * stairsSize.y),
                    stairsStartPosition.z + (i * stairsSize.y) * stepWidthFactor);

            stairsPosition = stairsPosition + transform.localPosition;

            GameObject stair = Instantiate(
                    stairsPrefab,
                    stairsPosition,
                    Quaternion.identity);

            stair.name = "Stair";
            stair.tag = "Stair";
            stair.transform.parent = transform;
            stair.transform.localScale = stairSize;

            moveObjects.objectsToMove.Add(stair);

            yield return new WaitForSeconds(delay);
        }

        moveObjects.enabled = true;
        moveObjects.Init();
    }

    private void AddStairs()
    {
        for (int i = oldStairsNumber; i < stairsNumber; i++)
        {
            stairsPosition = new Vector3(
                stairsStartPosition.x,
            stairsStartPosition.y + (i * stairsSize.y),
            stairsStartPosition.z + (i * stairsSize.y) * stepWidthFactor);

            stairsPosition = stairsPosition + transform.localPosition;

            GameObject stair = Instantiate(
                    stairsPrefab,
                    stairsPosition,
                    Quaternion.identity);

            stair.name = "Stair";
            stair.tag = "Stair";
            stair.transform.parent = transform;
            stair.transform.localScale = stairSize;

            //moveObjects.objectsToMove.Add(stair);
            //moveObjects.Init();
        }
    }
}

如果我不使用两行moveObjects.objectsToMove.Add(stair);moveObjects.Init();,它将添加楼梯,但是新添加的楼梯将是静态的。但是,如果我使用这两行,新添加的楼梯也会移动,但也会更改整个楼梯的位置。

这是添加新楼梯后不使用这两行的屏幕截图:

Stairs static

在添加新楼梯后使用两行时的以下屏幕截图:

Stairs moving

现在,楼梯正在移动,但不在以前的位置上。 现在,楼梯的移动速度比其他楼梯快得多。 楼梯之间没有间隙,就像以前一样。我的意思是在楼梯0上出现间隙,如第一个屏幕截图所示。

这是移动楼梯的MoveStairs脚本:

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

public class MoveStairs : MonoBehaviour
{
    public List<GameObject> objectsToMove = new List<GameObject>();
    public AnimationCurve curve;
    public float stepsPerSecond = 1f;
    public bool changeDirection = false;

    private Vector3 trackStart;
    private Vector3 trackEnd;
    private Vector3 horizontalTravel;
    private float verticalTravel;
    private float divisor;
    private float phase = 0f;

    // Use this for initialization
    public void Init()
    {
        if (curve == null)
        {
            curve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
        }
        curve.preWrapMode = WrapMode.Clamp;
        curve.postWrapMode = WrapMode.Clamp;

        trackStart = objectsToMove[0].transform.localPosition;
        int count = objectsToMove.Count;
        var span = objectsToMove[count - 1].transform.localPosition - trackStart;

        divisor = 1f / count;
        horizontalTravel = (count + 1) * span * divisor;
        horizontalTravel.y = 0f;

        verticalTravel = span.y;
        trackEnd = trackStart + (count + 1) * span / count;
    }

    // Update is called once per frame
    void Update()
    {
        if (objectsToMove != null && objectsToMove.Count > 0 && curve != null)
        {
            AnimationCurve();
        }
    }

    private void AnimationCurve()
    {
        phase = Mathf.Repeat(phase + stepsPerSecond * divisor * Time.deltaTime, 1f);

        for (int i = 0; i < objectsToMove.Count; i++)
        {
            float t = Mathf.Repeat(phase + i * divisor, 1f);
            // Get the height of the curve at this step.
            float curveHeight = curve.Evaluate(t) * verticalTravel;

            if (changeDirection)
            {
                objectsToMove[i].transform.localPosition = trackStart                // First step
                                  - horizontalTravel * t      // evenly spaced horizontal
                                  + curveHeight * Vector3.up; // curving vertical
            }
            else
            {
                objectsToMove[i].transform.localPosition = trackStart                // First step
                                  + horizontalTravel * t      // evenly spaced horizontal
                                  + curveHeight * Vector3.up; // curving vertical
            }
        }
    }
}

主要目标是更改梯级数字值时游戏实时运行:向上或向下为特定的一组楼梯添加/销毁新楼梯。

public int stairsNumber = 5;

最后一个脚本是第一个脚本,它像楼梯0楼梯1楼梯2那样创建每个楼梯单位,每个单位都是预制件的复制品,该预制件已将两个脚本附加到GenerateStairs和MoveStairs上方:

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

public class GenerateStairsUnits : MonoBehaviour
{
    [Header("Stairs Units Prefab")]
    public GameObject stairsUnitsPrefab;
    [Space(5)]
    [Header("Settings")]
    [Range(1, 20)]
    public int numberOfUnits = 1;
    [Range(10, 100)]
    public int gap = 10;

    private int oldNumberOfUnits = 0;
    private List<GameObject> units = new List<GameObject>();
    private GameObject unitsParent;
    private GameObject Unit;

    // Use this for initialization
    void Start ()
    {
        oldNumberOfUnits = numberOfUnits;

        unitsParent = GameObject.Find("Stairs Units");
        for (int i = 0; i < numberOfUnits; i++)
        {
            Unit = Instantiate(stairsUnitsPrefab, unitsParent.transform);
            Unit.transform.localPosition = (i + 1f) * new Vector3(gap, 0, 0);
            Unit.name = "Stairs " + i.ToString();
            Unit.tag = "Unit";
            units.Add(Unit);
        }
    }

    private void Update()
    {

    }
}

0 个答案:

没有答案