【问题标题】:How can i move all the Spheres on the Terrain from it's original positions to new positions and back to the original in a loop?如何将地形上的所有球体从原始位置移动到新位置并循环返回原始位置?
【发布时间】:2016-08-30 08:55:36
【问题描述】:

我想要它做的是在编辑器和运行游戏时看到所有球体同时移动到另一个方向,或者它可能是相同的方向直到 endPoint 然后回到 startPoint循环不停。

这是我的脚本:

using System;
using UnityEngine;
using Random = UnityEngine.Random;

[ExecuteInEditMode]
public class SphereBuilder : MonoBehaviour
{
    // for tracking properties change
    private Vector3 _extents;
    private int _sphereCount;
    private float _sphereSize;

    /// <summary>
    ///     How far to place spheres randomly.
    /// </summary>
    public Vector3 Extents;

    /// <summary>
    ///     How many spheres wanted.
    /// </summary>
    public int SphereCount;

    public float SphereSize;

    private void OnValidate()
    {
        // prevent wrong values to be entered
        Extents = new Vector3(Mathf.Max(0.0f, Extents.x), Mathf.Max(0.0f, Extents.y), Mathf.Max(0.0f, Extents.z));
        SphereCount = Mathf.Max(0, SphereCount);
        SphereSize = Mathf.Max(0.0f, SphereSize);
    }

    private void Reset()
    {
        Extents = new Vector3(250.0f, 20.0f, 250.0f);
        SphereCount = 100;
        SphereSize = 20.0f;
    }

    private void Update()
    {
        UpdateSpheres();
    }

    private void UpdateSpheres()
    {
        if (Extents == _extents && SphereCount == _sphereCount && Mathf.Approximately(SphereSize, _sphereSize))
            return;

        // cleanup
        var spheres = GameObject.FindGameObjectsWithTag("Sphere");
        foreach (var t in spheres)
        {
            if (Application.isEditor)
            {
                DestroyImmediate (t);
            }
            else
            {
                Destroy(t);
            }
        }

        var withTag = GameObject.FindWithTag("Terrain");
        if (withTag == null)
            throw new InvalidOperationException("Terrain not found");

        for (var i = 0; i < SphereCount; i++)
        {
            var o = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            o.tag = "Sphere";
            o.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);

            // get random position
            var x = Random.Range(-Extents.x, Extents.x);
            var y = Extents.y; // sphere altitude relative to terrain below
            var z = Random.Range(-Extents.z, Extents.z);

            // now send a ray down terrain to adjust Y according terrain below
            var height = 10000.0f; // should be higher than highest terrain altitude
            var origin = new Vector3(x, height, z);
            var ray = new Ray(origin, Vector3.down);
            RaycastHit hit;
            var maxDistance = 20000.0f;
            var nameToLayer = LayerMask.NameToLayer("Terrain");
            var layerMask = 1 << nameToLayer;
            if (Physics.Raycast(ray, out hit, maxDistance, layerMask))
            {
                var distance = hit.distance;
                y = height - distance + y; // adjust
            }
            else
            {
                Debug.LogWarning("Terrain not hit, using default height !");
            }

            // place !
            o.transform.position = new Vector3(x, y, z);
        }

        _extents = Extents;
        _sphereCount = SphereCount;
        _sphereSize = SphereSize;
    }
}

更新

我创建了另一个 c# 脚本并将其拖到地形上。

using UnityEngine;
using System.Collections;

public class MoveSpheres : MonoBehaviour {

    public Transform _transform;
    private Vector3 pos1 = new Vector3(-4,0,0);
    private Vector3 pos2 = new Vector3(4,0,0);
    public float speed = 1.0f;
    // Use this for initialization
    void Start () {



    }

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

        _transform.position = Vector3.Lerp (pos1, pos2, Mathf.PingPong(Time.time*speed, 1.0f));


    }
}

这个脚本移动一个球体。但我想移动所有的球体。 而且,如果我在第一个脚本中更改球体的数量,然后移动它们也继续移动它们。

问题在于第一个脚本中的 Destroy 部分。

【问题讨论】:

  • 除了最初的问题之外,您还想消除一些代码异味:ExecuteInEditMode 真的有必要吗?当您可以添加公共变量时,为什么要搜索所有对象(甚至基于它们的根名称)?您可以获得所有对象变换而不是整个对象(也就是说,它几乎没有区别)。此外,您可能希望在对象上附加一个移动脚本,而不是在一个循环中进行所有转换(mono/unity 编译器对此进行了更好的优化 - 在一个 obj 的一次更新中,unity 似乎会出现循环时间很长的性能问题/跨度>

标签: c# unity3d unityscript unity5


【解决方案1】:

您可以将球体从一个位置移动到另一个位置并返回https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

【讨论】:

  • 它可以工作,但前提是我删除而不使用其他脚本中的破坏。破坏只是破坏球体并使其在新脚本中丢失变换。即使我添加了一个未连接到我的其他脚本的新游戏对象球体。
  • 好吧放松,我们可以解决这个问题!一次一件事,我希望你现在停止破坏球体。告诉我你想什么时候摧毁这个球体?移动时还是停止移动时?
  • 对不起。我只想在更改球体计数时销毁球体。例如,如果我将球体的数量更改为 1,则破坏其他球体并创建 1 个新球体。如果我设置然后 10 个球体破坏 1 并创建新的 10 个球体。这是 DestroyImmediate (t) 行;在我的脚本中做。但是我被告知要使用 Destroy 而不是 DestroyImmediate 但 Destroy 不会做出我想要的。
  • 更新了我的问题。从第一个脚本中删除了 MoveObjects 函数删除了 MoveObjects 并创建了一个新的 c# 脚本文件来进行移动。
  • 好吧,酷现在把移动脚本放在球体上,这样当创建球体时它会自行移动,现在要删除和创建新球体,创建一个名为球体的空游戏对象来删除所有球体使用 for循环使用 gameobject.ChildCount 删除或创建新球体并设置其父级,希望对您有所帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 2020-11-07
  • 2013-11-08
相关资源
最近更新 更多