【问题标题】:How to place spheres in a half circle shape between 2 points如何将球体放置在两点之间的半圆形中
【发布时间】:2019-06-24 13:51:10
【问题描述】:

我在两个给定点之间生成小球体。但是它总是以直线生成。球体是否可以开始生成从 A 点到 B 点的曲线?

我通过定义NumberOfSegments来定义两点之间应该生成多少个球体。

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

public class GeneratePoints : MonoBehaviour
{
    public Transform PointA; 
    public Transform PointB; 
    public float NumberOfSegments = 3; 
    public float AlongThePath = .25f;

    // Update is called once per frame
    void Start()
    {
       StartCoroutine(StartSpheringOut());
    }

    IEnumerator StartSpheringOut()
    {
        NumberOfSegments += 1;// since we are skipping 1st placement since its the same as starting point we increase the number by 1 
        AlongThePath = 1 / (NumberOfSegments);//% along the path

        for (int i = 1; i < NumberOfSegments; i++)
        {
            yield return new WaitForSeconds(0.05f);
            Vector3 CreatPosition = PointA.position + (PointB.position - PointA.position) * (AlongThePath * i);

            GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            sphere.transform.position = CreatPosition;
            sphere.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
        }
    }
}

【问题讨论】:

  • Define what a curve from Point A to Point B is ...有多种方法可以在数学上定义曲线(例如BezierNurbs),但我不知道任何仅基于2 个输入点 ...
  • @derHugo 是的,我认为没有贝塞尔曲线我无法生成曲线。如果说我想做没有贝塞尔曲线,那么假设 A 点和 B 点之间的距离是 2 米,所以我必须在它周围生成 5-10 个点,所以它看起来像一条曲线。
  • 所以你的意思是你创建一个半圆,中心位于 A 和 B 的中间?
  • @derHugo 是的

标签: c# unity3d


【解决方案1】:

这实际上几乎已经存在于Unity Manual

using UnityEngine;
public class CircleFormation : MonoBehaviour
{
   // Instantiates prefabs in a circle formation
   public GameObject prefab;
   public int numberOfObjects = 20;
   public float radius = 5f;

   void Start()
   {
       for (int i = 0; i < numberOfObjects; i++)
       {
           float angle = i * Mathf.PI * 2 / numberOfObjects;
           float x = Mathf.Cos(angle) * radius;
           float z = Mathf.Sin(angle) * radius;
           Vector3 pos = transform.position + new Vector3(x, 0, z);
           float angleDegrees = -angle*Mathf.Rad2Deg;
           Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
           Instantiate(prefab, pos, rot);
       }
   }
}

您可以将其用于初学者,然后根据您的需要对其进行调整,以使其正常工作。因此,由于您只想要圆的一半,您所要做的基本上就是将angle 除以2 并添加pointApointB 以计算中心位置。此外,如果两个位置不在同一个 XZ 平面上,则必须旋转整个圆:

public GameObject A;
public GameObject B;

public int amount;

[ContextMenu("PlaceSpheres()")]
privtae void DebugPlace()
{
    PlaceSpheres(A.transform.position, B.transform.position, amount);
}

public void PlaceSpheres(Vector3 posA, Vector3 posB, int numberOfObjects)
{
    // get circle center and radius
    var radius = Vector3.Distance(posA, posB) / 2f;
    var centerPos = (posA + posB) / 2f;

    // get a rotation that looks in the direction
    // posA -> posB
    var centerDirection = Quaternion.LookRotation((posB - posA).normalized);

    for (var i = 0; i < numberOfObjects; i++)
    {
        // Max angle is 180° (= Mathf.PI in rad) not 360° (= Mathf.PI * 2 in rad)
        //          |
        //          |    don't place the first object exactly on posA 
        //          |    but start already with an offset
        //          |    (remove the +1 if you want to start at posA instead)
        //          |               |
        //          |               |     don't place the last object on posB 
        //          |               |     but end one offset before
        //          |               |     (remove the +1 if you want to end 
        //          |               |     exactly a posB instead)
        //          |               |                       |
        //          V               V                       V
        var angle = Mathf.PI * (i + 1) / (numberOfObjects + 1f);
        var x = Mathf.Sin(angle) * radius;
        var z = Mathf.Cos(angle) * radius;
        var pos = new Vector3(x, 0, z);
        // Rotate the pos vector according to the centerDirection
        pos = centerDirection * pos;

        var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position = centerPos + pos;
        sphere.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
    }
}

【讨论】:

  • 我有一个查询,作为第 2 部分的问题。如何仅创建一个球体,该球体在此弧形位置从 A 点到 B 点以及从 B 点到 A 点循环运动?
  • @MohammedSaifSDK 这不再是您的问题范围!简而言之:与其实例化新对象,不如将位置存储在列表中,然后在该列表的点之间移动。
  • 谢谢,我会尝试这样做,如果我遇到困难,我会提出一个新问题。
猜你喜欢
  • 1970-01-01
  • 2017-09-12
  • 2018-10-31
  • 1970-01-01
  • 2019-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
相关资源
最近更新 更多