【问题标题】:Scale GameObject over time随着时间的推移缩放游戏对象
【发布时间】:2017-10-05 13:40:32
【问题描述】:

我制作了一个统一的测试游戏,所以当我点击一个按钮时,它会生成一个从工厂类创建的圆柱体。我正在努力做到这一点,所以当我创建圆柱体时,它的高度会在接下来的 20 秒内缩小。我发现的一些方法很难转化为我正在做的事情。如果您能引导我走向正确的方向,我将不胜感激。

这是我的圆柱体类代码

 public class Cylinder : Shape
{
    public Cylinder()
    {
    GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        cylinder.transform.position = new Vector3(3, 0, 0);
        cylinder.transform.localScale = new Vector3(1.0f, Random.Range(1, 2)-1*Time.deltaTime, 1.0f);

        cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
        Destroy(cylinder, 30.0f);
    }
}

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    这可以通过协程函数中的Time.deltaTimeVector3.Lerp 来完成。类似于Rotate GameObject over timeMove GameObject over time 问题。稍微修改一下就可以做到这一点。

    bool isScaling = false;
    
    IEnumerator scaleOverTime(Transform objectToScale, Vector3 toScale, float duration)
    {
        //Make sure there is only one instance of this function running
        if (isScaling)
        {
            yield break; ///exit if this is still running
        }
        isScaling = true;
    
        float counter = 0;
    
        //Get the current scale of the object to be moved
        Vector3 startScaleSize = objectToScale.localScale;
    
        while (counter < duration)
        {
            counter += Time.deltaTime;
            objectToScale.localScale = Vector3.Lerp(startScaleSize, toScale, counter / duration);
            yield return null;
        }
    
        isScaling = false;
    }
    

    用法

    将在 20 秒内缩放 GameObject:

    StartCoroutine(scaleOverTime(cylinder.transform, new Vector3(0, 0, 90), 20f));
    

    【讨论】:

    • Vector3 startScaleSize = objectToScale.position; 应该是Vector3 startScaleSize = objectToScale.localScale;
    • @TheSkimek 是的,没错。这是一个快速的港口。谢谢指正。
    【解决方案2】:

    查看Lerp。如何使用它的一般示例如下所示:

    float t = 0;
    Update()
    {
        t += Time.deltaTime;
        cylinder.localScale = new Vector3(1, Mathf.Lerp(2f, 1f, t/3f), 1); // shrink from 2 to 1 over 3 seconds;
    }
    

    【讨论】:

      【解决方案3】:

      您将创建一个新的单一行为脚本并将其添加到您的原语中。然后,您将使用单一行为的“更新”方法(或使用协程)随着时间的推移更改对象。

      单一行为必须是这样的:

      public class ShrinkBehaviour : MonoBehaviour
      {
          bool isNeedToShrink;
          Config currentConfig;
      
          float startTime;
          float totalDistance;
      
          public void StartShrink(Config config)
          {
              startTime = Time.time;
              currentConfig = config;
              totalDistance = Vector3.Distance(currentConfig.startSize, currentConfig.destinationSize);
              isNeedToShrink = true;
              transform.localScale = config.startSize;
          }
      
          private void Update()
          {
              if (isNeedToShrink)
              {
                  var nextSize = GetNextSize(currentConfig);
      
                  if (Vector3.Distance(nextSize, currentConfig.destinationSize) <= 0.05f)
                  {
                      isNeedToShrink = false;
                      return;
                  }
      
                  transform.localScale = nextSize;
              }
          }
      
          Vector3 GetNextSize(Config config)
          {
              float timeCovered = (Time.time - startTime) / config.duration;
              var result = Vector3.Lerp(config.startSize, config.destinationSize, timeCovered);
              return result;
          }
      
          public struct Config
          {
              public float duration;
              public Vector3 startSize;
              public Vector3 destinationSize;
          }
      }
      

      为了使用这个,你必须做下一步:

      public Cylinder()
      {
          GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
          var shrink = cylinder.AddComponent<ShrinkBehaviour>();
          shrink.StartShrink(new ShrinkBehaviour.Config() { startSize = Vector3.one * 10, destinationSize = Vector3.one * 1, duration = 20f });
          cylinder.transform.position = new Vector3(3, 0, 0);
      
          cylinder.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
          Destroy(cylinder, 30.0f);
      }
      

      您必须记住,monobehaviour-script 必须在单独的文件中,并且必须具有与 monobehaviour-class 名称相似的名称。例如,ShrinkBehaviour.cs;

      【讨论】:

      • 如果我只想缩小物体高度20秒怎么办?
      • 你没有声明速度的定义,你是从哪里得到速度的?
      • 我修好了。只需将速度替换为持续时间即可。
      • 我正在尝试,它只需要几秒钟就可以缩小到目标大小。
      • 已经修复了。你不需要压裂。尝试再复制一次:)
      猜你喜欢
      • 1970-01-01
      • 2016-10-01
      • 2013-01-20
      相关资源
      最近更新 更多