Я хочу создать спиральное движение объекта в C# для Unity - PullRequest
0 голосов
/ 28 мая 2020

Я создал сценарий C# для определения спирального движения объекта на плоскости в 3D.

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

public class spiralanti : MonoBehaviour
{
    float angles;
    float radiuss;
    float angleSpeed;
    float rSpeed;
    // Start is called before the first frame update
    void Start()
    {
        angles = 0;
        radiuss = 10;
        angleSpeed = 150;
        rSpeed = 0.7f;
        angles = Mathf.Max(0, Mathf.PI);
        radiuss = Mathf.Max(0, radiuss);

        //float x = 0;
        // float y = 0;
        // float z = 0;
    }

    // Update is called once per frame
    void Update()
    {
        angles += Time.deltaTime * angleSpeed;
        radiuss -= Time.deltaTime * rSpeed;
        if (radiuss == 0)
        {
            float x = 0;
            float y = 0;
            float z = 0;

            transform.position = new Vector3(x, y, z);
        }

        else
        {
            float x = radiuss * Mathf.Cos(Mathf.Deg2Rad * angles);
            float z = radiuss * Mathf.Sin(Mathf.Deg2Rad * angles);
            float y = 0;

            transform.position = new Vector3(x, y, z);
        }


        }

 }

Объект очень хорошо вращается по спирали, но я хочу сделать он останавливается, когда достигает исходной точки, и остается там. Я пробовал использовать оператор if-else, указанный в коде, но он не останавливается. Вместо этого он становится внешней спиралью из внутренней.

Помогите пожалуйста с кодом.

1 Ответ

1 голос
/ 28 мая 2020

Прежде всего: никогда не используйте == для сравнения двух float значений.

Из-за неточности с плавающей запятой значение может не точно совпадать с другим, даже если логически вы бы так подумал.

Пример Unity использует if

10f / 10f != 1f

, поскольку иногда это может быть что-то вроде 1.00000001 или 0.999999999.

IF вы хотите проверьте точные значения, а используйте Mathf. Примерно

if(Mathf.Approximately(a,b))

, что в основном равно

if(Mathf.Abs(a-b) <= Mathf.Epsilon)

, а затем, во-вторых, ваше

radiuss -= Time.deltaTime * rSpeed;

допускает перерегулирование, поэтому, если перед запуском radiuss уже < Time.deltaTime * rSpeed, вы получите отрицательное значение, которое не совсем == 0, но, возможно, -0.00000001 или меньше, поэтому вы никогда не попадете в блок if.


Таким образом, вы можете либо просто использовать

if(radius <= 0)
{
   transform.position = Vector3.zero;
}
...

, либо вы можете определенно убедиться, что оно не ниже 0, и сделать

radius = Mathf.Max(0, radius);
if(Mathf.Approximately(radius, 0))
{
    transform.position = Vector3.zero;
}
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...